Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check safe initialization of static objects #16970

Merged
merged 113 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
b787d3c
WIP - check global objects
liufengyun Oct 15, 2022
337730b
Add more docs
liufengyun Oct 15, 2022
e112581
Add code skeleton
liufengyun Oct 15, 2022
9604f76
More code type check
liufengyun Oct 17, 2022
a3b9f12
Add skeleton
liufengyun Oct 18, 2022
ce25221
Refine abstract domain
liufengyun Jan 4, 2023
f8960f3
Check cycles
liufengyun Jan 5, 2023
0f4afa8
Fix cache
liufengyun Jan 5, 2023
db0430c
Stop fix point computation in case of errors
liufengyun Jan 5, 2023
f6d255a
Introduce Bottom value
liufengyun Jan 5, 2023
03afb7d
Define evalType
liufengyun Jan 5, 2023
fea9fb9
Remove Ext
liufengyun Jan 6, 2023
46c7b8b
Fix init and resolveThis
liufengyun Jan 8, 2023
e997bc0
Fix call
liufengyun Jan 8, 2023
fab38b5
Fix callConstructor
liufengyun Jan 8, 2023
e6dbb2d
Fix select
liufengyun Jan 8, 2023
d6278d1
Fix instantiate
liufengyun Jan 8, 2023
4b8a041
First test passes
liufengyun Jan 8, 2023
3e0f1b9
Extract common code to separate files
liufengyun Jan 9, 2023
c7642f3
Fix crash for instantiating top-level classes
liufengyun Jan 9, 2023
9160e6c
Refine printing
liufengyun Jan 9, 2023
daf1e50
Show trace in cyclic errors
liufengyun Jan 9, 2023
9c2a570
Enable cache
liufengyun Jan 11, 2023
3ff3774
Distinguish Config and Res in Cache
liufengyun Jan 12, 2023
46b2594
Better trace
liufengyun Jan 12, 2023
61152e0
Fix termination and cache for tests/init/neg/apply2.scala
liufengyun Jan 12, 2023
778cf2d
Fix cast crash
liufengyun Jan 12, 2023
8793ba8
Fix trace for objects
liufengyun Jan 12, 2023
b1adb98
Reorganize tests
liufengyun Jan 13, 2023
055f1d7
Fix error annotations
liufengyun Jan 13, 2023
d41cf8b
Add t9360 and improve error message
liufengyun Jan 13, 2023
99eaf43
Add t9312
liufengyun Jan 13, 2023
c04bc16
Add t9261
liufengyun Jan 13, 2023
c2ec366
Add t9115
liufengyun Jan 13, 2023
e26b686
Add t5366
liufengyun Jan 13, 2023
66be029
Add i11262
liufengyun Jan 13, 2023
3197f5a
Add more global tests
liufengyun Jan 13, 2023
3fe429f
Add crash test
liufengyun Jan 13, 2023
91e9c6a
Make sure the first outer is set
liufengyun Jan 14, 2023
5d31d3e
Fix crash
liufengyun Jan 14, 2023
e99f706
The two tests may cause deadlock
liufengyun Jan 14, 2023
b3b696f
Fix error annotations for test cases
liufengyun Jan 14, 2023
2bbab07
Disallow mutating other static objects
liufengyun Jan 14, 2023
b06adad
Suppress debug printing
liufengyun Jan 14, 2023
9800395
Fix rebase error
liufengyun Jan 29, 2023
26e01ad
Refine abstract domain
liufengyun Feb 16, 2023
a5ed526
Handle assignment
liufengyun Feb 16, 2023
8c42c6d
Fix reading local mutable variable
liufengyun Feb 16, 2023
3938f8e
Fix compilation
liufengyun Feb 17, 2023
708a4dd
Add documentation
liufengyun Feb 20, 2023
cf49ce4
Use referential equality for heap to improve performance
liufengyun Feb 20, 2023
a282ce9
Make widen parametric to enable user-defined widening
liufengyun Feb 20, 2023
b4b0d07
Introduce init.widen
liufengyun Feb 20, 2023
c221da1
Respect environment
liufengyun Feb 20, 2023
2f75e5e
Fix error annotation
liufengyun Feb 20, 2023
27ff0eb
Ignore primitive types in assignment
liufengyun Feb 22, 2023
d69fc4f
Fix primitive value optimization
liufengyun Feb 22, 2023
7a1e7f3
Use ListSet to avoid explosion due to duplicate entries
liufengyun Feb 22, 2023
e963765
Better handling of locals
liufengyun Feb 22, 2023
13f804f
Only report non-trivial cycles
liufengyun Feb 22, 2023
5f81ee6
Reclassify test
liufengyun Feb 22, 2023
eacbd1b
Fix access local var
liufengyun Feb 22, 2023
cf925b2
Refine error message: don't show code for whole object
liufengyun Feb 22, 2023
2a73df2
Handle local variables properly
liufengyun Feb 23, 2023
1c66251
Fix resolution of definition environment
liufengyun Feb 23, 2023
7ade2e7
Lookup local variable using the right environment
liufengyun Feb 24, 2023
0d3ca9d
Use correct outer environment for local methods
liufengyun Feb 24, 2023
e8520c2
Use correct environment for val definitions
liufengyun Feb 24, 2023
2467571
Workaround bug in typer
liufengyun Feb 24, 2023
dd3ef2c
Suppress trivial self cycle warning
liufengyun Feb 24, 2023
9bc0df6
Fix environment for local class
liufengyun Feb 24, 2023
1b1727e
Refactor heap: make it disjoint for different objects
liufengyun Feb 25, 2023
602b775
Fix non-termination cause by equality of heap
liufengyun Feb 26, 2023
3c07f62
Fix typo: Use the widened value as method args
liufengyun Feb 26, 2023
5dfaf0b
Handle by-name parameters
liufengyun Feb 26, 2023
4b8ba9b
Tighten initialization-time irrelevance for local vars
liufengyun Feb 26, 2023
6d27960
Handle arguments for functions
liufengyun Feb 27, 2023
60ef6d1
Re use static objects: so that the fields hold correct values
liufengyun Feb 27, 2023
1a540ee
Constant folding drop anntations
liufengyun Feb 27, 2023
0fa9779
Simplify ownership tracking
liufengyun Feb 27, 2023
19a88de
Fix error message printing
liufengyun Feb 27, 2023
fb1f0c2
Handle immutable body values in widening
liufengyun Feb 27, 2023
d273c0f
Fix environment for reading local vars
liufengyun Feb 27, 2023
9d9bcb1
Use correct env for writing local vars
liufengyun Feb 27, 2023
58fce39
Primitive support for arrays
liufengyun Mar 5, 2023
1a9a744
More tests for array
liufengyun Mar 5, 2023
1bde3a5
Add region context to objects
liufengyun Mar 26, 2023
9799d50
Context-sensitive closures
liufengyun Mar 26, 2023
0a23d2c
Simplify: No need to put owner and region in object
liufengyun Mar 26, 2023
25888f3
Support region annotation
liufengyun Mar 26, 2023
6a6040e
Tweak default: widen 1
liufengyun Mar 26, 2023
1c30928
Ignore false warnings for Java & Scala 2
liufengyun Mar 26, 2023
db976fc
Guard the check under a flag
liufengyun Mar 26, 2023
4672e4b
Separate -Ysafe-int and -Ysafe-init-global
liufengyun Mar 31, 2023
5c46833
Add global init checking test cases
q-ata Apr 5, 2023
fb21862
Separate object init tests from class init tests
liufengyun Apr 6, 2023
557fbc7
Fix tests
liufengyun May 1, 2023
4d4518a
Align syntax with paper
liufengyun May 1, 2023
3e64c6b
Fix accidental changes to community build
liufengyun May 2, 2023
1aacd59
Fix typos
liufengyun May 22, 2023
a8d0b7f
Fix typo
liufengyun May 22, 2023
47bbeba
Fix typo
liufengyun May 22, 2023
d79c1ec
Add documentation to code
liufengyun May 22, 2023
81e0562
Apply suggestions from code review
liufengyun May 23, 2023
4cdfa54
Address review: factor out isByNameParam
liufengyun May 27, 2023
b5d8531
Add comment to code
liufengyun May 27, 2023
0638458
Fix typo in doc
liufengyun Jun 5, 2023
daf12de
Handle return properly
liufengyun Jun 10, 2023
ccb7983
Use warning instead of error for error state of init check
liufengyun Jun 12, 2023
cade1c7
Add experimental to lib changes
liufengyun Jun 12, 2023
8e9b194
Fix experimental definition test
liufengyun Jun 12, 2023
473e765
Show more context for warnings
liufengyun Jun 15, 2023
ce093cb
Report more warnings for pattern match
liufengyun Jun 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ private sealed trait YSettings:
val YnoKindPolymorphism: Setting[Boolean] = BooleanSetting("-Yno-kind-polymorphism", "Disable kind polymorphism.")
val YexplicitNulls: Setting[Boolean] = BooleanSetting("-Yexplicit-nulls", "Make reference types non-nullable. Nullable types can be expressed with unions: e.g. String|Null.")
val YcheckInit: Setting[Boolean] = BooleanSetting("-Ysafe-init", "Ensure safe initialization of objects")
val YcheckInitGlobal: Setting[Boolean] = BooleanSetting("-Ysafe-init-global", "Check safe initialization of global objects")
val YrequireTargetName: Setting[Boolean] = BooleanSetting("-Yrequire-targetName", "Warn if an operator is defined without a @targetName annotation")
val YrecheckTest: Setting[Boolean] = BooleanSetting("-Yrecheck-test", "Run basic rechecking (internal test only)")
val YccDebug: Setting[Boolean] = BooleanSetting("-Ycc-debug", "Used in conjunction with captureChecking language import, debug info for captured references")
Expand All @@ -398,4 +399,3 @@ private sealed trait YSettings:

