Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 414127

Summary: [null] Bogus potential null pointer access warning
Product: [Eclipse Project] JDT Reporter: Ed Merks <Ed.Merks>
Component: CoreAssignee: Stephan Herrmann <stephan.herrmann>
Status: CLOSED WORKSFORME QA Contact:
Severity: normal    
Priority: P3 CC: register.eclipse, stephan.herrmann
Version: 4.3   
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
Project with the bogus warning none

Description Ed Merks CLA 2013-07-31 08:47:44 EDT
Created attachment 233978 [details]
Project with the bogus warning

This sample:

package bogus_null_pointer_warning;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;

public class Main
{
  void bogus_null_pointer_warning() throws IOException
  {
    InputStream inputStream = null;
    try
    {
      for (Object object : Collections.emptyList())
      {
        if (object != null)
        {
          if (inputStream == null)
          {
            try
            {
              inputStream = createInputStream();
            }
            catch (IOException exception)
            {
              inputStream = new ByteArrayInputStream(new byte [0]);
            }
            if (!inputStream.markSupported())
            {
              inputStream = new BufferedInputStream(inputStream);
            }
            inputStream.mark(Integer.MAX_VALUE);
          }
        }
      }
    }
    finally
    {
      if (inputStream != null)
      {
        inputStream.close();
      }
    }
  }
  
  InputStream createInputStream() throws IOException
  {
    return new ByteArrayInputStream(new byte[0]);
    
  }
}

results in a bogus warning on the call to "markSupported".  This looks like a regression relative to the Juno release, i.e., I have code like this in the EMF runtime that didn't previous have warnings.
Comment 1 Ed Merks CLA 2013-07-31 08:48:13 EDT
I should have said relative to Indigo, not Juno.
Comment 2 Stephan Herrmann CLA 2013-07-31 17:22:54 EDT
Thanks, Ed, for the report. I can reproduce.

At first glance I would have blamed this on how the JLS requires us to analyse the 
flow through a try-catch, but interestingly, the following example is accepted:

  void no_init_problem() throws IOException
  {
    InputStream inputStream;
    try
    {
      for (Object object : Collections.emptyList())
      {
        if (object != null)
        {
            try
            {
              inputStream = createInputStream();
            }
            catch (IOException exception)
            {
              inputStream = new ByteArrayInputStream(new byte [0]);
            }
            if (!inputStream.markSupported())
            {
              inputStream = new BufferedInputStream(inputStream);
            }
            inputStream.mark(Integer.MAX_VALUE);
        }
      }
    }
    finally
    {
    	// NOP
    }
  }

In this case we recognize that inputStream has been definitely assigned at the 
point of calling markSupported().


Next observation: the warning can be avoided by declaring the return of
createInputStream() as @NonNull (with null annotations enabled, obviously :) ).
That's odd since normally we prefer to remain silent after seeing an assignment 
with unknown nullness, but in this combination of 
- previously null
- assigning unknown
- inside a try
we somehow come to a wrong conclusion. 

I'll take a closer look when I find the time.
Comment 3 Till Brychcy CLA 2016-04-06 16:01:18 EDT
this is already fixed in 4.5.1 (i haven't checked in earlier versions)