/******************************************************************************* * Copyright (c) 2013, 2014 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for * bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions * Bug 454031 - [compiler][null][loop] bug in null analysis; wrong "dead code" detection *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; import java.io.File; import java.io.IOException; import java.util.Map; import junit.framework.Test; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; /* See also NullReferenceTests for general null reference tests */ @SuppressWarnings({ "unchecked", "rawtypes" }) public class NullReferenceTestAsserts extends AbstractRegressionTest { // class libraries including org.eclipse.equinox.common String[] assertLib = null; public NullReferenceTestAsserts(String name) { super(name); } // Static initializer to specify tests subset using TESTS_* static variables // All specified tests which does not belong to the class are skipped... // Only the highest compliance level is run; add the VM argument // -Dcompliance=1.4 (for example) to lower it if needed static { // TESTS_NAMES = new String[] { "testBug382069" }; // TESTS_NUMBERS = new int[] { 561 }; // TESTS_RANGE = new int[] { 1, 2049 }; } static final String JUNIT_ASSERT_NAME = "junit/framework/Assert.java"; static final String JUNIT_ASSERT_CONTENT = "package junit.framework;\n" + "public class Assert {\n" + " static public void assertNull(Object object) {}\n" + " static public void assertNull(String message, Object object) {}\n" + " static public void assertNotNull(Object object) {}\n" + " static public void assertNotNull(String message, Object object) {}\n" + " static public void assertTrue(boolean expression) {}\n" + " static public void assertTrue(String message, boolean expression) {}\n" + " static public void assertFalse(boolean expression) {}\n" + " static public void assertFalse(String message, boolean expression) {}\n" + "}\n"; static final String ORG_JUNIT_ASSERT_NAME = "org/junit/Assert.java"; static final String ORG_JUNIT_ASSERT_CONTENT = "package org.junit;\n" + "public class Assert {\n" + " static public void assertNull(Object object) {}\n" + " static public void assertNull(String message, Object object) {}\n" + " static public void assertNotNull(Object object) {}\n" + " static public void assertNotNull(String message, Object object) {}\n" + " static public void assertTrue(boolean expression) {}\n" + " static public void assertTrue(String message, boolean expression) {}\n" + " static public void assertFalse(boolean expression) {}\n" + " static public void assertFalse(String message, boolean expression) {}\n" + "}\n"; static final String APACHE_VALIDATE_NAME = "org/apache/commons/lang/Validate.java"; static final String APACHE_VALIDATE_CONTENT = "package org.apache.commons.lang;\n" + "public class Validate {\n" + " static public void notNull(Object object) {}\n" + " static public void notNull(Object object, String message) {}\n" + " static public void isTrue(boolean expression) {}\n" + " static public void isTrue(boolean expression, String message) {}\n" + " static public void isTrue(boolean expression, String message, double value) {}\n" + " static public void isTrue(boolean expression, String message, long value) {}\n" + " static public void isTrue(boolean expression, String message, Object value) {}\n" + "}\n"; static final String APACHE_3_VALIDATE_NAME = "org/apache/commons/lang3/Validate.java"; static final String APACHE_3_VALIDATE_CONTENT = "package org.apache.commons.lang3;\n" + "public class Validate {\n" + " static public <T> T notNull(T object) { return object; }\n" + " static public <T> T notNull(T object, String message, Object... values) { return object; }\n" + " static public void isTrue(boolean expression) {}\n" + " static public void isTrue(boolean expression, String message, double value) {}\n" + " static public void isTrue(boolean expression, String message, long value) {}\n" + " static public void isTrue(boolean expression, String message, Object value) {}\n" + "}\n"; static final String GOOGLE_PRECONDITIONS_NAME = "com/google/common/base/Preconditions.java"; static final String GOOGLE_PRECONDITIONS_CONTENT = "package com.google.common.base;\n" + "public class Preconditions {\n" + " static public <T> T checkNotNull(T object) { return object; }\n" + " static public <T> T checkNotNull(T object, Object message) { return object; }\n" + " static public <T> T checkNotNull(T object, String message, Object... values) { return object; }\n" + " static public void checkArgument(boolean expression) {}\n" + " static public void checkArgument(boolean expression, Object message) {}\n" + " static public void checkArgument(boolean expression, String msgTmpl, Object... messageArgs) {}\n" + " static public void checkState(boolean expression) {}\n" + " static public void checkState(boolean expression, Object message) {}\n" + " static public void checkState(boolean expression, String msgTmpl, Object... messageArgs) {}\n" + "}\n"; public static Test suite() { return buildAllCompliancesTestSuite(testClass()); } public static Class testClass() { return NullReferenceTestAsserts.class; } protected void setUp() throws Exception { super.setUp(); if (this.assertLib == null) { String[] defaultLibs = getDefaultClassPaths(); int len = defaultLibs.length; this.assertLib = new String[len+1]; System.arraycopy(defaultLibs, 0, this.assertLib, 0, len); File bundleFile = FileLocator.getBundleFile(Platform.getBundle("org.eclipse.equinox.common")); if (bundleFile.isDirectory()) this.assertLib[len] = bundleFile.getPath()+"/bin"; else this.assertLib[len] = bundleFile.getPath(); } } // Conditionally augment problem detection settings static boolean setNullRelatedOptions = true; protected Map getCompilerOptions() { Map defaultOptions = super.getCompilerOptions(); if (setNullRelatedOptions) { defaultOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); defaultOptions.put(CompilerOptions.OPTION_ReportPotentialNullReference, CompilerOptions.ERROR); defaultOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); defaultOptions.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE); defaultOptions.put(CompilerOptions.OPTION_IncludeNullInfoFromAsserts, CompilerOptions.ENABLED); } return defaultOptions; } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 public void testBug127575a() throws IOException { this.runConformTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o) {\n" + " boolean b = o != null;\n" + // sheds doubts upon o " org.eclipse.core.runtime.Assert.isLegal(o != null);\n" + // protection " o.toString();\n" + // quiet " }\n" + "}\n"}, "", this.assertLib, true, null); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 public void testBug127575b() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o) {\n" + " org.eclipse.core.runtime.Assert.isLegal(o == null);\n" + // forces null " o.toString();\n" + // can only be null " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 4)\n" + " o.toString();\n" + " ^\n" + "Null pointer access: The variable o can only be null at this location\n" + "----------\n", this.assertLib, true); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 public void testBug127575c() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o, boolean b) {\n" + " org.eclipse.core.runtime.Assert.isLegal(o != null || b, \"FAIL\");\n" + // shed doubts " o.toString();\n" + // complain " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 4)\n" + " o.toString();\n" + " ^\n" + "Potential null pointer access: The variable o may be null at this location\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 public void testBug127575d() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o1, Object o2) {\n" + " org.eclipse.core.runtime.Assert.isLegal(o1 != null && o2 == null);\n" + " if (o1 == null) { };\n" + // complain " if (o2 == null) { };\n" + // complain " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 4)\n" + " if (o1 == null) { };\n" + " ^^\n" + "Null comparison always yields false: The variable o1 cannot be null at this location\n" + "----------\n" + "2. WARNING in X.java (at line 4)\n" + " if (o1 == null) { };\n" + " ^^^\n" + "Dead code\n" + "----------\n" + "3. ERROR in X.java (at line 5)\n" + " if (o2 == null) { };\n" + " ^^\n" + "Redundant null check: The variable o2 can only be null at this location\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 public void testBug127575e() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o) {\n" + " org.eclipse.core.runtime.Assert.isLegal(false && o != null);\n" + " if (o == null) { };\n" + // quiet " }\n" + "}\n"}, "----------\n" + "1. WARNING in X.java (at line 3)\n" + " org.eclipse.core.runtime.Assert.isLegal(false && o != null);\n" + " ^^^^^^^^^\n" + "Dead code\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 public void testBug127575e_1() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o) {\n" + " o = null;\n" + " org.eclipse.core.runtime.Assert.isLegal(false && o != null);\n" + " if (o == null) { };\n" + // warn on o because o was null above. " }\n" + "}\n"}, "----------\n" + "1. WARNING in X.java (at line 4)\n" + " org.eclipse.core.runtime.Assert.isLegal(false && o != null);\n" + " ^^^^^^^^^\n" + "Dead code\n" + "----------\n" + "2. ERROR in X.java (at line 5)\n" + " if (o == null) { };\n" + " ^\n" + "Redundant null check: The variable o can only be null at this location\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 public void testBug127575e_2() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o) {\n" + " org.eclipse.core.runtime.Assert.isLegal(true || o != null);\n" + " if (o == null) { };\n" + // quiet " }\n" + "}\n"}, "----------\n" + "1. WARNING in X.java (at line 3)\n" + " org.eclipse.core.runtime.Assert.isLegal(true || o != null);\n" + " ^^^^^^^^^\n" + "Dead code\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 public void testBug127575f() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o) {\n" + " org.eclipse.core.runtime.Assert.isLegal(false || o != null);\n" + " if (o == null) { };\n" + // complain " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 4)\n" + " if (o == null) { };\n" + " ^\n" + "Null comparison always yields false: The variable o cannot be null at this location\n" + "----------\n" + "2. WARNING in X.java (at line 4)\n" + " if (o == null) { };\n" + " ^^^\n" + "Dead code\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 // do warn always false comparisons even inside org.eclipse.core.runtime.Assert.isLegal public void testBug127575g() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void foo() {\n" + " Object o = null;\n" + " org.eclipse.core.runtime.Assert.isLegal(o != null);\n" + // don't complain " if (o == null) { };\n" + // complain " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 4)\n" + " org.eclipse.core.runtime.Assert.isLegal(o != null);\n" + " ^\n" + "Null comparison always yields false: The variable o can only be null at this location\n" + "----------\n" + "2. ERROR in X.java (at line 5)\n" + " if (o == null) { };\n" + " ^\n" + "Null comparison always yields false: The variable o cannot be null at this location\n" + "----------\n" + "3. WARNING in X.java (at line 5)\n" + " if (o == null) { };\n" + " ^^^\n" + "Dead code\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 // Test to verify that asserts are exempted from redundant null check warnings, // but this doesn't affect the downstream info. public void testBug127575h() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void m() {\n" + " X foo = new X();\n" + " org.eclipse.core.runtime.Assert.isLegal (foo != null);\n" + // redundant check - don't warn " if (foo == null) {}\n" + " X foo2 = new X();\n" + " org.eclipse.core.runtime.Assert.isLegal (foo2 == null);\n" + // always false check - warn " if (foo2 == null) {}\n" + " X bar = null;\n" + " org.eclipse.core.runtime.Assert.isLegal (bar == null);\n" + // redundant check - don't warn " if (bar == null) {}\n" + " X bar2 = null;\n" + " org.eclipse.core.runtime.Assert.isLegal (bar2 != null);\n" + // always false check - warn " if (bar2 == null) {}\n" + " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 5)\n" + " if (foo == null) {}\n" + " ^^^\n" + "Null comparison always yields false: The variable foo cannot be null at this location\n" + "----------\n" + "2. WARNING in X.java (at line 5)\n" + " if (foo == null) {}\n" + " ^^\n" + "Dead code\n" + "----------\n" + "3. ERROR in X.java (at line 7)\n" + " org.eclipse.core.runtime.Assert.isLegal (foo2 == null);\n" + " ^^^^\n" + "Null comparison always yields false: The variable foo2 cannot be null at this location\n" + "----------\n" + "4. ERROR in X.java (at line 8)\n" + " if (foo2 == null) {}\n" + " ^^^^\n" + "Redundant null check: The variable foo2 can only be null at this location\n" + "----------\n" + "5. ERROR in X.java (at line 11)\n" + " if (bar == null) {}\n" + " ^^^\n" + "Redundant null check: The variable bar can only be null at this location\n" + "----------\n" + "6. ERROR in X.java (at line 13)\n" + " org.eclipse.core.runtime.Assert.isLegal (bar2 != null);\n" + " ^^^^\n" + "Null comparison always yields false: The variable bar2 can only be null at this location\n" + "----------\n" + "7. ERROR in X.java (at line 14)\n" + " if (bar2 == null) {}\n" + " ^^^^\n" + "Null comparison always yields false: The variable bar2 cannot be null at this location\n" + "----------\n" + "8. WARNING in X.java (at line 14)\n" + " if (bar2 == null) {}\n" + " ^^\n" + "Dead code\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 // Test to verify that asserts are exempted from redundant null check warnings, // but this doesn't affect the downstream info. public void testBug127575i() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void m() {\n" + " X bar = null;\n" + " X foo = getX();\n" + " if (foo == null) {\n" + " foo = new X();\n" + " }\n" + " org.eclipse.core.runtime.Assert.isTrue (foo != null && bar == null);\n" + // don't warn but do the null analysis " if (foo != null) {}\n" + // warn " if (bar == null) {}\n" + // warn " }\n" + " public X getX() { return new X();}\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 9)\n" + " if (foo != null) {}\n" + " ^^^\n" + "Redundant null check: The variable foo cannot be null at this location\n" + "----------\n" + "2. ERROR in X.java (at line 10)\n" + " if (bar == null) {}\n" + " ^^^\n" + "Redundant null check: The variable bar can only be null at this location\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 // Test to verify that asserts are exempted from redundant null check warnings in a looping context, // but this doesn't affect the downstream info. public void testBug127575j() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void m() {\n" + " X foo = new X();\n" + " X foo2 = new X();\n" + " X bar = null;\n" + " X bar2 = null;\n" + " while (true) {\n" + " org.eclipse.core.runtime.Assert.isLegal (foo != null);\n" + //don't warn " if (foo == null) {}\n" + " org.eclipse.core.runtime.Assert.isLegal (foo2 == null);\n" + //don't warn " if (foo2 == null) {}\n" + " org.eclipse.core.runtime.Assert.isLegal (bar == null);\n" + //don't warn " if (bar == null) {}\n" + " org.eclipse.core.runtime.Assert.isLegal (bar2 != null);\n" + //don't warn " if (bar2 == null) {}\n" + " }\n" + " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 9)\n" + " if (foo == null) {}\n" + " ^^^\n" + "Null comparison always yields false: The variable foo cannot be null at this location\n" + "----------\n" + "2. WARNING in X.java (at line 9)\n" + " if (foo == null) {}\n" + " ^^\n" + "Dead code\n" + "----------\n" + "3. ERROR in X.java (at line 10)\n" + " org.eclipse.core.runtime.Assert.isLegal (foo2 == null);\n" + " ^^^^\n" + "Null comparison always yields false: The variable foo2 cannot be null at this location\n" + "----------\n" + "4. ERROR in X.java (at line 11)\n" + " if (foo2 == null) {}\n" + " ^^^^\n" + "Redundant null check: The variable foo2 can only be null at this location\n" + "----------\n" + "5. ERROR in X.java (at line 13)\n" + " if (bar == null) {}\n" + " ^^^\n" + "Redundant null check: The variable bar can only be null at this location\n" + "----------\n" + "6. ERROR in X.java (at line 14)\n" + " org.eclipse.core.runtime.Assert.isLegal (bar2 != null);\n" + " ^^^^\n" + "Null comparison always yields false: The variable bar2 can only be null at this location\n" + "----------\n" + "7. ERROR in X.java (at line 15)\n" + " if (bar2 == null) {}\n" + " ^^^^\n" + "Null comparison always yields false: The variable bar2 cannot be null at this location\n" + "----------\n" + "8. WARNING in X.java (at line 15)\n" + " if (bar2 == null) {}\n" + " ^^\n" + "Dead code\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 // Test to verify that asserts are exempted from redundant null check warnings in a finally context, // but this doesn't affect the downstream info. public void testBug127575k() { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void m() {\n" + " X foo = new X();\n" + " X foo2 = new X();\n" + " X bar = null;\n" + " X bar2 = null;\n" + " try {\n" + " System.out.println(\"Inside try\");\n" + " }\n" + " finally {\n" + " org.eclipse.core.runtime.Assert.isLegal (foo != null);\n" + //don't warn " if (foo == null) {}\n" + " org.eclipse.core.runtime.Assert.isLegal (foo2 == null);\n" + //don't warn " if (foo2 == null) {}\n" + " org.eclipse.core.runtime.Assert.isLegal (bar == null);\n" + //don't warn " if (bar == null) {}\n" + " org.eclipse.core.runtime.Assert.isLegal (bar2 != null);\n" + //don't warn " if (bar2 == null) {}\n" + " }\n" + " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 12)\n" + " if (foo == null) {}\n" + " ^^^\n" + "Null comparison always yields false: The variable foo cannot be null at this location\n" + "----------\n" + "2. WARNING in X.java (at line 12)\n" + " if (foo == null) {}\n" + " ^^\n" + "Dead code\n" + "----------\n" + "3. ERROR in X.java (at line 13)\n" + " org.eclipse.core.runtime.Assert.isLegal (foo2 == null);\n" + " ^^^^\n" + "Null comparison always yields false: The variable foo2 cannot be null at this location\n" + "----------\n" + "4. ERROR in X.java (at line 14)\n" + " if (foo2 == null) {}\n" + " ^^^^\n" + "Redundant null check: The variable foo2 can only be null at this location\n" + "----------\n" + "5. ERROR in X.java (at line 16)\n" + " if (bar == null) {}\n" + " ^^^\n" + "Redundant null check: The variable bar can only be null at this location\n" + "----------\n" + "6. ERROR in X.java (at line 17)\n" + " org.eclipse.core.runtime.Assert.isLegal (bar2 != null);\n" + " ^^^^\n" + "Null comparison always yields false: The variable bar2 can only be null at this location\n" + "----------\n" + "7. ERROR in X.java (at line 18)\n" + " if (bar2 == null) {}\n" + " ^^^^\n" + "Null comparison always yields false: The variable bar2 cannot be null at this location\n" + "----------\n" + "8. WARNING in X.java (at line 18)\n" + " if (bar2 == null) {}\n" + " ^^\n" + "Dead code\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 // The condition of org.eclipse.core.runtime.Assert.isLegal is considered always true // and alters the following analysis suitably. public void testBug127575l() { this.runNegativeTest( new String[] { "Test.java", "public class Test {\n" + " void foo(Object a, Object b, Object c) {\n" + " org.eclipse.core.runtime.Assert.isLegal( 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" + " org.eclipse.core.runtime.Assert.isLegal(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" + " org.eclipse.core.runtime.Assert.isLegal(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. WARNING in Test.java (at line 4)\n" + " if (a!=null) {\n" + " System.out.println(\"a is not null\");\n" + " } else{\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Dead code\n" + "----------\n" + "3. ERROR in Test.java (at line 9)\n" + " a = null;\n" + " ^\n" + "Redundant assignment: The variable a can only be null at this location\n" + "----------\n" + "4. 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" + "5. ERROR in Test.java (at line 12)\n" + " if (b!=null) {\n" + " ^\n" + "Redundant null check: The variable b cannot be null at this location\n" + "----------\n" + "6. WARNING in Test.java (at line 14)\n" + " } else{\n" + " System.out.println(\"b is null\");\n" + " }\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Dead code\n" + "----------\n" + "7. ERROR in Test.java (at line 18)\n" + " if (c.equals(a)) {\n" + " ^\n" + "Null pointer access: The variable c can only be null at this location\n" + "----------\n", this.assertLib, true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 // NPE warnings should be given inside org.eclipse.core.runtime.Assert.isLegal too public void testBug127575m() { if (this.complianceLevel >= ClassFileConstants.JDK1_5) { this.runNegativeTest( new String[] { "Info.java", "public class Info {\n" + " public void test(Info[] infos) {\n" + " for (final Info info : infos) {\n " + " if (info != null) {\n" + " org.eclipse.core.runtime.Assert.isLegal( info.checkSomething());\n" + " info.doSomething();\n" + " }\n" + " }\n" + " for (final Info info : infos) {\n " + " if (info == null) {\n" + " org.eclipse.core.runtime.Assert.isLegal(info.checkSomething());\n" + // warn NPE " info.doSomething();\n" + " }\n" + " }\n" + " }\n" + " void doSomething() {}\n" + " boolean checkSomething() {return true;}\n" + "}\n"}, "----------\n" + "1. ERROR in Info.java (at line 11)\n" + " org.eclipse.core.runtime.Assert.isLegal(info.checkSomething());\n" + " ^^^^\n" + "Null pointer access: The variable info can only be null at this location\n" + "----------\n", this.assertLib, true); } } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 // always false comparison in Assert.isLegal in loop should be warned against public void testBug127575n() { if (this.complianceLevel >= ClassFileConstants.JDK1_5) { this.runNegativeTest( new String[] { "DoWhileBug.java", "public class DoWhileBug {\n" + " void test(boolean b1) {\n" + " Object o1 = null;\n" + " Object o2 = null;\n" + " do {\n" + " if (b1)\n" + " o1 = null;\n" + " org.eclipse.core.runtime.Assert.isLegal (o1 != null);\n" + " } while (true);\n" + " }\n" + "}" }, "----------\n" + "1. ERROR in DoWhileBug.java (at line 7)\n" + " o1 = null;\n" + " ^^\n" + "Redundant assignment: The variable o1 can only be null at this location\n" + "----------\n" + "2. ERROR in DoWhileBug.java (at line 8)\n" + " org.eclipse.core.runtime.Assert.isLegal (o1 != null);\n" + " ^^\n" + "Null comparison always yields false: The variable o1 can only be null at this location\n" + "----------\n", this.assertLib, true); } } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575 // "redundant null check" in Assert.isLegal in loop should not be warned against public void testBug127575o() { if (this.complianceLevel >= ClassFileConstants.JDK1_5) { this.runNegativeTest( new String[] { "DoWhileBug.java", "public class DoWhileBug {\n" + " void test(boolean b1) {\n" + " Object o1 = null;\n" + " Object o2 = null;\n" + " do {\n" + " if (b1)\n" + " o1 = null;\n" + " org.eclipse.core.runtime.Assert.isLegal ((o2 = o1) == null);\n" + " } while (true);\n" + " }\n" + "}" }, "----------\n" + "1. ERROR in DoWhileBug.java (at line 7)\n" + " o1 = null;\n" + " ^^\n" + "Redundant assignment: The variable o1 can only be null at this location\n" + "----------\n", this.assertLib, true); } } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=373953 public void testBug373953() throws IOException { this.runNegativeTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o) {\n" + " boolean b = o != null;\n" + // sheds doubts upon o " java.eclipse.core.runtime.Assert.isLegal(o != null);\n" + // bogus Assert " o.toString();\n" + // warn " }\n" + " void foo1(Object o) {\n" + " boolean b = o != null;\n" + // sheds doubts upon o " org.lang.core.runtime.Assert.isLegal(o != null);\n" + // bogus Assert " o.toString();\n" + // warn " }\n" + "}\n", "java.eclipse.core.runtime/Assert.java", "package java.eclipse.core.runtime;\n" + "public class Assert {\n" + " public static void isLegal(boolean b) {\n" + " }\n" + "}\n", "org.lang.core.runtime/Assert.java", "package org.lang.core.runtime;\n" + "public class Assert {\n" + " public static void isLegal(boolean b) {\n" + " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 5)\n" + " o.toString();\n" + " ^\n" + "Potential null pointer access: The variable o may be null at this location\n" + "----------\n" + "2. ERROR in X.java (at line 10)\n" + " o.toString();\n" + " ^\n" + "Potential null pointer access: The variable o may be null at this location\n" + "----------\n"); } // https://bugs.eclipse.org/382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions // junit's assertNotNull public void testBug382069a() throws IOException { this.runConformTest( new String[] { JUNIT_ASSERT_NAME, JUNIT_ASSERT_CONTENT, "X.java", "public class X {\n" + " void foo(Object o1, String o2) {\n" + " boolean b = o1 != null;\n" + // sheds doubts upon o1 " junit.framework.Assert.assertNotNull(o1);\n" + // protection " o1.toString();\n" + // quiet " b = o2 != null;\n" + // sheds doubts upon o2 " junit.framework.Assert.assertNotNull(\"msg\", o2);\n" + // protection " o2.toString();\n" + // quiet " }\n" + "}\n"}, ""); } // https://bugs.eclipse.org/382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions // org.eclipse.core.runtime.Assert.isNotNull public void testBug382069b() { if (this.complianceLevel >= ClassFileConstants.JDK1_5) { this.runConformTest( new String[] { "X.java", "public class X {\n" + " void foo(Object o1, String o2) {\n" + " boolean b = o1 != null;\n" + // sheds doubts upon o1 " org.eclipse.core.runtime.Assert.isNotNull(o1);\n" + // protection " o1.toString();\n" + // quiet " b = o2 != null;\n" + // sheds doubts upon o2 " org.eclipse.core.runtime.Assert.isNotNull(o2, \"msg\");\n" + // protection " o2.toString();\n" + // quiet " }\n" + "}" }, "", this.assertLib, true, null); } } // https://bugs.eclipse.org/382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions // junit's assertNull and dead code analysis public void testBug382069c() throws IOException { this.runNegativeTest( new String[] { JUNIT_ASSERT_NAME, JUNIT_ASSERT_CONTENT, "X.java", "public class X {\n" + " boolean foo(String o1, String o2) {\n" + " junit.framework.Assert.assertNull(\"something's wrong\", o1);\n" + // establish nullness " if (o2 == null)\n" + " return o1 != null;\n" + " junit.framework.Assert.assertNull(o2);\n" + // will always throw " return false; // dead code\n" + " }\n" + " void bar(X x) {\n" + " if (x == null) {\n" + " junit.framework.Assert.assertNotNull(x);\n" + " return; // dead code\n" + " }\n" + " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 5)\n" + " return o1 != null;\n" + " ^^\n" + "Null comparison always yields false: The variable o1 can only be null at this location\n" + "----------\n" + "2. WARNING in X.java (at line 7)\n" + " return false; // dead code\n" + " ^^^^^^^^^^^^^\n" + "Dead code\n" + "----------\n" + "3. WARNING in X.java (at line 12)\n" + " return; // dead code\n" + " ^^^^^^^\n" + "Dead code\n" + "----------\n"); } // https://bugs.eclipse.org/382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions // various asserts from org.apache.commons.lang.Validate public void testBug382069d() throws IOException { this.runNegativeTest( new String[] { APACHE_VALIDATE_NAME, APACHE_VALIDATE_CONTENT, "X.java", "import org.apache.commons.lang.Validate;\n" + "public class X {\n" + " void foo(Object o1, String o2, X x) {\n" + " boolean b = o1 != null;\n" + // sheds doubts upon o1 " Validate.notNull(o1);\n" + // protection " o1.toString();\n" + // quiet " b = o2 != null;\n" + // sheds doubts upon o2 " Validate.notNull(o2, \"msg\");\n" + // protection " o2.toString();\n" + // quiet " Validate.isTrue(x == null, \"ups\", x);\n" + " x.foo(null, null, null); // definite NPE\n" + " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 11)\n" + " x.foo(null, null, null); // definite NPE\n" + " ^\n" + "Null pointer access: The variable x can only be null at this location\n" + "----------\n"); } // https://bugs.eclipse.org/382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions // various asserts from org.apache.commons.lang3Validate public void testBug382069e() throws IOException { if (this.complianceLevel >= ClassFileConstants.JDK1_5) { this.runNegativeTest( new String[] { APACHE_3_VALIDATE_NAME, APACHE_3_VALIDATE_CONTENT, "X.java", "import org.apache.commons.lang3.Validate;\n" + "public class X {\n" + " void foo(Object o1, String o2, X x) {\n" + " boolean b = o1 != null;\n" + // sheds doubts upon o1 " Validate.notNull(o1);\n" + // protection " o1.toString();\n" + // quiet " b = o2 != null;\n" + // sheds doubts upon o2 " Validate.notNull(o2, \"msg\");\n" + // protection " o2.toString();\n" + // quiet " Validate.isTrue(x == null, \"ups\", x);\n" + " x.foo(null, null, null); // definite NPE\n" + " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 11)\n" + " x.foo(null, null, null); // definite NPE\n" + " ^\n" + "Null pointer access: The variable x can only be null at this location\n" + "----------\n"); } } // https://bugs.eclipse.org/382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions // various asserts from com.google.common.base.Preconditions public void testBug382069f() throws IOException { if (this.complianceLevel >= ClassFileConstants.JDK1_5) { this.runNegativeTest( new String[] { GOOGLE_PRECONDITIONS_NAME, GOOGLE_PRECONDITIONS_CONTENT, "X.java", "import com.google.common.base.Preconditions;\n" + "public class X {\n" + " void foo(Object o1, String o2, X x) {\n" + " boolean b = o1 != null;\n" + // sheds doubts upon o1 " Preconditions.checkNotNull(o1);\n" + // protection " o1.toString();\n" + // quiet " b = o2 != null;\n" + // sheds doubts upon o2 " Preconditions.checkNotNull(o2, \"msg {0}.{1}\", o1, o2);\n" + // protection " o2.toString();\n" + // quiet " Preconditions.checkArgument(x == null, \"ups\");\n" + " x.foo(null, null, null); // definite NPE\n" + " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 11)\n" + " x.foo(null, null, null); // definite NPE\n" + " ^\n" + "Null pointer access: The variable x can only be null at this location\n" + "----------\n"); } } // https://bugs.eclipse.org/382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions // java.util.Objects#requireNonNull public void testBug382069g() throws IOException { if (this.complianceLevel >= ClassFileConstants.JDK1_7) { this.runConformTest( new String[] { "X.java", "import static java.util.Objects.requireNonNull;\n" + "public class X {\n" + " void foo(Object o1, String o2, X x) {\n" + " boolean b = o1 != null;\n" + // sheds doubts upon o1 " requireNonNull(o1);\n" + // protection " o1.toString();\n" + // quiet " b = o2 != null;\n" + // sheds doubts upon o2 " requireNonNull(o2, \"msg\");\n" + // protection " o2.toString();\n" + // quiet " }\n" + "}\n"}, ""); } } // https://bugs.eclipse.org/382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions // junit's assertTrue / assertFalse public void testBug382069h() throws IOException { this.runConformTest( new String[] { JUNIT_ASSERT_NAME, JUNIT_ASSERT_CONTENT, "X.java", "public class X {\n" + " void foo(Object o1, String o2) {\n" + " boolean b = o1 != null;\n" + // sheds doubts upon o1 " junit.framework.Assert.assertTrue(o1 != null);\n" + // protection " o1.toString();\n" + // quiet " b = o2 != null;\n" + // sheds doubts upon o2 " junit.framework.Assert.assertFalse(\"msg\", o2 == null);\n" + // protection " o2.toString();\n" + // quiet " }\n" + "}\n"}, ""); } // Bug 401159 - [null] Respect org.junit.Assert for control flow // various asserts from org.junit.Assert public void testBug401159() throws IOException { this.runNegativeTest( new String[] { ORG_JUNIT_ASSERT_NAME, ORG_JUNIT_ASSERT_CONTENT, "X.java", "import org.junit.Assert;\n" + "public class X {\n" + " void foo(Object o1, String o2, X x) {\n" + " boolean b = o1 != null;\n" + // sheds doubts upon o1 " Assert.assertNotNull(o1);\n" + // protection " o1.toString();\n" + // quiet " b = o2 != null;\n" + // sheds doubts upon o2 " Assert.assertNotNull(\"msg\", o2);\n" + // protection " o2.toString();\n" + // quiet " Assert.assertTrue(\"ups\", x == null);\n" + " x.foo(null, null, null); // definite NPE\n" + " }\n" + "}\n"}, "----------\n" + "1. ERROR in X.java (at line 11)\n" + " x.foo(null, null, null); // definite NPE\n" + " ^\n" + "Null pointer access: The variable x can only be null at this location\n" + "----------\n"); } // https://bugs.eclipse.org/472618 - [compiler][null] assertNotNull vs. Assert.assertNotNull // junit's assertNotNull public void testBug472618() throws IOException { if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses auto-unboxing this.runConformTest( new String[] { JUNIT_ASSERT_NAME, JUNIT_ASSERT_CONTENT, "AssertionTest.java", "import junit.framework.Assert;\n" + "\n" + "public class AssertionTest extends Assert\n" + "{\n" + " void test()\n" + " {\n" + " Long test = null;\n" + "\n" + " if(Boolean.TRUE)\n" + " {\n" + " test = 0L;\n" + " }\n" + "\n" + " assertNotNull(test);\n" + "\n" + " test.longValue(); // <- potential null pointer access\n" + " }\n" + "}\n"}, ""); } }