On Thu, 12 Jan 2023 13:01:44 GMT, Maurizio Cimadamore <[email protected]>
wrote:
>> 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.
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java
> line 334:
>
>> 332: // of the stack trace of B. For example, if constructor Foo(int
>> x) has a leak, and constructor
>> 333: // Foo() invokes this(0), then emitting a warning for Foo()
>> would be redundant.
>> 334: final BiPredicate<DiagnosticPosition[], DiagnosticPosition[]>
>> extendsAsPrefix = (warning1, warning2) -> {
>
> Another strategy would be to give a single warning per leaking constructor.
We already impose a limit of at most one warning per constructor.
But for this limit what is technically meant by "per constructor" is "At most
one warning per constructor, assuming that constructor is the one being
analyzed (i.e., the one invoked by the subclass and not via `this()`)."
So that limitation doesn't stop a constructor from generating the same warning
multiple times due to it being invoked indirectly by other constructors via
`this()`. Those duplicate warnings are what the code above eliminates.
So this code only generates one warning, and it's reported for the second
constructor:
public class DupWarn1 {
public DupWarn1() {
this(0);
}
public DupWarn1(int x) {
this.mightLeak();
}
public void mightLeak() {
}
}
DupWarn1.java:8: warning: [this-escape] possible 'this' escape before subclass
is fully initialized
this.mightLeak();
^
This is appropriate. The leak is really in the second constructor; the first
constructor has nothing to do with it. Reporting a leak for both constructors
would be redundant.
An interesting side question: Is it possible to come up with an example where
constructor A has a 'this' leak, and some other constructor B invokes `this()`
to delegate to A, but when B delegates to A the leak occurs differently, or not
at all?
Because of the "flood" analysis, and the fact that you can't pass 'this'
references to `this()` or `super()` (these are static contexts), I don't think
it's possible.
So in fact the deduplication will always apply whenever `this()` is involved.
-------------
PR: https://git.openjdk.org/jdk/pull/11874