Skip to content

Commit 6794689

Browse files
author
EnzeXing
committed
Add option to ignore using unknown value warning
1 parent 8ce9293 commit 6794689

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
@@ -452,7 +452,7 @@ private sealed trait YSettings:
452452
val YnoKindPolymorphism: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-kind-polymorphism", "Disable kind polymorphism.")
453453
val YexplicitNulls: Setting[Boolean] = BooleanSetting(ForkSetting, "Yexplicit-nulls", "Make reference types non-nullable. Nullable types can be expressed with unions: e.g. String|Null.")
454454
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.")
455-
val YcheckInitGlobal: Setting[Boolean] = BooleanSetting(ForkSetting, "Ysafe-init-global", "Check safe initialization of global objects.")
455+
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")
456456
val YrequireTargetName: Setting[Boolean] = BooleanSetting(ForkSetting, "Yrequire-targetName", "Warn if an operator is defined without a @targetName annotation.")
457457
val YrecheckTest: Setting[Boolean] = BooleanSetting(ForkSetting, "Yrecheck-test", "Run basic rechecking (internal test only).")
458458
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
@@ -676,6 +676,11 @@ class Objects(using Context @constructorOnly):
676676

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

679+
/** Check if the checker option reports warnings about unknown code
680+
*/
681+
def reportUnknown(using context: Context): Boolean =
682+
context.settings.YcheckInitGlobal.value == "report-unknown"
683+
679684
/** Handle method calls `e.m(args)`.
680685
*
681686
* @param value The value for the receiver.
@@ -685,18 +690,21 @@ class Objects(using Context @constructorOnly):
685690
* @param superType The type of the super in a super call. NoType for non-super calls.
686691
* @param needResolve Whether the target of the call needs resolution?
687692
*/
688-
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) {
693+
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) {
689694
value.filterClass(meth.owner) match
690-
case UnknownValue => // TODO: This ensures soundness but emits extra warnings. Add an option to turn off warnings here
691-
report.warning("Using unknown value. " + Trace.show, Trace.position)
692-
Bottom
695+
case UnknownValue =>
696+
if reportUnknown then
697+
report.warning("Using unknown value. " + Trace.show, Trace.position)
698+
Bottom
699+
else
700+
UnknownValue
693701

694702
case Package(packageSym) =>
695703
report.warning("[Internal error] Unexpected call on package = " + value.show + ", meth = " + meth.show + Trace.show, Trace.position)
696704
Bottom
697705

698-
case BaseValue => // TODO: This ensures soundness but emits extra warnings. Add an option to return BaseValue here
699-
UnknownValue
706+
case BaseValue =>
707+
if reportUnknown then UnknownValue else BaseValue
700708

701709
case Bottom =>
702710
Bottom
@@ -744,7 +752,10 @@ class Objects(using Context @constructorOnly):
744752
arr
745753
else if target.equals(defn.Predef_classOf) then
746754
// Predef.classOf is a stub method in tasty and is replaced in backend
747-
UnknownValue
755+
BaseValue
756+
else if target.equals(defn.ClassTagModule_apply) then
757+
// ClassTag and other reflection related values are considered safe
758+
BaseValue
748759
else if target.hasSource then
749760
val cls = target.owner.enclosingClass.asClass
750761
val ddef = target.defTree.asInstanceOf[DefDef]
@@ -852,11 +863,14 @@ class Objects(using Context @constructorOnly):
852863
def select(value: Value, field: Symbol, receiver: Type, needResolve: Boolean = true): Contextual[Value] = log("select " + field.show + ", this = " + value.show, printer, (_: Value).show) {
853864
value.filterClass(field.owner) match
854865
case UnknownValue =>
855-
report.warning("Using unknown value", Trace.position)
856-
Bottom
866+
if reportUnknown then
867+
report.warning("Using unknown value. " + Trace.show, Trace.position)
868+
Bottom
869+
else
870+
UnknownValue
857871

858872
case BaseValue =>
859-
UnknownValue
873+
if reportUnknown then UnknownValue else BaseValue
860874

861875
case Package(packageSym) =>
862876
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
@@ -228,8 +228,8 @@ class CompilationTests {
228228
// initialization tests
229229
@Test def checkInitGlobal: Unit = {
230230
implicit val testGroup: TestGroup = TestGroup("checkInitGlobal")
231-
compileFilesInDir("tests/init-global/warn", defaultOptions.and("-Ysafe-init-global"), FileFilter.exclude(TestSources.negInitGlobalScala2LibraryTastyBlacklisted)).checkWarnings()
232-
compileFilesInDir("tests/init-global/pos", defaultOptions.and("-Ysafe-init-global", "-Xfatal-warnings"), FileFilter.exclude(TestSources.posInitGlobalScala2LibraryTastyBlacklisted)).checkCompile()
231+
compileFilesInDir("tests/init-global/warn", defaultOptions.and("-Ysafe-init-global:ignore-unknown"), FileFilter.exclude(TestSources.negInitGlobalScala2LibraryTastyBlacklisted)).checkWarnings()
232+
compileFilesInDir("tests/init-global/pos", defaultOptions.and("-Ysafe-init-global:ignore-unknown", "-Xfatal-warnings"), FileFilter.exclude(TestSources.posInitGlobalScala2LibraryTastyBlacklisted)).checkCompile()
233233
}
234234

235235
// initialization tests

0 commit comments

Comments
 (0)