Bug 313870 - Wrong warnings on Java.Compiler.Errors/Warnings "Redundant null check"
Summary: Wrong warnings on Java.Compiler.Errors/Warnings "Redundant null check"
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.6   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 3.7 M6   Edit
Assignee: Ayushman Jain CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 332713 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-05-21 03:22 EDT by Dietmar Hechensteiner CLA
Modified: 2011-03-07 11:34 EST (History)
6 users (show)

See Also:
stephan.herrmann: review+


Attachments
Contains test case (399 bytes, application/octet-stream)
2010-05-21 03:25 EDT, Dietmar Hechensteiner CLA
no flags Details
possible fix (1.66 KB, patch)
2011-02-09 02:39 EST, Ayushman Jain CLA
no flags Details | Diff
proposed fix v1.0 + regression tests (4.57 KB, patch)
2011-02-09 12:30 EST, Ayushman Jain CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dietmar Hechensteiner CLA 2010-05-21 03:22:51 EDT
Build Identifier: I20100513-1500

See attached test case

Reproducible: Always

Steps to Reproduce:
1. Compile test case. You can see one false warnings if the compiler setting
"Redundant null check" is on.
Comment 1 Dietmar Hechensteiner CLA 2010-05-21 03:25:36 EDT
Created attachment 169480 [details]
Contains test case
Comment 2 Srikanth Sankaran CLA 2010-05-21 03:30:22 EDT
Ayush, please follow up.
Comment 3 Paul Wagland CLA 2011-02-08 21:34:38 EST
I have essentially the same problem, with essentially the same reproduction
test case. If the initial line = "" is changed to line= null then the warning
goes away. It does not change based on whether the initial doRead is set to
true or false.


package net.wagland.paul.test;

import java.io.BufferedReader;
import java.io.IOException;

public class NullWarningTest {
  public void testNullWarning(BufferedReader bufReader) throws IOException {
    String line = "";
    boolean doRead = false;
    while (true) {
      if (doRead)
        line = bufReader.readLine();
      if (line == null)
        return;
      doRead = true;
    }
  }
}

I am getting this warning on eclipse Version: 3.6.2 Build id: M20110204-1030 (aka 3.6.3 RC3)

Bug 332713 should be marked as a duplicate of this bug.
Comment 4 Ayushman Jain CLA 2011-02-09 01:09:55 EST
(In reply to comment #3)
> Bug 332713 should be marked as a duplicate of this bug.

I don't think its a dup.
Comment 5 Paul Wagland CLA 2011-02-09 01:58:06 EST
(In reply to comment #4)
> (In reply to comment #3)
> > Bug 332713 should be marked as a duplicate of this bug.
> 
> I don't think its a dup.

I disagree. If you change my "while" to "for" then you get pretty much identical code. The only difference is that in the attachment, the boolean does not change value through the loop, however that is not required to produce this false warning. And this, in turn, is conceptually identical to the first test case on bug 332713.
Comment 6 Ayushman Jain CLA 2011-02-09 02:15:34 EST
(In reply to comment #5)
> (In reply to comment #4)
> > (In reply to comment #3)
> > > Bug 332713 should be marked as a duplicate of this bug.
> > 
> > I don't think its a dup.

Sorry, I was looking at the wrong bug. These 2 indeed are dups
Comment 7 Ayushman Jain CLA 2011-02-09 02:16:54 EST
*** Bug 332713 has been marked as a duplicate of this bug. ***
Comment 8 Ayushman Jain CLA 2011-02-09 02:39:12 EST
Created attachment 188566 [details]
possible fix

Fix for bug 291418 should've also checked for the variable declared outside a loop being possibly assigned inside one of the branches of the loop, since that assignment can change the null status, even if it doesnt mark the variable as null or non null per se.
Comment 9 Ayushman Jain CLA 2011-02-09 12:30:10 EST
Created attachment 188605 [details]
proposed fix v1.0 + regression tests

same fix as above with tests added.

The fix basically just adds a check to make sure that the null status has not been affected inside a loop by means of an assignment, before assuming that the null status can be borrowed from upstream info.
Comment 10 Ayushman Jain CLA 2011-02-09 12:31:09 EST
Stephan can you please review the changes when you have time? Thanks!
Comment 11 Stephan Herrmann CLA 2011-02-15 07:36:56 EST
(In reply to comment #10)
> Stephan can you please review the changes when you have time? Thanks!

I tried to break the patch but couldn't, so it looks good.

I wondered why that condition only asks the flowInfo.isPotentially.. bits,
but flowInfo.isDefinitely... is already asked earlier in the same method 
so it looks complete now.

Next I checked for possible interaction with the pending fix for bug 336428
since it operates in the same neighborhood, but the issues are actually
independent.

My final concern was trying to understand why this is relevant:
  this.upstreamNullFlowInfo.isDefinitelyNonNull(local)
whereas the opposite is not
  this.upstreamNullFlowInfo.isDefinitelyNull(local)

Trying to understand these in context led me to puzzle about this comment:
  // prot. non null + prot. null => pot. null // PREMATURE use tainted instead
(in NullReferenceImplTransformations).

This makes the semantics of mergedWith(..) asymmetric which is surprising.

However, in that larger context I couldn't see any easy answers (do you see
why these things are so asymmetric?) and your patch is surely the best
we can do right now, hence +1.

(You might just want to add some linebreak so the comment starts somewhere
before column 162 :) )
Comment 12 Stephan Herrmann CLA 2011-02-15 13:01:43 EST
(In reply to comment #11)
> Trying to understand these in context led me to puzzle about this comment:
>   // prot. non null + prot. null => pot. null // PREMATURE use tainted instead
> (in NullReferenceImplTransformations).
> 
> This makes the semantics of mergedWith(..) asymmetric which is surprising.

I tried hard to find a test that breaks due to a missing pot.-non-null bit.
I found that pot.-non-null is only used in combination with definitely-null
in order stop us from reporting "can only be null". 
If we also have pot.null in the mix that warning will never occur 
so pot.-non-null can be safely dropped in the mentioned merge.

Thus all looks fine to me, no reason to worry about asymmetry here.
Comment 13 Ayushman Jain CLA 2011-02-16 10:42:01 EST
(In reply to comment #12)
> Thus all looks fine to me, no reason to worry about asymmetry here.

Thanks Stephan, I'll release the fix today.

(In reply to comment #11)
> (You might just want to add some linebreak so the comment starts somewhere
> before column 162 :) )

Will do!
Comment 14 Ayushman Jain CLA 2011-02-16 13:58:30 EST
Released in HEAD for 3.7M6
Comment 15 Paul Wagland CLA 2011-02-17 02:47:17 EST
Is there any chance of getting this in for the 3.6.2 release?
Comment 16 Ayushman Jain CLA 2011-02-17 04:33:12 EST
(In reply to comment #15)
> Is there any chance of getting this in for the 3.6.2 release?

Unfortunately no. We're too close to shipping 3.6.2 to make any more changes. Besides, this is not really a blocking issue.
Comment 17 Olivier Thomann CLA 2011-03-07 11:34:51 EST
Verified for 3.7M6.