Wed, 16 Oct 2013 16:33:04 -0400
8026286: Improper locking of annotation queues causes assertion failures.
8026063: Calls to annotate.flush() cause incorrect type annotations to be generated.
Summary: Fix locking in ClassReader.java
Reviewed-by: jfranck
1.1 --- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Wed Oct 16 10:47:21 2013 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Wed Oct 16 16:33:04 2013 -0400 1.3 @@ -97,7 +97,6 @@ 1.4 final Symtab syms; 1.5 final Annotate annotate; 1.6 final Attr attr; 1.7 - private final boolean typeAnnoAsserts; 1.8 1.9 protected TypeAnnotations(Context context) { 1.10 context.put(typeAnnosKey, this); 1.11 @@ -107,7 +106,6 @@ 1.12 annotate = Annotate.instance(context); 1.13 attr = Attr.instance(context); 1.14 Options options = Options.instance(context); 1.15 - typeAnnoAsserts = options.isSet("TypeAnnotationAsserts"); 1.16 } 1.17 1.18 /** 1.19 @@ -1042,11 +1040,7 @@ 1.20 @Override 1.21 public void visitMethodDef(final JCMethodDecl tree) { 1.22 if (tree.sym == null) { 1.23 - if (typeAnnoAsserts) { 1.24 - Assert.error("Visiting tree node before memberEnter"); 1.25 - } else { 1.26 - return; 1.27 - } 1.28 + Assert.error("Visiting tree node before memberEnter"); 1.29 } 1.30 if (sigOnly) { 1.31 if (!tree.mods.annotations.isEmpty()) { 1.32 @@ -1150,10 +1144,7 @@ 1.33 // Nothing to do for separateAnnotationsKinds if 1.34 // there are no annotations of either kind. 1.35 } else if (tree.sym == null) { 1.36 - if (typeAnnoAsserts) { 1.37 - Assert.error("Visiting tree node before memberEnter"); 1.38 - } 1.39 - // Something is wrong already. Quietly ignore. 1.40 + Assert.error("Visiting tree node before memberEnter"); 1.41 } else if (tree.sym.getKind() == ElementKind.PARAMETER) { 1.42 // Parameters are handled in visitMethodDef or visitLambda. 1.43 } else if (tree.sym.getKind() == ElementKind.FIELD) {
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Oct 16 10:47:21 2013 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Oct 16 16:33:04 2013 -0400 2.3 @@ -129,6 +129,12 @@ 2.4 flush(); 2.5 } 2.6 2.7 + /** Variant which allows for a delayed flush of annotations. 2.8 + * Needed by ClassReader */ 2.9 + public void enterDoneWithoutFlush() { 2.10 + enterCount--; 2.11 + } 2.12 + 2.13 public void flush() { 2.14 if (enterCount != 0) return; 2.15 enterCount++;
3.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Oct 16 10:47:21 2013 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Oct 16 16:33:04 2013 -0400 3.3 @@ -2405,8 +2405,6 @@ 3.4 return c; 3.5 } 3.6 3.7 - private boolean suppressFlush = false; 3.8 - 3.9 /** Completion for classes to be loaded. Before a class is loaded 3.10 * we make sure its enclosing class (if any) is loaded. 3.11 */ 3.12 @@ -2414,13 +2412,14 @@ 3.13 if (sym.kind == TYP) { 3.14 ClassSymbol c = (ClassSymbol)sym; 3.15 c.members_field = new Scope.ErrorScope(c); // make sure it's always defined 3.16 - boolean saveSuppressFlush = suppressFlush; 3.17 - suppressFlush = true; 3.18 + annotate.enterStart(); 3.19 try { 3.20 completeOwners(c.owner); 3.21 completeEnclosing(c); 3.22 } finally { 3.23 - suppressFlush = saveSuppressFlush; 3.24 + // The flush needs to happen only after annotations 3.25 + // are filled in. 3.26 + annotate.enterDoneWithoutFlush(); 3.27 } 3.28 fillIn(c); 3.29 } else if (sym.kind == PCK) { 3.30 @@ -2431,7 +2430,7 @@ 3.31 throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex); 3.32 } 3.33 } 3.34 - if (!filling && !suppressFlush) 3.35 + if (!filling) 3.36 annotate.flush(); // finish attaching annotations 3.37 } 3.38
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/annotations/typeAnnotations/TestAnonInnerInstance1.java Wed Oct 16 16:33:04 2013 -0400 4.3 @@ -0,0 +1,57 @@ 4.4 +/* 4.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +/* 4.28 + * @test 4.29 + * @bug 8026286 4.30 + * @summary This test previously forced an assertion to fail, due to 4.31 + * TypeAnnotationPosition visiting a tree node prior to 4.32 + * memberEnter. 4.33 + * @compile TestAnonInnerInstance1.java 4.34 + */ 4.35 + 4.36 +import java.lang.annotation.*; 4.37 +import static java.lang.annotation.RetentionPolicy.*; 4.38 +import static java.lang.annotation.ElementType.*; 4.39 +import java.util.List; 4.40 + 4.41 +class TestAnonInnerInstance1<T> { 4.42 + Object mtest(TestAnonInnerInstance1<T> t){ return null; } 4.43 + Object mmtest(TestAnonInnerInstance1<T> t){ return null; } 4.44 + 4.45 + public void test() { 4.46 + 4.47 + mtest(new TestAnonInnerInstance1<T>() { 4.48 + class InnerAnon<U> { // Test1$1$InnerAnon.class 4.49 + @A @B @C @D String ia_m1(){ return null; }; 4.50 + } 4.51 + //If this is commented out, annotations are attributed correctly 4.52 + InnerAnon<String> IA = new InnerAnon< String>(); 4.53 + }); 4.54 + } 4.55 +} 4.56 + 4.57 +@Retention(RUNTIME) @Target({TYPE_USE,FIELD}) @interface A { } 4.58 +@Retention(RUNTIME) @Target({TYPE_USE,METHOD}) @interface B { } 4.59 +@Retention(CLASS) @Target({TYPE_USE,FIELD}) @interface C { } 4.60 +@Retention(CLASS) @Target({TYPE_USE,METHOD}) @interface D { }
5.1 --- a/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java Wed Oct 16 10:47:21 2013 -0700 5.2 +++ b/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java Wed Oct 16 16:33:04 2013 -0400 5.3 @@ -24,7 +24,6 @@ 5.4 /* 5.5 * @test 5.6 * @bug 8008762 5.7 - * @ignore 8013409: test failures for type annotations 5.8 * @summary Type annotation on inner class in anonymous class 5.9 * shows up as regular annotation 5.10 */