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

Jan Lahoda jan.lahoda at oracle.com
Mon Jun 8 13:35:50 UTC 2020


Hi,

Updated patch which will only check whether the type is a functional 
interface for lambdas and member references. Full updated patch:
http://cr.openjdk.java.net/~jlahoda/8235564/webrev.01/

Delta from previous patch:
http://cr.openjdk.java.net/~jlahoda/8235564/webrev.delta.00-01/

Does this look OK?

Thanks,
     Jan

On 05. 06. 20 21:51, Vicente Romero wrote:
> 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