diff options
| author | Stephan Herrmann | 2014-07-22 11:16:44 +0000 |
|---|---|---|
| committer | Stephan Herrmann | 2014-07-22 14:28:04 +0000 |
| commit | b62a0575eabeb814900afcc3426a14b0da5fd6ad (patch) | |
| tree | 18917586d7565962b4ed132bf54df0945f814751 | |
| parent | 61133b8c5e6da454f7cea747a5c83744e4b067c9 (diff) | |
| download | eclipse.jdt.core-b62a0575eabeb814900afcc3426a14b0da5fd6ad.tar.gz eclipse.jdt.core-b62a0575eabeb814900afcc3426a14b0da5fd6ad.tar.xz eclipse.jdt.core-b62a0575eabeb814900afcc3426a14b0da5fd6ad.zip | |
Bug 434602 - Possible error with inferred null annotations leading to
contradictory null annotations
- incl. fix of TVB.declaringElement if cloned during initialization
5 files changed, 110 insertions, 4 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java index 840a577fb4..7c31a77079 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java @@ -5667,6 +5667,91 @@ public void testTypeVariable15a() { "Illegal redefinition of parameter arg, inherited method from ITest declares this parameter as \'List<T>\' (mismatching null constraints)\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=434602 +// Possible error with inferred null annotations leading to contradictory null annotations +public void testTypeVariable16() { + runNegativeTestWithLibs( + new String[] { + "X.java", + "import org.eclipse.jdt.annotation.NonNullByDefault;\n" + + "import org.eclipse.jdt.annotation.Nullable;\n" + + "\n" + + "class Y { void doit() {} }\n" + + "@NonNullByDefault\n" + + "class X {\n" + + " void foo() {\n" + + " X x = new X();\n" + + " Y y = x.bar(); // Error: Contradictory null annotations before the fix\n" + + " y.doit(); // check that @Nullable from bar's declaration has effect on 'y'\n" + + " }\n" + + "\n" + + " public <T extends Y> @Nullable T bar() {\n" + + " return null;\n" + + " }\n" + + "}\n" + }, + getCompilerOptions(), + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " y.doit(); // check that @Nullable from bar's declaration has effect on 'y'\n" + + " ^\n" + + "Potential null pointer access: The variable y may be null at this location\n" + + "----------\n"); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=434602 +// Possible error with inferred null annotations leading to contradictory null annotations +// Method part of parameterized class. +public void testTypeVariable16a() { + runConformTestWithLibs( + new String[] { + "X.java", + "import org.eclipse.jdt.annotation.NonNullByDefault;\n" + + "import org.eclipse.jdt.annotation.Nullable;\n" + + "\n" + + "class Y {}\n" + + "@NonNullByDefault\n" + + "public class X <T> {\n" + + " void foo() {\n" + + " X<Y> x = new X<Y>();\n" + + " x.bar(); // Error: Contradictory null annotations before the fix\n" + + " }\n" + + "\n" + + " public @Nullable T bar() {\n" + + " return null;\n" + + " }\n" + + "}\n" + }, + getCompilerOptions(), + ""); +} +public void testTypeVariable16b() { + runNegativeTestWithLibs( + new String[] { + "X.java", + "import org.eclipse.jdt.annotation.Nullable;\n" + + "import org.eclipse.jdt.annotation.NonNull;\n" + + "\n" + + "class Y {}\n" + + "class Y2 extends Y {}\n" + + "\n" + + "class X {\n" + + " void foo() {\n" + + " X x = new X();\n" + + " x.bar(null); // null arg is illegal\n" + + " }\n" + + " public <T extends @NonNull Y> @Nullable T bar(T t) {\n" + + " return null; // OK\n" + + " }\n" + + "}\n" + }, + getCompilerOptions(), + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " x.bar(null); // null arg is illegal\n" + + " ^^^^\n" + + "Null type mismatch: required \'@NonNull Y\' but the provided value is null\n" + + "----------\n"); +} public void testBug434600() { runConformTestWithLibs( new String[] { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java index b6ed2c8c94..baf0271e07 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java @@ -28,6 +28,7 @@ * Bug 390889 - [1.8][compiler] Evaluate options to support 1.7- projects against 1.8 JRE. * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables * Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type + * Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations * Jesper Steen Moller - Contributions for * Bug 412150 [1.8] [compiler] Enable reflected parameter names during annotation processing * Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable @@ -767,9 +768,9 @@ private MethodBinding createMethod(IBinaryMethod method, long sourceLevel, char[ if (use15specifics) result.tagBits |= method.getTagBits(); result.typeVariables = typeVars; - // fixup the declaring element of the type variable + // fixup the declaring element of all type variables for (int i = 0, length = typeVars.length; i < length; i++) - typeVars[i].declaringElement = result; + this.environment.typeSystem.fixTypeVariableDeclaringElement(typeVars[i], result); return result; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java index 5fe450c9c5..8144e21b9f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java @@ -26,6 +26,7 @@ * Bug 424624 - [1.8][null] if a static-object with annotation @NonNull is used, a warning is shown * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables * Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type + * Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -62,7 +63,7 @@ public class LookupEnvironment implements ProblemReasons, TypeConstants { private int lastCompletedUnitIndex = -1; private int lastUnitIndex = -1; - private TypeSystem typeSystem; + TypeSystem typeSystem; public INameEnvironment nameEnvironment; public CompilerOptions globalOptions; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java index fb5cbb3259..26019083de 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java @@ -19,6 +19,7 @@ * Bug 418743 - [1.8][null] contradictory annotations on invocation of generic method not reported * Bug 416182 - [1.8][compiler][null] Contradictory null annotations not rejected * Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault + * Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -739,7 +740,7 @@ public class ParameterizedGenericMethodBinding extends ParameterizedMethodBindin // check this variable can be substituted given parameterized type if (originalVariable.rank < length && TypeBinding.equalsEquals(variables[originalVariable.rank], originalVariable)) { TypeBinding substitute = this.typeArguments[originalVariable.rank]; - return originalVariable.hasTypeAnnotations() ? this.environment.createAnnotatedType(substitute, originalVariable.getTypeAnnotations()) : substitute; + return originalVariable.combineTypeAnnotations(substitute); } return originalVariable; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java index f2316883a1..de1b4c20ad 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java @@ -7,6 +7,8 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Stephan Herrmann - Contribution for + * Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -376,4 +378,20 @@ public class TypeSystem { } return cacheDerivedType(keyType, new IntersectionCastTypeBinding(intersectingTypes, this.environment)); } + + /** + * If a TVB was created with a dummy declaring element and needs to be fixed now, + * make sure that this update affects all early clones, too. + */ + public void fixTypeVariableDeclaringElement(TypeVariableBinding var, Binding declaringElement) { + int id = var.id; + if (id < this.typeid && this.types[id] != null) { + for (TypeBinding t : this.types[id]) { + if (t instanceof TypeVariableBinding) + ((TypeVariableBinding)t).declaringElement = declaringElement; + } + } else { + var.declaringElement = declaringElement; + } + } }
\ No newline at end of file |
