8028699: Compiler crash during speculative attribution of annotated type
authorjlahoda
Tue, 03 Dec 2013 18:50:26 +0100
changeset 22003 ed437c411fbd
parent 21897 ba025087b9f9
child 22004 203318f0799d
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
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
langtools/test/tools/javac/annotations/typeAnnotations/failures/CheckForDeclAnnoNPE.java
langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.java
langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out
--- 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