### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.compiler.tool Index: src/org/eclipse/jdt/internal/compiler/tool/Options.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Options.java,v retrieving revision 1.12 diff -u -r1.12 Options.java --- src/org/eclipse/jdt/internal/compiler/tool/Options.java 25 Apr 2010 22:50:28 -0000 1.12 +++ src/org/eclipse/jdt/internal/compiler/tool/Options.java 20 Sep 2010 09:50:01 -0000 @@ -195,6 +195,7 @@ || token.equals("staticReceiver")//$NON-NLS-1$ || token.equals("super")//$NON-NLS-1$ || token.equals("suppress")//$NON-NLS-1$ + || token.equals("suppressAssertNull")//$NON-NLS-1$ || token.equals("syncOverride")//$NON-NLS-1$ || token.equals("synthetic-access")//$NON-NLS-1$ || token.equals("syntheticAccess")//$NON-NLS-1$ #P org.eclipse.jdt.core Index: batch/org/eclipse/jdt/internal/compiler/batch/Main.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java,v retrieving revision 1.353 diff -u -r1.353 Main.java --- batch/org/eclipse/jdt/internal/compiler/batch/Main.java 25 Apr 2010 20:10:08 -0000 1.353 +++ batch/org/eclipse/jdt/internal/compiler/batch/Main.java 20 Sep 2010 09:50:05 -0000 @@ -3456,7 +3456,12 @@ } else if (token.equals("super")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportOverridingMethodWithoutSuperInvocation, severity, isEnabling); return; - } + } else if (token.equals("suppressAssertNull")) { //$NON-NLS-1$ + this.options.put( + CompilerOptions.OPTION_SuppressNullInfoFromAsserts, + isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); + return; + } break; case 't' : if (token.startsWith("tasks")) { //$NON-NLS-1$ Index: batch/org/eclipse/jdt/internal/compiler/batch/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties,v retrieving revision 1.923 diff -u -r1.923 messages.properties --- batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 17 Sep 2010 19:35:19 -0000 1.923 +++ batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 20 Sep 2010 09:50:05 -0000 @@ -313,6 +313,8 @@ \ suppress + enable @SuppressWarnings\n\ \ When used with -err:, it can also silent optional\n\ \ errors and warnings\n\ +\ suppressAssertNull suppress null warnings for variables\n\ +\ that got tainted in an assert expression\n\ \ syncOverride missing synchronized in synchr. method override\n\ \ syntheticAccess synthetic access for innerclass\n\ \ tasks() tasks identified by tags inside comments\n\ Index: compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java,v retrieving revision 1.63 diff -u -r1.63 AssertStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 12 Aug 2010 16:58:28 -0000 1.63 +++ compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 20 Sep 2010 09:50:05 -0000 @@ -14,6 +14,7 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.codegen.*; import org.eclipse.jdt.internal.compiler.flow.*; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.lookup.*; import org.eclipse.jdt.internal.compiler.ASTVisitor; @@ -82,6 +83,11 @@ // change this if we need to carry null analysis results of the assert // expression downstream } else { + CompilerOptions compilerOptions = currentScope.compilerOptions(); + if (compilerOptions.suppressNullInfoFromAsserts) { + // keep just the initializations info, don't include assert's null info + return flowInfo.mergedWith(assertInfo.nullInfoLessUnconditionalCopy()); + } return flowInfo.mergedWith(assertInfo.nullInfoLessUnconditionalCopy()). addInitializationsFrom(assertWhenTrueInfo.discardInitializationInfo()); // keep the merge from the initial code for the definite assignment Index: compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java,v retrieving revision 1.231 diff -u -r1.231 CompilerOptions.java --- compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 8 Sep 2010 12:55:49 -0000 1.231 +++ compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 20 Sep 2010 09:50:05 -0000 @@ -131,7 +131,7 @@ public static final String OPTION_ReportDeadCodeInTrivialIfStatement = "org.eclipse.jdt.core.compiler.problem.deadCodeInTrivialIfStatement"; //$NON-NLS-1$ public static final String OPTION_ReportTasks = "org.eclipse.jdt.core.compiler.problem.tasks"; //$NON-NLS-1$ public static final String OPTION_ReportUnusedObjectAllocation = "org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation"; //$NON-NLS-1$ - + public static final String OPTION_SuppressNullInfoFromAsserts = "org.eclipse.jdt.core.compiler.problem.suppressNullInfoFromAsserts"; //$NON-NLS-1$ // Backward compatibility public static final String OPTION_ReportInvalidAnnotation = "org.eclipse.jdt.core.compiler.problem.invalidAnnotation"; //$NON-NLS-1$ public static final String OPTION_ReportMissingAnnotation = "org.eclipse.jdt.core.compiler.problem.missingAnnotation"; //$NON-NLS-1$ @@ -352,6 +352,8 @@ public boolean generateClassFiles; /** Indicate if method bodies should be ignored */ public boolean ignoreMethodBodies; + /** Suppress null related warnings for variables tainted inside an assert statement (java 1.5 and above)*/ + public boolean suppressNullInfoFromAsserts; // keep in sync with warningTokenToIrritant and warningTokenFromIrritant public final static String[] warningTokens = { @@ -914,6 +916,7 @@ optionsMap.put(OPTION_ReportDeadCodeInTrivialIfStatement, this.reportDeadCodeInTrivialIfStatement ? ENABLED : DISABLED); optionsMap.put(OPTION_ReportTasks, getSeverityString(Tasks)); optionsMap.put(OPTION_ReportUnusedObjectAllocation, getSeverityString(UnusedObjectAllocation)); + optionsMap.put(OPTION_SuppressNullInfoFromAsserts, this.suppressNullInfoFromAsserts ? ENABLED : DISABLED); return optionsMap; } @@ -1058,6 +1061,9 @@ // ignore method bodies this.ignoreMethodBodies = false; + + // allow null info from asserts to be considered downstream by default + this.suppressNullInfoFromAsserts = false; } public void set(Map optionsMap) { @@ -1264,6 +1270,13 @@ this.reportMissingOverrideAnnotationForInterfaceMethodImplementation = false; } } + if ((optionValue = optionsMap.get(OPTION_SuppressNullInfoFromAsserts)) != null) { + if (ENABLED.equals(optionValue)) { + this.suppressNullInfoFromAsserts = true; + } else if (DISABLED.equals(optionValue)) { + this.suppressNullInfoFromAsserts = false; + } + } if ((optionValue = optionsMap.get(OPTION_ReportMethodWithConstructorName)) != null) updateSeverity(MethodWithConstructorName, optionValue); if ((optionValue = optionsMap.get(OPTION_ReportOverridingPackageDefaultMethod)) != null) updateSeverity(OverriddenPackageDefaultMethod, optionValue); if ((optionValue = optionsMap.get(OPTION_ReportDeprecation)) != null) updateSeverity(UsingDeprecatedAPI, optionValue); @@ -1506,6 +1519,7 @@ buf.append("\n\t- missing @Override annotation for interface method implementation: ").append(this.reportMissingOverrideAnnotationForInterfaceMethodImplementation ? ENABLED : DISABLED); //$NON-NLS-1$ buf.append("\n\t- missing @Deprecated annotation: ").append(getSeverityString(MissingDeprecatedAnnotation)); //$NON-NLS-1$ buf.append("\n\t- incomplete enum switch: ").append(getSeverityString(IncompleteEnumSwitch)); //$NON-NLS-1$ + buf.append("\n\t- suppress null related warnings for variables tainted in assert statements: ").append(this.suppressNullInfoFromAsserts ? ENABLED : DISABLED); //$NON-NLS-1$ buf.append("\n\t- suppress warnings: ").append(this.suppressWarnings ? ENABLED : DISABLED); //$NON-NLS-1$ buf.append("\n\t- suppress optional errors: ").append(this.suppressOptionalErrors ? ENABLED : DISABLED); //$NON-NLS-1$ buf.append("\n\t- unhandled warning token: ").append(getSeverityString(UnhandledWarningToken)); //$NON-NLS-1$ #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java,v retrieving revision 1.210 diff -u -r1.210 BatchCompilerTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java 25 Aug 2010 11:11:58 -0000 1.210 +++ src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java 20 Sep 2010 09:50:19 -0000 @@ -1707,7 +1707,9 @@ " super overriding a method without making a super invocation\n" + " suppress + enable @SuppressWarnings\n" + " When used with -err:, it can also silent optional\n" + - " errors and warnings\n" + + " errors and warnings\n" + + " suppressAssertNull suppress null warnings for variables\n" + + " that got tainted in an assert expression\n" + " syncOverride missing synchronized in synchr. method override\n" + " syntheticAccess synthetic access for innerclass\n" + " tasks() tasks identified by tags inside comments\n" + @@ -1775,135 +1777,137 @@ true); String logContents = Util.fileContent(logFileName); String expectedLogContents = - "\n" + - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + + " NORMALIZED SECTION\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + "\n"; String normalizedExpectedLogContents = MessageFormat.format( @@ -11123,6 +11127,55 @@ "3 problems (3 warnings)", true); } + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342 +// -warn option - regression tests to check option suppressAssertNull +public void test293_warn_options() { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " void foo(Object a, Object b, Object c) {\n" + + " assert a == null;\n " + + " if (a!=null) {\n" + + " System.out.println(\"a is not null\");\n" + + " } else{\n" + + " System.out.println(\"a is null\");\n" + + " }\n" + + " a = null;\n" + + " if (a== null) {}\n" + + " assert b != null;\n " + + " if (b!=null) {\n" + + " System.out.println(\"b is not null\");\n" + + " } else{\n" + + " System.out.println(\"b is null\");\n" + + " }\n" + + " assert c == null;\n" + + " if (c.equals(a)) {\n" + + " System.out.println(\"\");\n" + + " } else{\n" + + " System.out.println(\"\");\n" + + " }\n" + + " }\n" + + " public static void main(String[] args){\n" + + " X test = new X();\n" + + " test.foo(null,null, null);\n" + + " }\n" + + "}\n", + }, + "\"" + OUTPUT_DIR + File.separator + "X.java\"" + + " -sourcepath \"" + OUTPUT_DIR + "\"" + + " -warn:null,suppressAssertNull -1.5 -proc:none -d \"" + OUTPUT_DIR + "\"", + "", + "----------\n" + + "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 10)\n" + + " if (a== null) {}\n" + + " ^\n" + + "Redundant null check: The variable a can only be null at this location\n" + + "----------\n" + + "1 problem (1 warning)", + true); +} //https://bugs.eclipse.org/bugs/show_bug.cgi?id=280784 public void test293(){ createCascadedJars(); Index: src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java,v retrieving revision 1.103 diff -u -r1.103 NullReferenceTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 15 Sep 2010 16:09:09 -0000 1.103 +++ src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 20 Sep 2010 09:50:20 -0000 @@ -13493,4 +13493,108 @@ null); } } + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342 +// EqualExpression in assert, comparison against non null +public void testBug325342a() { + if (this.complianceLevel >= ClassFileConstants.JDK1_5) { + Map compilerOptions = getCompilerOptions(); + compilerOptions.put(CompilerOptions.OPTION_SuppressNullInfoFromAsserts, CompilerOptions.ENABLED); + this.runNegativeTest( + new String[] { + "Test.java", + "public class Test {\n" + + " void foo(Object a, Object b, Object c) {\n" + + " assert a == null;\n " + + " if (a!=null) {\n" + + " System.out.println(\"a is not null\");\n" + + " } else{\n" + + " System.out.println(\"a is null\");\n" + + " }\n" + + " a = null;\n" + + " if (a== null) {}\n" + + " assert b != null;\n " + + " if (b!=null) {\n" + + " System.out.println(\"b is not null\");\n" + + " } else{\n" + + " System.out.println(\"b is null\");\n" + + " }\n" + + " assert c == null;\n" + + " if (c.equals(a)) {\n" + + " System.out.println(\"\");\n" + + " } else{\n" + + " System.out.println(\"\");\n" + + " }\n" + + " }\n" + + " public static void main(String[] args){\n" + + " Test test = new Test();\n" + + " test.foo(null,null, null);\n" + + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in Test.java (at line 10)\n" + + " if (a== null) {}\n" + + " ^\n" + + "Redundant null check: The variable a can only be null at this location\n" + + "----------\n", + null, + true, + compilerOptions); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342 +// EqualExpression in assert, comparison against non null +public void testBug325342b() { + if (this.complianceLevel >= ClassFileConstants.JDK1_5) { + Map compilerOptions = getCompilerOptions(); + compilerOptions.put(CompilerOptions.OPTION_SuppressNullInfoFromAsserts, CompilerOptions.DISABLED); + this.runNegativeTest( + new String[] { + "Test.java", + "public class Test {\n" + + " void foo(Object a, Object b, Object c) {\n" + + " assert a == null;\n " + + " if (a!=null) {\n" + + " System.out.println(\"a is not null\");\n" + + " } else{\n" + + " System.out.println(\"a is null\");\n" + + " }\n" + + " assert b != null;\n " + + " if (b!=null) {\n" + + " System.out.println(\"a is not null\");\n" + + " } else{\n" + + " System.out.println(\"a is null\");\n" + + " }\n" + + " assert c == null;\n" + + " if (c.equals(a)) {\n" + + " System.out.println(\"\");\n" + + " } else{\n" + + " System.out.println(\"\");\n" + + " }\n" + + " }\n" + + " public static void main(String[] args){\n" + + " Test test = new Test();\n" + + " test.foo(null,null,null);\n" + + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in Test.java (at line 4)\n" + + " if (a!=null) {\n" + + " ^\n" + + "Null comparison always yields false: The variable a can only be null at this location\n" + + "----------\n" + + "2. ERROR in Test.java (at line 10)\n" + + " if (b!=null) {\n" + + " ^\n" + + "Redundant null check: The variable b cannot be null at this location\n" + + "----------\n" + + "3. ERROR in Test.java (at line 16)\n" + + " if (c.equals(a)) {\n" + + " ^\n" + + "Null pointer access: The variable c can only be null at this location\n" + + "----------\n", + null, true, compilerOptions); + } +} } \ No newline at end of file