val YforceInlineWhileTyping: Setting[Boolean] = BooleanSetting("-Yforce-inline-while-typing", "Make non-transparent inline methods inline when typing. Emulates the old inlining behavior of 3.0.0-M3.")
end YSettings

5 changes: 5 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,11 @@ class Definitions {

@tu lazy val JavaRepeatableAnnot: ClassSymbol = requiredClass("java.lang.annotation.Repeatable")

// Initialization annotations
@tu lazy val InitModule: Symbol = requiredModule("scala.annotation.init")
@tu lazy val InitWidenAnnot: ClassSymbol = InitModule.requiredClass("widen")
@tu lazy val InitRegionMethod: Symbol = InitModule.requiredMethod("region")

// A list of meta-annotations that are relevant for fields and accessors
@tu lazy val NonBeanMetaAnnots: Set[Symbol] =
Set(FieldMetaAnnot, GetterMetaAnnot, ParamMetaAnnot, SetterMetaAnnot, CompanionClassMetaAnnot, CompanionMethodMetaAnnot)
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ object Symbols {
ctx.settings.YretainTrees.value ||
denot.owner.isTerm || // no risk of leaking memory after a run for these
denot.isOneOf(InlineOrProxy) || // need to keep inline info
ctx.settings.YcheckInit.value // initialization check
ctx.settings.YcheckInit.value || // initialization check
ctx.settings.YcheckInitGlobal.value

/** The last denotation of this symbol */
private var lastDenot: SymDenotation = _
Expand Down
9 changes: 9 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,15 @@ object Types {
case _ => false
}

/** Returns the annotation that is an instance of `cls` carried by the type. */
@tailrec final def getAnnotation(cls: ClassSymbol)(using Context): Option[Annotation] = stripTypeVar match {
case AnnotatedType(tp, annot) =>
if annot.matches(cls) then Some(annot)
else tp.getAnnotation(cls)
case _ =>
None
}

/** Does this type have a supertype with an annotation satisfying given predicate `p`? */
def derivesAnnotWith(p: Annotation => Boolean)(using Context): Boolean = this match {
case tp: AnnotatedType => p(tp.annot) || tp.parent.derivesAnnotWith(p)
Expand Down
8 changes: 6 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/init/Checker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@ class Checker extends Phase:
override val runsAfter = Set(Pickler.name)

override def isEnabled(using Context): Boolean =
super.isEnabled && ctx.settings.YcheckInit.value
super.isEnabled && (ctx.settings.YcheckInit.value || ctx.settings.YcheckInitGlobal.value)

override def runOn(units: List[CompilationUnit])(using Context): List[CompilationUnit] =
val checkCtx = ctx.fresh.setPhase(this.start)
val traverser = new InitTreeTraverser()
units.foreach { unit => traverser.traverse(unit.tpdTree) }
val classes = traverser.getClasses()

Semantic.checkClasses(classes)(using checkCtx)
if ctx.settings.YcheckInit.value then
Semantic.checkClasses(classes)(using checkCtx)

if ctx.settings.YcheckInitGlobal.value then
Objects.checkClasses(classes)(using checkCtx)

units

Expand Down
Loading
Loading