On Thu, 12 Jan 2023 14:59:12 GMT, Archie L. Cobbs <d...@openjdk.org> wrote:

>>> * On the Java stack
>>>   (a) The current 'this' instance
>>>   (b) A method parameter
>>>   (c) A local variable
>>>   (d) A temporary value that is part of the current expression being 
>>> evaluated
>>>   (e) The return value from a method that just returned
>>>   (f) A caught exception
>>> 
>>> * In a field of some object...
>>>   (a) A normal field
>>>   (b) An outer 'this' instance
>>>   (c) Other synthetic field (e.g., captured free variable)
>>> 
>>> * As an element in a reference array
>>> 
>>> * In native code as a native reference
>> 
>> Thanks for the classification. This is helpful.
>> 
>> I'm not sure what you mean by (1f). You mean `this` can be embedded in an 
>> exception being thrown? Is that different from (2)?
>> 
>> Also, it seems to me that (3) is a special case of (2) - in the sense that 
>> you can imagine a reference array as a big object that has many fields as 
>> there are elements - so the same reasoning applies.
>> 
>> When looking at (2d) and (2e) the fact that Javac's AST is not in SSA form 
>> means that, yes, we need to track _expressions_ not just variables (e.g. for 
>> chains of methods calls, ternary operators and such).
>
>> I'm not sure what you mean by (1f). You mean this can be embedded in an 
>> exception being thrown? Is that different from (2)?
> 
> Yes, this would be a different case from any other that you'd have to handle 
> in the code if you wanted to deal with it. 
> 
> An example of how this could happen would be:
> 
> public class ThrownThis extends RuntimeException {
> 
>     public ThrownThis(Object obj) {
>         try {
>             this.validate(obj);
>         } catch (RuntimeException e) {
>             e.mightLeak();  // LEAK HERE
>         }
>     }
> 
>     private void validate(Object obj) {
>         if (obj.hashCode() != 123)
>             throw this;
>     }
> 
>     public void mightLeak() {
>     }
> }
> 
> Of course, that's an absurd example and the likelihood that any random piece 
> of actually code does that is negligible.
> 
> Regardless, I did briefly consider including handling for thrown exceptions 
> but quickly decided it couldn't possibly be worth the trouble.
> 
> As a result, if you compile that example with `-Xlint:this-escape` you don't 
> get a warning. No major loss!
> 
>> Also, it seems to me that (3) is a special case of (2) - in the sense that 
>> you can imagine a reference array as a big object that has many fields as 
>> there are elements - so the same reasoning applies.
> 
> Yes it's effectively the same thing, but fields and array elements are 
> accessed by different mechanisms in Java, so from the point of the analyzer 
> they have to be handled separately for that reason, which is why I broke them 
> out.

> Yes, this would be a different case from any other that you'd have to handle 
> in the code if you wanted to deal with it.
> 
> An example of how this could happen would be:
> 
> ```java
> public class ThrownThis extends RuntimeException {
> 
>     public ThrownThis(Object obj) {
>         try {
>             this.validate(obj);
>         } catch (RuntimeException e) {
>             e.mightLeak();  // LEAK HERE
>         }
>     }
> 
>     private void validate(Object obj) {
>         if (obj.hashCode() != 123)
>             throw this;
>     }
> 
>     public void mightLeak() {
>     }
> }
> ```
> 
Interesting example - I thought you might have been referring to a case where 
the class being analyzed was itself an exception.

Question - shouldn't we conclude that `this` leak when we see `throw this` ? 
E.g. what if the constructor did not have a `catch` (or if the catch was of a 
different type) ?
> Of course, that's an absurd example and the likelihood that any random piece 
> of actually code does that is negligible.
> 
> Regardless, I did briefly consider including handling for thrown exceptions 
> but quickly decided it couldn't possibly be worth the trouble.
> 
> As a result, if you compile that example with `-Xlint:this-escape` you don't 
> get a warning. No major loss!
> 
> > Also, it seems to me that (3) is a special case of (2) - in the sense that 
> > you can imagine a reference array as a big object that has many fields as 
> > there are elements - so the same reasoning applies.
> 
> Yes it's effectively the same thing, but fields and array elements are 
> accessed by different mechanisms in Java, so from the point of the analyzer 
> they have to be handled separately for that reason, which is why I broke them 
> out.

-------------

PR: https://git.openjdk.org/jdk/pull/11874

Reply via email to