diff options
| author | Stephan Herrmann | 2013-05-16 07:20:22 +0000 |
|---|---|---|
| committer | Jayaprakash Arthanareeswaran | 2013-05-16 10:58:54 +0000 |
| commit | 47466daad88774b9542c26be2fa2eb0f129ed0bd (patch) | |
| tree | 6dafdcf8852b9da8d4f5683a2c979f94094ef1d0 | |
| parent | fa66834f9f4ec8541916655f7830d28cd8630692 (diff) | |
| download | eclipse.jdt.core-47466daad88774b9542c26be2fa2eb0f129ed0bd.tar.gz eclipse.jdt.core-47466daad88774b9542c26be2fa2eb0f129ed0bd.tar.xz eclipse.jdt.core-47466daad88774b9542c26be2fa2eb0f129ed0bd.zip | |
Bug 403086 - [compiler][null] include the effect of 'assert' in
syntactic null analysis for fields
8 files changed, 107 insertions, 13 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java index a90c01da95..c585d49f4f 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java @@ -28,7 +28,7 @@ public NullAnnotationTest(String name) { // Static initializer to specify tests subset using TESTS_* static variables // All specified tests which do not belong to the class are skipped... static { -// TESTS_NAMES = new String[] { "test_parameter_specification_inheritance_01" }; +// TESTS_NAMES = new String[] { "test_nullable_field_10c" }; // TESTS_NUMBERS = new int[] { 561 }; // TESTS_RANGE = new int[] { 1, 2049 }; } @@ -4630,7 +4630,15 @@ public void test_nullable_field_10c() { " if (o1 != null || o2 != null || o3 != null) \n" + " System.out.println(o2.toString()); // warn here: disjunktion is no protection\n" + " if (!(o1 != null)) \n" + - " System.out.println(o1.toString()); // warn here: negation is no protection\n" + + " System.out.println(o1.toString()); // warn here: negated inequality is no protection\n" + + " if (!(o1 == null || o2 == null)) \n" + + " System.out.println(o1.toString()); // don't warn here\n" + + " if (!(o1 == null && o2 == null)) \n" + + " System.out.println(o2.toString()); // warn here: negated conjunction is no protection\n" + + " if (!(!(o1 == null))) \n" + + " System.out.println(o1.toString()); // warn here: double negation is no protection\n" + + " if (!(!(o1 != null && o2 != null))) \n" + + " System.out.println(o1.toString()); // don't warn here\n" + " }\n" + "}\n" }, @@ -4642,7 +4650,17 @@ public void test_nullable_field_10c() { "Potential null pointer access: The field o2 is declared as @Nullable\n" + "----------\n" + "2. ERROR in X.java (at line 10)\n" + - " System.out.println(o1.toString()); // warn here: negation is no protection\n" + + " System.out.println(o1.toString()); // warn here: negated inequality is no protection\n" + + " ^^\n" + + "Potential null pointer access: The field o1 is declared as @Nullable\n" + + "----------\n" + + "3. ERROR in X.java (at line 14)\n" + + " System.out.println(o2.toString()); // warn here: negated conjunction is no protection\n" + + " ^^\n" + + "Potential null pointer access: The field o2 is declared as @Nullable\n" + + "----------\n" + + "4. ERROR in X.java (at line 16)\n" + + " System.out.println(o1.toString()); // warn here: double negation is no protection\n" + " ^^\n" + "Potential null pointer access: The field o1 is declared as @Nullable\n" + "----------\n"); @@ -6000,4 +6018,64 @@ public void test_conditional_expression_1() { "Potential null pointer access: This expression of type Boolean may be null but requires auto-unboxing\n" + "----------\n"); } + +// Bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields +public void testBug403086_1() { + Map customOptions = getCompilerOptions(); + customOptions.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR); + customOptions.put(JavaCore.COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS, JavaCore.ENABLED); + customOptions.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED); + runConformTestWithLibs( + new String[] { + NullReferenceTestAsserts.JUNIT_ASSERT_NAME, + NullReferenceTestAsserts.JUNIT_ASSERT_CONTENT, + "Y.java", + "import org.eclipse.jdt.annotation.*;\n" + + "class Y {\n" + + " @Nullable String str;\n" + + " int foo(@Nullable String str2) {\n" + + " int i;\n" + + " junit.framework.Assert.assertNotNull(str);\n" + + " i = str.length();\n" + + "\n" + + " assert this.str != null;\n" + + " i = str.length();\n" + + "\n" + + " return i;\n" + + " }\n" + + "}\n" + }, + customOptions, + ""); +} + +//Bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields +public void testBug403086_2() { + Map customOptions = getCompilerOptions(); + customOptions.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR); + customOptions.put(JavaCore.COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS, JavaCore.ENABLED); + customOptions.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED); + runConformTestWithLibs( + new String[] { + NullReferenceTestAsserts.JUNIT_ASSERT_NAME, + NullReferenceTestAsserts.JUNIT_ASSERT_CONTENT, + "Y.java", + "import org.eclipse.jdt.annotation.*;\n" + + "class Y {\n" + + " @Nullable String str;\n" + + " int foo(@Nullable String str2) {\n" + + " int i;\n" + + " junit.framework.Assert.assertNotNull(str);\n" + + " i = str.length();\n" + + "\n" + + " assert ! (this.str == null);\n" + + " i = str.length();\n" + + "\n" + + " return i;\n" + + " }\n" + + "}\n" + }, + customOptions, + ""); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java index 254d50f4a0..8ae057c527 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,7 +7,9 @@ * * Contributors: * IBM Corporation - initial API and implementation - * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE + * Stephan Herrmann - Contributions for + * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE + * bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; @@ -47,6 +49,8 @@ public class AND_AND_Expression extends BinaryExpression { } FlowInfo leftInfo = this.left.analyseCode(currentScope, flowContext, flowInfo); + if ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) != 0) + flowContext.expireNullCheckedFieldInfo(); // need to be careful of scenario: // (x && y) && !z, if passing the left info to the right, it would be // swapped by the ! @@ -61,6 +65,8 @@ public class AND_AND_Expression extends BinaryExpression { } } rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo); + if ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) != 0) + flowContext.expireNullCheckedFieldInfo(); if ((this.left.implicitConversion & TypeIds.UNBOXING) != 0) { this.left.checkNPE(currentScope, flowContext, flowInfo); } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java index 71c86c259a..7cc168bb54 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ * Stephan Herrmann - Contributions for * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE * bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null" + * bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; @@ -54,6 +55,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl flowContext.tagBits |= FlowContext.HIDE_NULL_COMPARISON_WARNING; FlowInfo conditionFlowInfo = this.assertExpression.analyseCode(currentScope, flowContext, flowInfo.copy()); + flowContext.extendTimeToLiveForNullCheckedField(1); // survive this assert as a Statement flowContext.tagBits &= ~FlowContext.HIDE_NULL_COMPARISON_WARNING; UnconditionalFlowInfo assertWhenTrueInfo = conditionFlowInfo.initsWhenTrue().unconditionalInits(); FlowInfo assertInfo = conditionFlowInfo.initsWhenFalse(); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java index ff8c93ec1b..909bc0d49b 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java @@ -12,6 +12,7 @@ * bug 331649 - [compiler][null] consider null annotations for fields * bug 383368 - [compiler][null] syntactic null analysis for field references * bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions + * bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; @@ -47,7 +48,7 @@ public class EqualExpression extends BinaryExpression { rightNonNullChecked = scope.problemReporter().expressionNonNullComparison(this.right, checkEquality); } - boolean contextualCheckEquality = checkEquality ^ ((flowContext.tagBits & FlowContext.INSIDE_NEGATIVE_ASSERT) != 0); + boolean contextualCheckEquality = checkEquality ^ ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) != 0); // perform flowInfo-based checks for variables and record info for syntactic null analysis for fields: if (!leftNonNullChecked) { LocalVariableBinding local = this.left.localVariableBinding(); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java index e710768a59..9825fb7bf5 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java @@ -31,6 +31,7 @@ * bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions * bug 382350 - [1.8][compiler] Unable to invoke inherited default method via I.super.m() syntax * bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super + * bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields * Jesper S Moller - Contributions for * Bug 378674 - "The method can be declared as static" is wrong * Andy Clement - Contributions for @@ -263,7 +264,7 @@ private FlowInfo analyseBooleanAssertion(BlockScope currentScope, Expression arg int tagBitsSave = flowContext.tagBits; flowContext.tagBits |= FlowContext.HIDE_NULL_COMPARISON_WARNING; if (!passOnTrue) - flowContext.tagBits |= FlowContext.INSIDE_NEGATIVE_ASSERT; // this affects syntactic analysis for fields in EqualExpression + flowContext.tagBits |= FlowContext.INSIDE_NEGATION; // this affects syntactic analysis for fields in EqualExpression FlowInfo conditionFlowInfo = argument.analyseCode(currentScope, flowContext, flowInfo.copy()); flowContext.extendTimeToLiveForNullCheckedField(2); // survive this assert as a MessageSend and as a Statement flowContext.tagBits = tagBitsSave; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java index 111714a5d0..4d05409f31 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java @@ -10,6 +10,7 @@ * Stephan Herrmann - Contributions for * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE * bug 383368 - [compiler][null] syntactic null analysis for field references + * bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; @@ -52,7 +53,8 @@ public class OR_OR_Expression extends BinaryExpression { } FlowInfo leftInfo = this.left.analyseCode(currentScope, flowContext, flowInfo); - flowContext.expireNullCheckedFieldInfo(); + if ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) == 0) + flowContext.expireNullCheckedFieldInfo(); // need to be careful of scenario: // (x || y) || !z, if passing the left info to the right, it would be swapped by the ! @@ -68,7 +70,8 @@ public class OR_OR_Expression extends BinaryExpression { } } rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo); - flowContext.expireNullCheckedFieldInfo(); + if ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) == 0) + flowContext.expireNullCheckedFieldInfo(); if ((this.left.implicitConversion & TypeIds.UNBOXING) != 0) { this.left.checkNPE(currentScope, flowContext, flowInfo); } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java index 81b932311f..c3c94ba46b 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java @@ -9,6 +9,7 @@ * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for * bug 383368 - [compiler][null] syntactic null analysis for field references + * bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; @@ -35,10 +36,11 @@ public FlowInfo analyseCode( FlowInfo flowInfo) { this.expression.checkNPE(currentScope, flowContext, flowInfo); if (((this.bits & OperatorMASK) >> OperatorSHIFT) == NOT) { + flowContext.tagBits ^= FlowContext.INSIDE_NEGATION; flowInfo = this.expression. analyseCode(currentScope, flowContext, flowInfo). asNegatedCondition(); - flowContext.expireNullCheckedFieldInfo(); + flowContext.tagBits ^= FlowContext.INSIDE_NEGATION; return flowInfo; } else { return this.expression. diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java index d1e571c606..3806cfcc8f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java @@ -19,6 +19,7 @@ * bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null" * bug 383368 - [compiler][null] syntactic null analysis for field references * bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check + * bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields *******************************************************************************/ package org.eclipse.jdt.internal.compiler.flow; @@ -85,8 +86,8 @@ public class FlowContext implements TypeConstants { public static final int DEFER_NULL_DIAGNOSTIC = 0x1; public static final int PREEMPT_NULL_DIAGNOSTIC = 0x2; - // inside an assertFalse checks for equality / inequality have reversed meaning for syntactic analysis for fields: - public static final int INSIDE_NEGATIVE_ASSERT = 0x4; + // inside an assertFalse or a not-expression checks for equality / inequality have reversed meaning for syntactic analysis for fields: + public static final int INSIDE_NEGATION = 0x4; /** * used to hide null comparison related warnings inside assert statements */ |
