Skip to content

Commit 7ffca49

Browse files
author
EnzeXing
committed
Add option to ignore using unknown value warning
1 parent 61ff827 commit 7ffca49

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
@@ -170,7 +170,7 @@ class Compiler {
170170
val rctx =
171171
if ctx.settings.Xsemanticdb.value then
172172
ctx.addMode(Mode.ReadPositions)
173-
else if ctx.settings.YcheckInitGlobal.value then
173+
else if !ctx.settings.YcheckInitGlobal.isDefault then
174174
ctx.addMode(Mode.ReadPositions)
175175
else
176176
ctx

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ private sealed trait YSettings:
443443
val YnoKindPolymorphism: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-kind-polymorphism", "Disable kind polymorphism.")
444444
val YexplicitNulls: Setting[Boolean] = BooleanSetting(ForkSetting, "Yexplicit-nulls", "Make reference types non-nullable. Nullable types can be expressed with unions: e.g. String|Null.")
445445
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.")
446-
val YcheckInitGlobal: Setting[Boolean] = BooleanSetting(ForkSetting, "Ysafe-init-global", "Check safe initialization of global objects.")
446+
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")
447447
val YrequireTargetName: Setting[Boolean] = BooleanSetting(ForkSetting, "Yrequire-targetName", "Warn if an operator is defined without a @targetName annotation.")
448448
val YrecheckTest: Setting[Boolean] = BooleanSetting(ForkSetting, "Yrecheck-test", "Run basic rechecking (internal test only).")
449449
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
@@ -683,6 +683,11 @@ class Objects(using Context @constructorOnly):
683683

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

686+
/** Check if the checker option reports warnings about unknown code
687+
*/
688+
def reportUnknown(using context: Context): Boolean =
689+
context.settings.YcheckInitGlobal.value == "report-unknown"
690+
686691
/** Handle method calls `e.m(args)`.
687692
*
688693
* @param value The value for the receiver.
@@ -692,18 +697,21 @@ class Objects(using Context @constructorOnly):
692697
* @param superType The type of the super in a super call. NoType for non-super calls.
693698
* @param needResolve Whether the target of the call needs resolution?
694699
*/
695-
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) {
700+
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) {
696701
value.filterClass(meth.owner) match
697-
case UnknownValue => // TODO: This ensures soundness but emits extra warnings. Add an option to turn off warnings here
698-
report.warning("Using unknown value. " + Trace.show, Trace.position)
699-
Bottom
702+
case UnknownValue =>
703+
if reportUnknown then
704+
report.warning("Using unknown value. " + Trace.show, Trace.position)
705+
Bottom
706+
else
707+
UnknownValue
700708

701709
case Package(packageSym) =>
702710
report.warning("[Internal error] Unexpected call on package = " + value.show + ", meth = " + meth.show + Trace.show, Trace.position)
703711
Bottom
704712

705-
case BaseValue => // TODO: This ensures soundness but emits extra warnings. Add an option to return BaseValue here
706-
UnknownValue
713+
case BaseValue =>
714+
if reportUnknown then UnknownValue else BaseValue
707715

708716
case Bottom =>
709717
Bottom
@@ -751,7 +759,10 @@ class Objects(using Context @constructorOnly):
751759
arr
752760
else if target.equals(defn.Predef_classOf) then
753761
// Predef.classOf is a stub method in tasty and is replaced in backend
754-
UnknownValue
762+
BaseValue
763+
else if target.equals(defn.ClassTagModule_apply) then
764+
// ClassTag and other reflection related values are considered safe
765+
BaseValue
755766
else if target.hasSource then
756767
val cls = target.owner.enclosingClass.asClass
757768
val ddef = target.defTree.asInstanceOf[DefDef]
@@ -859,11 +870,14 @@ class Objects(using Context @constructorOnly):
859870
def select(value: Value, field: Symbol, receiver: Type, needResolve: Boolean = true): Contextual[Value] = log("select " + field.show + ", this = " + value.show, printer, (_: Value).show) {
860871
value.filterClass(field.owner) match
861872
case UnknownValue =>
862-
report.warning("Using unknown value", Trace.position)
863-
Bottom
873+
if reportUnknown then
874+
report.warning("Using unknown value. " + Trace.show, Trace.position)
875+
Bottom
876+
else
877+
UnknownValue
864878

865879
case BaseValue =>
866-
UnknownValue
880+
if reportUnknown then UnknownValue else BaseValue
867881

868882
case Package(packageSym) =>
869883
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)