8028699: Compiler crash during speculative attribution of annotated type
Summary: Moving the checkForDeclarationAnnotations check into Attr.TypeAnnotationsValidator
Reviewed-by: jjg
Contributed-by: wdietl@gmail.com
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Nov 26 15:33:12 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Dec 03 18:50:26 2013 +0100
@@ -28,7 +28,6 @@
import java.util.*;
import javax.lang.model.element.ElementKind;
-import javax.lang.model.type.TypeKind;
import javax.tools.JavaFileObject;
import com.sun.source.tree.IdentifierTree;
@@ -2164,11 +2163,6 @@
tree.constructor,
localEnv,
new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
- } else {
- if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
- checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
- tree.clazz.type.tsym);
- }
}
if (tree.constructor != null && tree.constructor.kind == MTH)
@@ -2230,21 +2224,6 @@
}
}
- private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations,
- Symbol sym) {
- // Ensure that no declaration annotations are present.
- // Note that a tree type might be an AnnotatedType with
- // empty annotations, if only declaration annotations were given.
- // This method will raise an error for such a type.
- for (JCAnnotation ai : annotations) {
- if (!ai.type.isErroneous() &&
- typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
- log.error(ai.pos(), "annotation.type.not.applicable");
- }
- }
- }
-
-
/** Make an attributed null check tree.
*/
public JCExpression makeNullCheck(JCExpression arg) {
@@ -2271,10 +2250,6 @@
attribExpr(l.head, localEnv, syms.intType);
owntype = new ArrayType(owntype, syms.arrayClass);
}
- if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
- checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,
- tree.elemtype.type.tsym);
- }
} else {
// we are seeing an untyped aggregate { ... }
// this is allowed only if the prototype is an array
@@ -4419,7 +4394,7 @@
}
public void visitMethodDef(JCMethodDecl tree) {
if (tree.recvparam != null &&
- tree.recvparam.vartype.type.getKind() != TypeKind.ERROR) {
+ !tree.recvparam.vartype.type.isErroneous()) {
checkForDeclarationAnnotations(tree.recvparam.mods.annotations,
tree.recvparam.vartype.type.tsym);
}
@@ -4458,17 +4433,28 @@
super.visitTypeTest(tree);
}
public void visitNewClass(JCNewClass tree) {
- if (tree.clazz.type != null)
+ if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+ checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
+ tree.clazz.type.tsym);
+ }
+ if (tree.def != null) {
+ checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
+ }
+ if (tree.clazz.type != null) {
validateAnnotatedType(tree.clazz, tree.clazz.type);
+ }
super.visitNewClass(tree);
}
public void visitNewArray(JCNewArray tree) {
- if (tree.elemtype != null && tree.elemtype.type != null)
+ if (tree.elemtype != null && tree.elemtype.type != null) {
+ if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+ checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,
+ tree.elemtype.type.tsym);
+ }
validateAnnotatedType(tree.elemtype, tree.elemtype.type);
+ }
super.visitNewArray(tree);
}
-
- @Override
public void visitClassDef(JCClassDecl tree) {
if (sigOnly) {
scan(tree.mods);
@@ -4483,8 +4469,6 @@
scan(member);
}
}
-
- @Override
public void visitBlock(JCBlock tree) {
if (!sigOnly) {
scan(tree.stats);
@@ -4590,6 +4574,20 @@
}
}
}
+
+ private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations,
+ Symbol sym) {
+ // Ensure that no declaration annotations are present.
+ // Note that a tree type might be an AnnotatedType with
+ // empty annotations, if only declaration annotations were given.
+ // This method will raise an error for such a type.
+ for (JCAnnotation ai : annotations) {
+ if (!ai.type.isErroneous() &&
+ typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
+ log.error(ai.pos(), "annotation.type.not.applicable");
+ }
+ }
+ }
};
// <editor-fold desc="post-attribution visitor">
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Nov 26 15:33:12 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Dec 03 18:50:26 2013 +0100
@@ -2985,6 +2985,7 @@
boolean annotationApplicable(JCAnnotation a, Symbol s) {
Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
Name[] targets;
+
if (arr == null) {
targets = defaultTargetMetaInfo(a, s);
} else {
@@ -3001,7 +3002,7 @@
}
for (Name target : targets) {
if (target == names.TYPE)
- { if (s.kind == TYP && !s.isAnonymous()) return true; }
+ { if (s.kind == TYP) return true; }
else if (target == names.FIELD)
{ if (s.kind == VAR && s.owner.kind != MTH) return true; }
else if (target == names.METHOD)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CheckForDeclAnnoNPE.java Tue Dec 03 18:50:26 2013 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8028699
+ * @summary Ensure there is no NPE in checking for decl. annotations in this example
+ * @author Werner Dietl
+ * @compile -doe CheckForDeclAnnoNPE.java
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+class CheckForDeclAnnoNPE {
+ void test(String s) {
+ test(new @TA String().toString());
+ }
+}
+
+@Target(ElementType.TYPE_USE)
+@interface TA {}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.java Tue Nov 26 15:33:12 2013 +0100
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.java Tue Dec 03 18:50:26 2013 +0100
@@ -10,9 +10,6 @@
Object e1 = new @DA int[5];
Object e2 = new @DA String[42];
Object e3 = new @DA Object();
-
- // The declaration annotation is only allowed for
- // an anonymous class creation.
Object ok = new @DA Object() { };
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out Tue Nov 26 15:33:12 2013 +0100
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out Tue Dec 03 18:50:26 2013 +0100
@@ -1,5 +1,5 @@
DeclarationAnnotation.java:10:21: compiler.err.annotation.type.not.applicable
DeclarationAnnotation.java:11:21: compiler.err.annotation.type.not.applicable
DeclarationAnnotation.java:12:21: compiler.err.annotation.type.not.applicable
-DeclarationAnnotation.java:16:21: compiler.err.annotation.type.not.applicable
+DeclarationAnnotation.java:13:21: compiler.err.annotation.type.not.applicable
4 errors