RFR: JDK-8235564: javac crashes while compiling incorrect method invocation with member reference

Vicente Romero vicente.romero at oracle.com
Fri Jun 5 19:51:23 UTC 2020


sounds good,

Thanks,
Vicente

On 6/5/20 3:04 PM, Jan Lahoda wrote:
> Hi Vicente,
>
> On 05. 06. 20 20:22, Vicente Romero wrote:
>> Hi,
>>
>> looks good, my only question is if this:
>>
>> Type ptRecovery = pt != null && types.isFunctionalInterface(pt) ? pt 
>> : Type.recoveryType;
>>
>>
>> wont be a too strict semantic change, but given that this is recovery 
>> code anyway I guess that users won't see a difference in the printed 
>> diagnostics,
>
> Thanks for the comment!
>
> I guess you might be right - I'll limit check for the function 
> interface only to DeferredTypes that represent lambdas and member 
> references (where we really need a functional target type). Will send 
> a new webrev early next week.
>
> Thanks,
>     Jan
>
>>
>> Vicente
>>
>> On 6/5/20 11:20 AM, Jan Lahoda wrote:
>>> Hi,
>>>
>>> Consider code like:
>>> public class Test {
>>>     static void test() {
>>>         existingWithoutFunctional(Test::undefined);
>>>     }
>>>
>>>     private static void existingWithoutFunctional(String parameter) {}
>>> }
>>>
>>> javac crashes on this (please see the bug for the stack trace). The 
>>> reason for this is that while there are two errors in the source 
>>> code: a) passing member reference to a parameter that is not of a 
>>> functional type; b) the member reference refers to a method that 
>>> does not exist, no error is reported. The first error is suppressed 
>>> because the parameter is erroneous, and it is expected an error was 
>>> already issued for it (this is fine).
>>>
>>> The second error is mostly accidentally suppressed because 
>>> Attr.visitReference will get "String" and pt(), and hence 
>>> getTargetInfo() will fail to find the functional type, and most of 
>>> the processing/verification is skipped, and this causes the problem. 
>>> The problem is while doing recovery 
>>> DeferredAttr.RecoveryDeferredTypeMap.recover will use the 
>>> non-functional formal parameter type as the expected target type. 
>>> This was an attempt to improve error recovery, but seems to go too 
>>> far. The proposal is to use the formal parameter type only if it is 
>>> a functional type.
>>>
>>> As a result, for the example above, the javac reponse will be:
>>> $ javac Test.java
>>> Test.java:3: error: invalid method reference
>>>         existingWithoutFunctional(Test::undefined);
>>>                                   ^
>>>   cannot find symbol
>>>     symbol:   method undefined()
>>>     location: class Test
>>> 1 error
>>>
>>> Which is the same as in JDK 11.
>>> cr.openjdk.java.net/~jlahoda/8235564/webrev.00/
>>>
>>> Proposed webrev:
>>>
>>> JBS: https://bugs.openjdk.java.net/browse/JDK-8235564
>>>
>>> How does this look?
>>>
>>> Thanks,
>>>     Jan
>>>
>>>
>>>
>>>
>>>
>>



More information about the compiler-dev mailing list