8026286: Improper locking of annotation queues causes assertion failures
8026063: Calls to annotate.flush() cause incorrect type annotations to be generated Fix locking in ClassReader.java Reviewed-by: jfranck
This commit is contained in:
parent
ef68cc1fc1
commit
b8aff04aa0
@ -97,7 +97,6 @@ public class TypeAnnotations {
|
||||
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 @@ public class TypeAnnotations {
|
||||
annotate = Annotate.instance(context);
|
||||
attr = Attr.instance(context);
|
||||
Options options = Options.instance(context);
|
||||
typeAnnoAsserts = options.isSet("TypeAnnotationAsserts");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1042,11 +1040,7 @@ public class TypeAnnotations {
|
||||
@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 @@ public class TypeAnnotations {
|
||||
// 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) {
|
||||
|
@ -129,6 +129,12 @@ public class Annotate {
|
||||
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++;
|
||||
|
@ -2405,8 +2405,6 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex);
|
||||
}
|
||||
}
|
||||
if (!filling && !suppressFlush)
|
||||
if (!filling)
|
||||
annotate.flush(); // finish attaching annotations
|
||||
}
|
||||
|
||||
|
@ -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<T> {
|
||||
Object mtest(TestAnonInnerInstance1<T> t){ return null; }
|
||||
Object mmtest(TestAnonInnerInstance1<T> t){ return null; }
|
||||
|
||||
public void test() {
|
||||
|
||||
mtest(new TestAnonInnerInstance1<T>() {
|
||||
class InnerAnon<U> { // Test1$1$InnerAnon.class
|
||||
@A @B @C @D String ia_m1(){ return null; };
|
||||
}
|
||||
//If this is commented out, annotations are attributed correctly
|
||||
InnerAnon<String> 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 { }
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user