RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5]
Maurizio Cimadamore
mcimadamore at openjdk.org
Wed Jan 11 00:07:15 UTC 2023
On Tue, 10 Jan 2023 19:20:35 GMT, Archie L. Cobbs <duke at openjdk.org> wrote:
>> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1098:
>>
>>> 1096: private <T extends JCTree> void visitLooped(T tree, Consumer<T> visitor) {
>>> 1097: this.visitScoped(tree, false, t -> {
>>> 1098: while (true) {
>>
>> Why is this needed? Can the tracking state of `this` change after multiple "execution" of the same code?
>
> Yes, because the 'this' reference can bounce around through different variables in scope each time around the loop. So we have to repeat the loop until all 'this' references have "flooded" into all the nooks and crannies.
>
> The `ThisEscapeLoop.java` unit test demonstrates:
>
> public class ThisEscapeLoop {
>
> public ThisEscapeLoop() {
> ThisEscapeLoop ref1 = this;
> ThisEscapeLoop ref2 = null;
> ThisEscapeLoop ref3 = null;
> ThisEscapeLoop ref4 = null;
> for (int i = 0; i < 100; i++) {
> ref4 = ref3;
> ref3 = ref2;
> ref2 = ref1;
> if (ref4 != null)
> ref4.mightLeak();
> }
> }
>
> public void mightLeak() {
> }
> }
So, if the code was be like this:
ThisEscapeLoop ref11 = this;
ThisEscapeLoop ref12 = null;
ThisEscapeLoop ref13 = null;
ThisEscapeLoop ref14 = null;
for (int i = 0; i < 100; i++) {
ref14 = ref13;
ref13 = ref12;
ref12 = ref11;
ThisEscapeLoop ref21 = ref14;
ThisEscapeLoop ref22 = null;
ThisEscapeLoop ref23 = null;
ThisEscapeLoop ref24 = null;
for (int i = 0; i < 100; i++) {
ref24 = ref23;
ref23 = ref22;
ref22 = ref21;
if (ref24 != null)
ref24.mightLeak();
}
}
Then it would take not 3 iterations but 3 * 3 to figure out that it is a potential leak?
-------------
PR: https://git.openjdk.org/jdk/pull/11874
More information about the core-libs-dev
mailing list