barry-m / checker-framework

Automatically exported from code.google.com/p/checker-framework
Other
0 stars 0 forks source link

Assignment in initializer between two uninitialized variables results in an initialized variable #345

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Run the NullnessChecker on the following code snippet (also attached):
public class Test {
    String f1;
    String f2;

    {
        f1 = f2;
        f2 = f1;
        f2.toString();   //Null pointer exception here
    }

    public static void main(String [] args) {
        Test a = new Test();
    }
}

What is the expected output? What do you see instead?
The first assignment should issue a warning since it would expect an 
initialized value.  EIther that, or the field f1 should not be considered 
initialized after the assignment.

What version of the product are you using? On what operating system?
Checker Framework 1.8.4

Original issue reported on code.google.com by Jonathan...@gmail.com on 8 Aug 2014 at 7:32

Attachments:

GoogleCodeExporter commented 9 years ago
Note that the issue also arises for constructors.
So the test case for the repository should contain:
1. initializer as above, expecting an error on first assignment.
2. constructor with the same body as the initializer, also expecting an error.
3. a normal method, no error.

cu, WMD.

Original comment by wdi...@gmail.com on 8 Aug 2014 at 7:42

GoogleCodeExporter commented 9 years ago
I'll add the test case as you specified.  Werner, do you believe the correct 
behavior would be to issue an [assignment.type.incompatible] on the assignments?

Original comment by jbu...@cs.washington.edu on 8 Aug 2014 at 7:51

GoogleCodeExporter commented 9 years ago
Yes, I think there should be an assignment error for the first assignment.
The alternative you had (f1 not being initialized after the assignment) doesn't 
work, I think; you could have:

class Test {
    String f1;
    String f2;

    Test() {
        f1 = f2;
        f2 = "";
    }

    public static void main(String [] args) {
        Test a = new Test();
        a.f1.toString();
    }
}

So even if we considered f1 uninitialized at the end of the constructor, 
afterwards we'll only use the declared type. So in main f1 will still be null 
and we didn't get a warning.

Original comment by wdi...@gmail.com on 8 Aug 2014 at 7:56