changeset 3562:47a91ecb0b87 jdk8u172-b01

8191969: javac produces incorrect RuntimeInvisibleTypeAnnotations length attribute Reviewed-by: jlahoda, vromero
author sadayapalam
date Mon, 04 Dec 2017 10:33:18 -0500
parents 03ff1eee9fe8
children 989188d1a978 74e32084dce9
files src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java test/tools/javac/annotations/typeAnnotations/classfile/TypeAnnotationPropagationTest.java
diffstat 2 files changed, 113 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Oct 24 13:16:58 2017 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Dec 04 10:33:18 2017 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -2009,7 +2009,7 @@
                         Assert.error(skind.name());
                         throw new AssertionError();
                 }
-                if (ret != sym) {
+                if (ret != sym && skind.propagateAnnotations()) {
                     ret.setDeclarationAttributes(sym.getRawAttributes());
                     ret.setTypeAttributes(sym.getRawTypeAttributes());
                 }
@@ -2045,7 +2045,6 @@
                             if (m.containsKey(lambdaIdent.sym)) {
                                 Symbol tSym = m.get(lambdaIdent.sym);
                                 JCTree t = make.Ident(tSym).setType(lambdaIdent.type);
-                                tSym.setTypeAttributes(lambdaIdent.sym.getRawTypeAttributes());
                                 return t;
                             }
                             break;
@@ -2054,7 +2053,6 @@
                                 // Transform outer instance variable references anchoring them to the captured synthetic.
                                 Symbol tSym = m.get(lambdaIdent.sym.owner);
                                 JCExpression t = make.Ident(tSym).setType(lambdaIdent.sym.owner.type);
-                                tSym.setTypeAttributes(lambdaIdent.sym.owner.getRawTypeAttributes());
                                 t = make.Select(t, lambdaIdent.name);
                                 t.setType(lambdaIdent.type);
                                 TreeInfo.setSymbol(t, lambdaIdent.sym);
@@ -2075,7 +2073,6 @@
                 if (m.containsKey(fieldAccess.sym.owner)) {
                     Symbol tSym = m.get(fieldAccess.sym.owner);
                     JCExpression t = make.Ident(tSym).setType(fieldAccess.sym.owner.type);
-                    tSym.setTypeAttributes(fieldAccess.sym.owner.getRawTypeAttributes());
                     return t;
                 }
                 return null;
@@ -2272,6 +2269,17 @@
         CAPTURED_THIS,  // class symbols to translated synthetic parameters (for captured member access)
         CAPTURED_OUTER_THIS, // used when `this' capture is illegal, but outer this capture is legit (JDK-8129740)
         TYPE_VAR;       // original to translated lambda type variables
+
+        boolean propagateAnnotations() {
+            switch (this) {
+                case CAPTURED_VAR:
+                case CAPTURED_THIS:
+                case CAPTURED_OUTER_THIS:
+                    return false;
+                default:
+                    return true;
+           }
+        }
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/classfile/TypeAnnotationPropagationTest.java	Mon Dec 04 10:33:18 2017 -0500
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017, Google Inc. 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 8144185 8191969
+ * @summary javac produces incorrect RuntimeInvisibleTypeAnnotations length attribute
+ */
+
+import static java.lang.annotation.ElementType.TYPE_USE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
+import com.sun.tools.classfile.TypeAnnotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.Arrays;
+import java.util.Objects;
+
+public class TypeAnnotationPropagationTest extends ClassfileTestHelper {
+    public static void main(String[] args) throws Exception {
+        new TypeAnnotationPropagationTest().run();
+    }
+
+    public void run() throws Exception {
+        ClassFile cf = getClassFile("TypeAnnotationPropagationTest$Test.class");
+
+        Method f = null;
+        for (Method m : cf.methods) {
+            if (m.getName(cf.constant_pool).contains("f")) {
+                f = m;
+                break;
+            }
+        }
+
+        int idx = f.attributes.getIndex(cf.constant_pool, Attribute.Code);
+        Code_attribute cattr = (Code_attribute) f.attributes.get(idx);
+        idx = cattr.attributes.getIndex(cf.constant_pool, Attribute.RuntimeVisibleTypeAnnotations);
+        RuntimeVisibleTypeAnnotations_attribute attr =
+                (RuntimeVisibleTypeAnnotations_attribute) cattr.attributes.get(idx);
+
+        TypeAnnotation anno = attr.annotations[0];
+        assertEquals(anno.position.lvarOffset, new int[] {3}, "start_pc");
+        assertEquals(anno.position.lvarLength, new int[] {8}, "length");
+        assertEquals(anno.position.lvarIndex, new int[] {1}, "index");
+    }
+
+    void assertEquals(int[] actual, int[] expected, String message) {
+        if (!Arrays.equals(actual, expected)) {
+            throw new AssertionError(
+                    String.format(
+                            "actual: %s, expected: %s, %s",
+                            Arrays.toString(actual), Arrays.toString(expected), message));
+        }
+    }
+
+    /** ********************* Test class ************************ */
+    static class Test {
+        void f() {
+            @A String s = "";
+            Runnable r =
+                    () -> {
+                        Objects.requireNonNull(s);
+                        Objects.requireNonNull(s);
+                        Objects.requireNonNull(s);
+                        Objects.requireNonNull(s);
+                        Objects.requireNonNull(s);
+                        Objects.requireNonNull(s);
+                    };
+        }
+
+        @Retention(RUNTIME)
+        @Target(TYPE_USE)
+        @interface A {}
+    }
+}