Skip to content

Commit bf18e95

Browse files
author
EnzeXing
committed
Add option to ignore using unknown value warning
1 parent 44ed0b3 commit bf18e95

File tree

6 files changed

+31
-17
lines changed

6 files changed

+31
-17
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ class Compiler {
171171
val rctx =
172172
if ctx.settings.Xsemanticdb.value then
173173
ctx.addMode(Mode.ReadPositions)
174-
else if ctx.settings.YcheckInitGlobal.value then
174+
else if !ctx.settings.YcheckInitGlobal.isDefault then
175175
ctx.addMode(Mode.ReadPositions)
176176
else
177177
ctx

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ private sealed trait YSettings:
446446
val YnoKindPolymorphism: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-kind-polymorphism", "Disable kind polymorphism.")
447447
val YexplicitNulls: Setting[Boolean] = BooleanSetting(ForkSetting, "Yexplicit-nulls", "Make reference types non-nullable. Nullable types can be expressed with unions: e.g. String|Null.")
448448
val YnoFlexibleTypes: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-flexible-types", "Disable turning nullable Java return types and parameter types into flexible types, which behave like abstract types with a nullable lower bound and non-nullable upper bound.")
449-
val YcheckInitGlobal: Setting[Boolean] = BooleanSetting(ForkSetting, "Ysafe-init-global", "Check safe initialization of global objects.")
449+
val YcheckInitGlobal: Setting[String] = ChoiceSetting(ForkSetting, "Ysafe-init-global", "[report-unknown, ignore-unknown]", "Check safe initialization of global objects.", List("report-unknown", "ignore-unknown", "off"), "off")
450450
val YrequireTargetName: Setting[Boolean] = BooleanSetting(ForkSetting, "Yrequire-targetName", "Warn if an operator is defined without a @targetName annotation.")
451451
val YrecheckTest: Setting[Boolean] = BooleanSetting(ForkSetting, "Yrecheck-test", "Run basic rechecking (internal test only).")
452452
val YccDebug: Setting[Boolean] = BooleanSetting(ForkSetting, "Ycc-debug", "Used in conjunction with captureChecking language import, debug info for captured references.")

compiler/src/dotty/tools/dotc/core/Symbols.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ object Symbols extends SymUtils {
8585
denot.owner.isTerm || // no risk of leaking memory after a run for these
8686
denot.isOneOf(InlineOrProxy) || // need to keep inline info
8787
ctx.settings.Whas.checkInit || // initialization check
88-
ctx.settings.YcheckInitGlobal.value
88+
!ctx.settings.YcheckInitGlobal.isDefault
8989

9090
/** The last denotation of this symbol */
9191
private var lastDenot: SymDenotation = uninitialized

compiler/src/dotty/tools/dotc/transform/init/Checker.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Checker extends Phase:
2929
override val runsAfter = Set(Pickler.name)
3030

3131
override def isEnabled(using Context): Boolean =
32-
super.isEnabled && (ctx.settings.Whas.checkInit || ctx.settings.YcheckInitGlobal.value)
32+
super.isEnabled && (ctx.settings.Whas.checkInit || !ctx.settings.YcheckInitGlobal.isDefault)
3333

3434
def traverse(traverser: InitTreeTraverser)(using Context): Boolean = monitor(phaseName):
3535
val unit = ctx.compilationUnit
@@ -53,7 +53,7 @@ class Checker extends Phase:
5353
if ctx.settings.Whas.checkInit then
5454
Semantic.checkClasses(classes)(using checkCtx)
5555

56-
if ctx.settings.YcheckInitGlobal.value then
56+
if !ctx.settings.YcheckInitGlobal.isDefault then
5757
val obj = new Objects
5858
obj.checkClasses(classes)(using checkCtx)
5959
}

compiler/src/dotty/tools/dotc/transform/init/Objects.scala

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,11 @@ class Objects(using Context @constructorOnly):
718718

719719
def widen(height: Int): Contextual[List[Value]] = values.map(_.widen(height)).toList
720720

721+
/** Check if the checker option reports warnings about unknown code
722+
*/
723+
def reportUnknown(using context: Context): Boolean =
724+
context.settings.YcheckInitGlobal.value == "report-unknown"
725+
721726
/** Handle method calls `e.m(args)`.
722727
*
723728
* @param value The value for the receiver.
@@ -727,18 +732,21 @@ class Objects(using Context @constructorOnly):
727732
* @param superType The type of the super in a super call. NoType for non-super calls.
728733
* @param needResolve Whether the target of the call needs resolution?
729734
*/
730-
def call(value: Value, meth: Symbol, args: List[ArgInfo], receiver: Type, superType: Type, needResolve: Boolean = true): Contextual[Value] = log("call " + meth.show + ", this = " + value.show + ", args = " + args.map(_.value.show), printer, (_: Value).show) {
735+
def call(value: Value, meth: Symbol, args: List[ArgInfo], receiver: Type, superType: Type, needResolve: Boolean = true): Contextual[Value] = log("call " + meth.show + ", this = " + value.show + ", args = " + args.map(_.tree.show), printer, (_: Value).show) {
731736
value.filterClass(meth.owner) match
732-
case UnknownValue => // TODO: This ensures soundness but emits extra warnings. Add an option to turn off warnings here
733-
report.warning("Using unknown value. " + Trace.show, Trace.position)
734-
Bottom
737+
case UnknownValue =>
738+
if reportUnknown then
739+
report.warning("Using unknown value. " + Trace.show, Trace.position)
740+
Bottom
741+
else
742+
UnknownValue
735743

736744
case Package(packageSym) =>
737745
report.warning("[Internal error] Unexpected call on package = " + value.show + ", meth = " + meth.show + Trace.show, Trace.position)
738746
Bottom
739747

740-
case BaseValue => // TODO: This ensures soundness but emits extra warnings. Add an option to return BaseValue here
741-
UnknownValue
748+
case BaseValue =>
749+
if reportUnknown then UnknownValue else BaseValue
742750

743751
case Bottom =>
744752
Bottom
@@ -786,7 +794,10 @@ class Objects(using Context @constructorOnly):
786794
arr
787795
else if target.equals(defn.Predef_classOf) then
788796
// Predef.classOf is a stub method in tasty and is replaced in backend
789-
UnknownValue
797+
BaseValue
798+
else if target.equals(defn.ClassTagModule_apply) then
799+
// ClassTag and other reflection related values are considered safe
800+
BaseValue
790801
else if target.hasSource then
791802
val cls = target.owner.enclosingClass.asClass
792803
val ddef = target.defTree.asInstanceOf[DefDef]
@@ -894,11 +905,14 @@ class Objects(using Context @constructorOnly):
894905
def select(value: Value, field: Symbol, receiver: Type, needResolve: Boolean = true): Contextual[Value] = log("select " + field.show + ", this = " + value.show, printer, (_: Value).show) {
895906
value.filterClass(field.owner) match
896907
case UnknownValue =>
897-
report.warning("Using unknown value", Trace.position)
898-
Bottom
908+
if reportUnknown then
909+
report.warning("Using unknown value. " + Trace.show, Trace.position)
910+
Bottom
911+
else
912+
UnknownValue
899913

900914
case BaseValue =>
901-
UnknownValue
915+
if reportUnknown then UnknownValue else BaseValue
902916

903917
case Package(packageSym) =>
904918
if field.isStaticObject then

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,8 @@ class CompilationTests {
231231
// initialization tests
232232
@Test def checkInitGlobal: Unit = {
233233
implicit val testGroup: TestGroup = TestGroup("checkInitGlobal")
234-
compileFilesInDir("tests/init-global/warn", defaultOptions.and("-Ysafe-init-global"), FileFilter.exclude(TestSources.negInitGlobalScala2LibraryTastyExcludelisted)).checkWarnings()
235-
compileFilesInDir("tests/init-global/pos", defaultOptions.and("-Ysafe-init-global", "-Xfatal-warnings"), FileFilter.exclude(TestSources.posInitGlobalScala2LibraryTastyExcludelisted)).checkCompile()
234+
compileFilesInDir("tests/init-global/warn", defaultOptions.and("-Ysafe-init-global:ignore-unknown"), FileFilter.exclude(TestSources.negInitGlobalScala2LibraryTastyExcludelisted)).checkWarnings()
235+
compileFilesInDir("tests/init-global/pos", defaultOptions.and("-Ysafe-init-global:ignore-unknown", "-Xfatal-warnings"), FileFilter.exclude(TestSources.posInitGlobalScala2LibraryTastyExcludelisted)).checkCompile()
236236
}
237237

238238
// initialization tests

0 commit comments

Comments
 (0)