Possible compiler bug? Code compiles on 8 but not 11

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Feb 10 12:29:53 UTC 2020


I believe your analysis is correct. And I also believe this is related 
to this thread from a couple of years ago:

https://mail.openjdk.java.net/pipermail/compiler-dev/2016-January/009947.html

Basically, when doing some optimization in the inference engine, we came 
across a bug in the javac compiler, where the 'unchecked' status of a 
call was overwritten and not taken into account.

We have also tightened up inference, as certain checks were 
(erroneously!) not giving errors:

https://bugs.openjdk.java.net/browse/JDK-8078024

and

https://bugs.openjdk.java.net/browse/JDK-8039214

(in both cases a release note has been added, to warn users about 
potential source compatibility issues).

Cheers
Maurizio

On 07/02/2020 20:45, B. Blaser wrote:
> My reproducer seems to be missing one line, see below.
> Bernard
>
> On Fri, 7 Feb 2020 at 21:22, B. Blaser <bsrbnd at gmail.com> wrote:
>> Alex, David,
>>
>> Here is a simpler reproducer:
>>
>> public class Factory {
>>      public Factory() {
>>          String ok = gen(StringGenerator.class);
>> //        @SuppressWarnings("unchecked")
>>          String ko = gen(Generator.class);
>>      }
>>
>>      public <T, F extends SimpleGenerator<T>> T gen(Class<F> c) { return null; }
>> }
>>
>> class StringGenerator extends SimpleGenerator<String> {}
>> class Generator<T> extends SimpleGenerator<T> {}
> abstract class SimpleGenerator<T> {}
>
>> $ javac -Xlint:unchecked Factory.java
>> Factory.java:5: warning: [unchecked] unchecked method invocation:
>> method gen in class Factory is applied to given types
>>          String ko = gen(Generator.class);
>>                         ^
>>    required: Class<F>
>>    found: Class<Generator>
>>    where F,T are type-variables:
>>      F extends SimpleGenerator<T> declared in method <T,F>gen(Class<F>)
>>      T extends Object declared in method <T,F>gen(Class<F>)
>> Factory.java:5: error: incompatible types: Object cannot be converted to String
>>          String ko = gen(Generator.class);
>>                         ^
>> 1 error
>> 1 warning
>>
>> JLS §15.8.2 states:
>>
>> "The type of C.class, where C is the name of a class, interface, or
>> array type (§4.3), is Class<C>"
>>
>> which means that the found type 'Class<Generator>' triggers the
>> following rule from §18.2.2:
>>
>> "A constraint formula of the form ‹ S → T › is reduced as follows:
>> [...]
>> • Otherwise, if T is a parameterized type of the form G<T 1 , ..., T n
>>> , and there exists no type of the form G< ... > that is a supertype
>> of S , but the raw type G is a supertype of S , then the constraint
>> reduces to true.
>> [...]
>> The fourth and fifth cases are implicit uses of unchecked conversion (§5.1.9)."
>>
>> implying then §18.5.2.1:
>>
>> "If unchecked conversion was necessary for the method to be applicable
>> during constraint set reduction in §18.5.1, the constraint formula ‹|
>> R | → T › is reduced and incorporated with B 2 ."
>>
>> meaning that erasing the return type of 'gen()' to 'Object' looks, at
>> first sight, correct. I'm not exactly sure what could have changed
>> between 8 and 11, but we've still made a small fix in this area some
>> years ago [1], as far as I can remember.
>>
>> Any feedback is welcome,
>> Bernard
>>
>> [1] http://hg.openjdk.java.net/jdk/jdk/rev/39446351e625
>>
>> On Fri, 31 Jan 2020 at 20:00, Alex Buckley <alex.buckley at oracle.com> wrote:
>>> Hi David,
>>>
>>> This is a question of whether javac is conforming to the JLS, and if so,
>>> whether the JLS is correct. It's best in such cases to quote the
>>> smallest possible code sample in inline text. Oracle's javac team is not
>>> looking to reproduce issues in the manner of a support organization, but
>>> rather to understand as precisely as possible what's going on in the
>>> type system.
>>>
>>> Alex
>>>
>>> On 1/31/2020 10:36 AM, David Grieve wrote:
>>>> I have some code that compiles on 8 but not on 11. With 11 (11.0.5, to be exact), the compiler gives an error:
>>>>
>>>>> Factory.java
>>>>> Error:(9, 25) java: incompatible types: java.lang.Object cannot be converted to Manager<java.lang.String>
>>>> This can be fixed with an explicit cast. But it seems to me that the cast should not be needed.
>>>>
>>>> I'm hoping to get an answer for why this compiles cleanly on 8, but not 11.
>>>>
>>>> I have uploaded a small sample that reproduces to http://cr.openjdk.java.net/~dgrieve/javac-bug.zip
>>>>


More information about the compiler-dev mailing list