Skip to content

Check of cyclic object initialization v3 #12122

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

Closed
wants to merge 47 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7febb3a
WIP - Check global objects
liufengyun Apr 3, 2021
d51d4b2
Introduce hierarchy for dependencies
liufengyun Apr 11, 2021
9c41828
Add StaticCall dependencies
liufengyun Apr 15, 2021
ac985ba
Add instance class to StaticCall
liufengyun Apr 15, 2021
e12a8c2
Add missing instance usage dependency
liufengyun Apr 15, 2021
252bf69
Fine-grained analysis of method dependencies
liufengyun Apr 15, 2021
05f7a25
Implement checkCyclic
liufengyun Apr 15, 2021
6d2cd29
Check cycles before adding to visited set
liufengyun Apr 15, 2021
eedc8cd
Ignore static object access for prefix in new expressions
liufengyun Apr 15, 2021
8c2d073
Skip object access in libraries
liufengyun Apr 15, 2021
dcc0e64
Add tests
liufengyun Apr 10, 2021
6082984
Handle usage of proxy dependencies
liufengyun Apr 15, 2021
d045ea6
Resolve overriding early
liufengyun Apr 15, 2021
14b9530
All tests green
liufengyun Apr 15, 2021
9c8850f
Fix crash compiling Dotty
liufengyun Apr 15, 2021
8ebaded
Add missing object access trace
liufengyun Apr 15, 2021
2e45946
Handle object access semantics depending on locations
liufengyun Apr 16, 2021
ec5c7ba
Fix crash in compiling Dotty
liufengyun Apr 16, 2021
8bdd645
Refine trace and error message for cycles
liufengyun Apr 16, 2021
3508d33
Simplify summarization logic
liufengyun Apr 16, 2021
2801664
Fix community build
liufengyun Apr 16, 2021
ea48d0b
Fix tests
liufengyun Apr 16, 2021
da72317
Refine code documentation
liufengyun Apr 16, 2021
f3bf03b
Report errors instead of crash
liufengyun Apr 16, 2021
b2ae947
Fix tests after phase move: constant folding happens later
liufengyun Apr 16, 2021
a97b309
Add instanceClass to InstanceUsage
liufengyun Apr 20, 2021
8675dc7
Remove class usage
liufengyun Apr 20, 2021
d8e887f
Check fields of InstanceUsage
liufengyun Apr 20, 2021
96fe9b5
Make ordering of check deterministic
liufengyun Apr 20, 2021
5787e5c
Make checking state final
liufengyun Apr 20, 2021
1a5b137
More friendly trace for collected transitive dependencies
liufengyun Apr 20, 2021
6546e2d
Add more tests
liufengyun Apr 20, 2021
25f0782
More refined analysis for calls on objects
liufengyun Apr 20, 2021
afd304a
Handle O.this.m() in type analysis
liufengyun Apr 20, 2021
06e577f
Add tests
liufengyun Apr 20, 2021
8af6f21
Don't trigger object access effect after super constructor call
liufengyun Apr 21, 2021
662da71
More fine-grained analysis for inner classes of static objects
liufengyun Apr 21, 2021
b38aef5
More friendly stack trace
liufengyun Apr 26, 2021
9f9f944
See through static calls on inner objects
liufengyun Apr 26, 2021
b70f63c
Support pinpointing in stacktrace
liufengyun Apr 26, 2021
224732b
Show file and line numbers at the beginning in stack trace
liufengyun Apr 26, 2021
ef76448
Remove unsound skip
liufengyun Apr 26, 2021
f48d081
Expand potentials on this of static objects
liufengyun Apr 26, 2021
dda3e79
Pinpoint the first leak correctly
liufengyun Apr 26, 2021
cabb318
Ignore contructor call of noInit traits and interface
liufengyun Apr 26, 2021
6211f4c
Correct indentation independent of file name size
liufengyun Apr 26, 2021
1c29167
More compact trace
liufengyun Apr 26, 2021
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
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ class Compiler {

/** Phases dealing with the transformation from pickled trees to backend trees */
protected def transformPhases: List[List[Phase]] =
List(new init.Checker) :: // Check initialization of objects
List(new FirstTransform, // Some transformations to put trees into a canonical form
new CheckReentrant, // Internal use only: Check that compiled program has no data races involving global vars
new ElimPackagePrefixes, // Eliminate references to package prefixes in Select nodes
new CookComments, // Cook the comments: expand variables, doc, etc.
new CheckStatic, // Check restrictions that apply to @static members
new BetaReduce, // Reduce closure applications
new InlineVals, // Check right hand-sides of an `inline val`s
new ExpandSAMs, // Expand single abstract method closures to anonymous classes
new init.Checker) :: // Check initialization of objects
new ExpandSAMs) :: // Expand single abstract method closures to anonymous classes
List(new ElimRepeated, // Rewrite vararg parameters and arguments
new ProtectedAccessors, // Add accessors for protected members
new ExtensionMethods, // Expand methods of value classes with extension methods
Expand Down
38 changes: 34 additions & 4 deletions compiler/src/dotty/tools/dotc/transform/init/Checker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,53 @@ import Types._
import Symbols._

import dotty.tools.dotc.transform._
import MegaPhase._
import Phases._


import scala.collection.mutable


class Checker extends MiniPhase {
class Checker extends Phase {
import tpd._

val phaseName = "initChecker"

// cache of class summary
private val cache = new Cache

private val cycleChecker = new CycleChecker(cache)

override val runsAfter = Set(Pickler.name)
val runsBefore = Set(ExpandSAMs.name)

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

override def transformTypeDef(tree: TypeDef)(using Context): tpd.Tree = {
if (!tree.isClassDef) return tree
override def runOn(units: List[CompilationUnit])(using Context): List[CompilationUnit] =
cycleChecker.clean()
val newUnits = super.runOn(units)
cycleChecker.checkCyclic()
newUnits

val traverser = new TreeTraverser {
override def traverse(tree: Tree)(using Context): Unit =
tree match {
case tdef: TypeDef if tdef.isClassDef =>
checkClassDef(tdef)
cycleChecker.classesInCurrentRun += tdef.symbol
traverseChildren(tree)
case _ =>
traverseChildren(tree)
}
}

override def run(using Context): Unit = {
val unit = ctx.compilationUnit
traverser.traverse(unit.tpdTree)
}

def checkClassDef(tree: TypeDef)(using Context): tpd.Tree = {
assert(tree.isClassDef)

val cls = tree.symbol.asClass
val instantiable: Boolean =
Expand All @@ -54,10 +80,14 @@ class Checker extends MiniPhase {
fieldsInited = mutable.Set.empty,
parentsInited = mutable.Set.empty,
safePromoted = mutable.Set.empty,
dependencies = mutable.Set.empty,
superConstrCalled = false,
env = Env(ctx.withOwner(cls), cache)
)

Checking.checkClassBody(tree)

cycleChecker.cacheConstructorDependencies(cls.primaryConstructor, state.dependencies.toList)
}

tree
Expand Down
Loading