# HG changeset patch # User emc # Date 1381955584 14400 # Node ID 7f6481e5fe3a3929c870b6ba320f1d814e70254d # Parent d7e155f874a79e363f71525dd624826009d7709b 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 diff -r d7e155f874a7 -r 7f6481e5fe3a src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java --- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Wed Oct 16 10:47:21 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Wed Oct 16 16:33:04 2013 -0400 @@ -97,7 +97,6 @@ final Symtab syms; final Annotate annotate; final Attr attr; - private final boolean typeAnnoAsserts; protected TypeAnnotations(Context context) { context.put(typeAnnosKey, this); @@ -107,7 +106,6 @@ annotate = Annotate.instance(context); attr = Attr.instance(context); Options options = Options.instance(context); - typeAnnoAsserts = options.isSet("TypeAnnotationAsserts"); } /** @@ -1042,11 +1040,7 @@ @Override public void visitMethodDef(final JCMethodDecl tree) { if (tree.sym == null) { - if (typeAnnoAsserts) { - Assert.error("Visiting tree node before memberEnter"); - } else { - return; - } + Assert.error("Visiting tree node before memberEnter"); } if (sigOnly) { if (!tree.mods.annotations.isEmpty()) { @@ -1150,10 +1144,7 @@ // Nothing to do for separateAnnotationsKinds if // there are no annotations of either kind. } else if (tree.sym == null) { - if (typeAnnoAsserts) { - Assert.error("Visiting tree node before memberEnter"); - } - // Something is wrong already. Quietly ignore. + Assert.error("Visiting tree node before memberEnter"); } else if (tree.sym.getKind() == ElementKind.PARAMETER) { // Parameters are handled in visitMethodDef or visitLambda. } else if (tree.sym.getKind() == ElementKind.FIELD) { diff -r d7e155f874a7 -r 7f6481e5fe3a src/share/classes/com/sun/tools/javac/comp/Annotate.java --- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Oct 16 10:47:21 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Oct 16 16:33:04 2013 -0400 @@ -129,6 +129,12 @@ flush(); } + /** Variant which allows for a delayed flush of annotations. + * Needed by ClassReader */ + public void enterDoneWithoutFlush() { + enterCount--; + } + public void flush() { if (enterCount != 0) return; enterCount++; diff -r d7e155f874a7 -r 7f6481e5fe3a src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Oct 16 10:47:21 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Oct 16 16:33:04 2013 -0400 @@ -2405,8 +2405,6 @@ return c; } - private boolean suppressFlush = false; - /** Completion for classes to be loaded. Before a class is loaded * we make sure its enclosing class (if any) is loaded. */ @@ -2414,13 +2412,14 @@ if (sym.kind == TYP) { ClassSymbol c = (ClassSymbol)sym; c.members_field = new Scope.ErrorScope(c); // make sure it's always defined - boolean saveSuppressFlush = suppressFlush; - suppressFlush = true; + annotate.enterStart(); try { completeOwners(c.owner); completeEnclosing(c); } finally { - suppressFlush = saveSuppressFlush; + // The flush needs to happen only after annotations + // are filled in. + annotate.enterDoneWithoutFlush(); } fillIn(c); } else if (sym.kind == PCK) { @@ -2431,7 +2430,7 @@ throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex); } } - if (!filling && !suppressFlush) + if (!filling) annotate.flush(); // finish attaching annotations } diff -r d7e155f874a7 -r 7f6481e5fe3a test/tools/javac/annotations/typeAnnotations/TestAnonInnerInstance1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/typeAnnotations/TestAnonInnerInstance1.java Wed Oct 16 16:33:04 2013 -0400 @@ -0,0 +1,57 @@ +/* + * 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 8026286 + * @summary This test previously forced an assertion to fail, due to + * TypeAnnotationPosition visiting a tree node prior to + * memberEnter. + * @compile TestAnonInnerInstance1.java + */ + +import java.lang.annotation.*; +import static java.lang.annotation.RetentionPolicy.*; +import static java.lang.annotation.ElementType.*; +import java.util.List; + +class TestAnonInnerInstance1 { + Object mtest(TestAnonInnerInstance1 t){ return null; } + Object mmtest(TestAnonInnerInstance1 t){ return null; } + + public void test() { + + mtest(new TestAnonInnerInstance1() { + class InnerAnon { // Test1$1$InnerAnon.class + @A @B @C @D String ia_m1(){ return null; }; + } + //If this is commented out, annotations are attributed correctly + InnerAnon IA = new InnerAnon< String>(); + }); + } +} + +@Retention(RUNTIME) @Target({TYPE_USE,FIELD}) @interface A { } +@Retention(RUNTIME) @Target({TYPE_USE,METHOD}) @interface B { } +@Retention(CLASS) @Target({TYPE_USE,FIELD}) @interface C { } +@Retention(CLASS) @Target({TYPE_USE,METHOD}) @interface D { } diff -r d7e155f874a7 -r 7f6481e5fe3a test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java --- a/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java Wed Oct 16 10:47:21 2013 -0700 +++ b/test/tools/javac/annotations/typeAnnotations/classfile/T8008762.java Wed Oct 16 16:33:04 2013 -0400 @@ -24,7 +24,6 @@ /* * @test * @bug 8008762 - * @ignore 8013409: test failures for type annotations * @summary Type annotation on inner class in anonymous class * shows up as regular annotation */