> This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to > allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` > when the compiler detects that the following situation is _in theory > possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source > file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could > get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and > before `B()` has performed any initialization. To the extent `B.foo()` > accesses any fields of `B` - all of which are still uninitialized - it is > likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no > assumptions about code outside of the current compilation unit. It doesn't > look outside of the current source file to see what might actually happen > when a method is invoked. It does follow method and constructors within the > current compilation unit, and applies a simplified > union-of-all-possible-branches data flow analysis to see where 'this' could > end up. > > From my review, virtually all of the warnings generated in the various JDK > modules are valid warnings in the sense that a 'this' escape, as defined > above, is really and truly possible. However, that doesn't imply that any > bugs were found within the JDK - only that the possibility of a certain type > of bug exists if certain superclass constructors are used by someone, > somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the > offending constructors so that subclass implementors are made aware of the > threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included > [doc > file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) > that these `@implNote`'s link to. See also the recent thread on `amber-dev` > for some background. > > Ideally, over time the owners of the various modules would review their > `@SuppressWarnings("this-escape")` annotations and determine which other > constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of > different JDK modules. My apologies for that. Adding these annotations was > determined to be the more conservative approach, as compared to just > excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * > `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * > `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * > `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")`
Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: - Use the more appropriate Type comparison method Types.isSameType(). - Add some more comments to clarify how the analysis works. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/d70d12f4..6e96a7d7 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=06 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=05-06 Stats: 31 lines in 2 files changed: 16 ins; 10 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874