RFR: 8232765: NullPointerException at Types.eraseNotNeeded() when compiling a class

Maurizio Cimadamore mcimadamore at openjdk.java.net
Wed Apr 21 14:27:37 UTC 2021


On Wed, 21 Apr 2021 14:11:56 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> Hi all,
>> 
>> The method `types::asSuper` may return `null` so that `types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym))` throws `NPE`.
>> 
>> This patch sets the return type and outputs the corresponding error message if `types::asSuper` returns `null`.
>> 
>> Thank you for taking the time to review.
>> 
>> Best Regards.
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java line 3501:
> 
>> 3499:                                            eType,
>> 3500:                                            List.nil());
>> 3501:             Type returnType = types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym);
> 
> I know you closed this PR - just wanted to leave a comment: issuing this kind of type-checking errors in Lower is unusual. This kind of stuff should be caught in earlier (e.g. in Attr) - and, over the years we've been making efforts to move all error generation in the front-end; note than when using compiler through the compiler API, you might not run Lower (and all desugaring steps) so you might miss errors if these are generated too late.
> 
> That said, surely the check:
> 
> 
>             Type returnType = types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym);
>  ```
> 
> Must be somewhere in Attr?

So, in `Attr` we check that the class implements `Iterable`. In this case it does, but there's an incompatible override. That issues an error as expected, so compiling the provided test case:


public class T8232765 {
          public void test(String[] args) {
              MyLinkedList<Integer> list = new MyLinkedList<>();
              for (int x : list)
                  System.out.print(x);
          }
      }
      class MyLinkedList<T> implements java.lang.Iterable<T> {
          public void iterator() {}
      };

Does not result in a crash.

I suspect the issue in JBS is more subtle, and involves, perhaps, separate compilation? I find this very odd - typically javac stops at a phase (e.g. Attr) if one or more files had errors in that phase. In this case we have a bad implementation of `Iterable`, so we should not be able to go past `Attr`.

-------------

PR: https://git.openjdk.java.net/jdk/pull/2099


More information about the compiler-dev mailing list