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

Jan Lahoda jan.lahoda at oracle.com
Fri Jun 5 19:04:46 UTC 2020


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