RFR: JDK-8235564: javac crashes while compiling incorrect method invocation with member reference
Vicente Romero
vicente.romero at oracle.com
Tue Jun 9 18:01:06 UTC 2020
looks good,
Vicente
On 6/8/20 9:35 AM, Jan Lahoda wrote:
> 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