Mon, 04 Dec 2017 10:33:18 -0500
8191969: javac produces incorrect RuntimeInvisibleTypeAnnotations length attribute
Reviewed-by: jlahoda, vromero
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Oct 24 13:16:58 2017 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Dec 04 10:33:18 2017 -0500 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -2009,7 +2009,7 @@ 1.11 Assert.error(skind.name()); 1.12 throw new AssertionError(); 1.13 } 1.14 - if (ret != sym) { 1.15 + if (ret != sym && skind.propagateAnnotations()) { 1.16 ret.setDeclarationAttributes(sym.getRawAttributes()); 1.17 ret.setTypeAttributes(sym.getRawTypeAttributes()); 1.18 } 1.19 @@ -2045,7 +2045,6 @@ 1.20 if (m.containsKey(lambdaIdent.sym)) { 1.21 Symbol tSym = m.get(lambdaIdent.sym); 1.22 JCTree t = make.Ident(tSym).setType(lambdaIdent.type); 1.23 - tSym.setTypeAttributes(lambdaIdent.sym.getRawTypeAttributes()); 1.24 return t; 1.25 } 1.26 break; 1.27 @@ -2054,7 +2053,6 @@ 1.28 // Transform outer instance variable references anchoring them to the captured synthetic. 1.29 Symbol tSym = m.get(lambdaIdent.sym.owner); 1.30 JCExpression t = make.Ident(tSym).setType(lambdaIdent.sym.owner.type); 1.31 - tSym.setTypeAttributes(lambdaIdent.sym.owner.getRawTypeAttributes()); 1.32 t = make.Select(t, lambdaIdent.name); 1.33 t.setType(lambdaIdent.type); 1.34 TreeInfo.setSymbol(t, lambdaIdent.sym); 1.35 @@ -2075,7 +2073,6 @@ 1.36 if (m.containsKey(fieldAccess.sym.owner)) { 1.37 Symbol tSym = m.get(fieldAccess.sym.owner); 1.38 JCExpression t = make.Ident(tSym).setType(fieldAccess.sym.owner.type); 1.39 - tSym.setTypeAttributes(fieldAccess.sym.owner.getRawTypeAttributes()); 1.40 return t; 1.41 } 1.42 return null; 1.43 @@ -2272,6 +2269,17 @@ 1.44 CAPTURED_THIS, // class symbols to translated synthetic parameters (for captured member access) 1.45 CAPTURED_OUTER_THIS, // used when `this' capture is illegal, but outer this capture is legit (JDK-8129740) 1.46 TYPE_VAR; // original to translated lambda type variables 1.47 + 1.48 + boolean propagateAnnotations() { 1.49 + switch (this) { 1.50 + case CAPTURED_VAR: 1.51 + case CAPTURED_THIS: 1.52 + case CAPTURED_OUTER_THIS: 1.53 + return false; 1.54 + default: 1.55 + return true; 1.56 + } 1.57 + } 1.58 } 1.59 1.60 /**
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/annotations/typeAnnotations/classfile/TypeAnnotationPropagationTest.java Mon Dec 04 10:33:18 2017 -0500 2.3 @@ -0,0 +1,100 @@ 2.4 +/* 2.5 + * Copyright (c) 2017, Google Inc. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/* 2.28 + * @test 2.29 + * @bug 8144185 8191969 2.30 + * @summary javac produces incorrect RuntimeInvisibleTypeAnnotations length attribute 2.31 + */ 2.32 + 2.33 +import static java.lang.annotation.ElementType.TYPE_USE; 2.34 +import static java.lang.annotation.RetentionPolicy.RUNTIME; 2.35 + 2.36 +import com.sun.tools.classfile.Attribute; 2.37 +import com.sun.tools.classfile.ClassFile; 2.38 +import com.sun.tools.classfile.Code_attribute; 2.39 +import com.sun.tools.classfile.Method; 2.40 +import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; 2.41 +import com.sun.tools.classfile.TypeAnnotation; 2.42 +import java.lang.annotation.Retention; 2.43 +import java.lang.annotation.Target; 2.44 +import java.util.Arrays; 2.45 +import java.util.Objects; 2.46 + 2.47 +public class TypeAnnotationPropagationTest extends ClassfileTestHelper { 2.48 + public static void main(String[] args) throws Exception { 2.49 + new TypeAnnotationPropagationTest().run(); 2.50 + } 2.51 + 2.52 + public void run() throws Exception { 2.53 + ClassFile cf = getClassFile("TypeAnnotationPropagationTest$Test.class"); 2.54 + 2.55 + Method f = null; 2.56 + for (Method m : cf.methods) { 2.57 + if (m.getName(cf.constant_pool).contains("f")) { 2.58 + f = m; 2.59 + break; 2.60 + } 2.61 + } 2.62 + 2.63 + int idx = f.attributes.getIndex(cf.constant_pool, Attribute.Code); 2.64 + Code_attribute cattr = (Code_attribute) f.attributes.get(idx); 2.65 + idx = cattr.attributes.getIndex(cf.constant_pool, Attribute.RuntimeVisibleTypeAnnotations); 2.66 + RuntimeVisibleTypeAnnotations_attribute attr = 2.67 + (RuntimeVisibleTypeAnnotations_attribute) cattr.attributes.get(idx); 2.68 + 2.69 + TypeAnnotation anno = attr.annotations[0]; 2.70 + assertEquals(anno.position.lvarOffset, new int[] {3}, "start_pc"); 2.71 + assertEquals(anno.position.lvarLength, new int[] {8}, "length"); 2.72 + assertEquals(anno.position.lvarIndex, new int[] {1}, "index"); 2.73 + } 2.74 + 2.75 + void assertEquals(int[] actual, int[] expected, String message) { 2.76 + if (!Arrays.equals(actual, expected)) { 2.77 + throw new AssertionError( 2.78 + String.format( 2.79 + "actual: %s, expected: %s, %s", 2.80 + Arrays.toString(actual), Arrays.toString(expected), message)); 2.81 + } 2.82 + } 2.83 + 2.84 + /** ********************* Test class ************************ */ 2.85 + static class Test { 2.86 + void f() { 2.87 + @A String s = ""; 2.88 + Runnable r = 2.89 + () -> { 2.90 + Objects.requireNonNull(s); 2.91 + Objects.requireNonNull(s); 2.92 + Objects.requireNonNull(s); 2.93 + Objects.requireNonNull(s); 2.94 + Objects.requireNonNull(s); 2.95 + Objects.requireNonNull(s); 2.96 + }; 2.97 + } 2.98 + 2.99 + @Retention(RUNTIME) 2.100 + @Target(TYPE_USE) 2.101 + @interface A {} 2.102 + } 2.103 +}