Tue, 13 Jan 2009 13:28:42 +0000
6723444: javac fails to substitute type variables into a constructor's throws clause
Summary: Added constructor's actual type info to NewClass AST node
Reviewed-by: jjg
Contributed-by: mark@twistedbanana.demon.co.uk
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Jan 13 13:28:20 2009 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Jan 13 13:28:42 2009 +0000 1.3 @@ -1457,7 +1457,7 @@ 1.4 localEnv.info.varArgs = false; 1.5 tree.constructor = rs.resolveConstructor( 1.6 tree.pos(), localEnv, clazztype, argtypes, typeargtypes); 1.7 - Type ctorType = checkMethod(clazztype, 1.8 + tree.constructorType = checkMethod(clazztype, 1.9 tree.constructor, 1.10 localEnv, 1.11 tree.args, 1.12 @@ -1465,7 +1465,7 @@ 1.13 typeargtypes, 1.14 localEnv.info.varArgs); 1.15 if (localEnv.info.varArgs) 1.16 - assert ctorType.isErroneous() || tree.varargsElement != null; 1.17 + assert tree.constructorType.isErroneous() || tree.varargsElement != null; 1.18 } 1.19 1.20 if (cdef != null) { 1.21 @@ -1527,6 +1527,13 @@ 1.22 typeargtypes, true, tree.varargsElement != null); 1.23 assert sym.kind < AMBIGUOUS || tree.constructor.type.isErroneous(); 1.24 tree.constructor = sym; 1.25 + tree.constructorType = checkMethod(clazztype, 1.26 + tree.constructor, 1.27 + localEnv, 1.28 + tree.args, 1.29 + argtypes, 1.30 + typeargtypes, 1.31 + localEnv.info.varArgs); 1.32 } 1.33 1.34 if (tree.constructor != null && tree.constructor.kind == MTH)
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Jan 13 13:28:20 2009 +0000 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Jan 13 13:28:42 2009 +0000 2.3 @@ -1136,11 +1136,32 @@ 2.4 scanExpr(tree.encl); 2.5 scanExprs(tree.args); 2.6 // scan(tree.def); 2.7 - for (List<Type> l = tree.constructor.type.getThrownTypes(); 2.8 + for (List<Type> l = tree.constructorType.getThrownTypes(); 2.9 l.nonEmpty(); 2.10 - l = l.tail) 2.11 + l = l.tail) { 2.12 markThrown(tree, l.head); 2.13 - scan(tree.def); 2.14 + } 2.15 + List<Type> caughtPrev = caught; 2.16 + try { 2.17 + // If the new class expression defines an anonymous class, 2.18 + // analysis of the anonymous constructor may encounter thrown 2.19 + // types which are unsubstituted type variables. 2.20 + // However, since the constructor's actual thrown types have 2.21 + // already been marked as thrown, it is safe to simply include 2.22 + // each of the constructor's formal thrown types in the set of 2.23 + // 'caught/declared to be thrown' types, for the duration of 2.24 + // the class def analysis. 2.25 + if (tree.def != null) 2.26 + for (List<Type> l = tree.constructor.type.getThrownTypes(); 2.27 + l.nonEmpty(); 2.28 + l = l.tail) { 2.29 + caught = chk.incl(l.head, caught); 2.30 + } 2.31 + scan(tree.def); 2.32 + } 2.33 + finally { 2.34 + caught = caughtPrev; 2.35 + } 2.36 } 2.37 2.38 public void visitNewArray(JCNewArray tree) {
3.1 --- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue Jan 13 13:28:20 2009 +0000 3.2 +++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue Jan 13 13:28:42 2009 +0000 3.3 @@ -1326,6 +1326,7 @@ 3.4 public JCClassDecl def; 3.5 public Symbol constructor; 3.6 public Type varargsElement; 3.7 + public Type constructorType; 3.8 protected JCNewClass(JCExpression encl, 3.9 List<JCExpression> typeargs, 3.10 JCExpression clazz,
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/generics/6723444/T6723444.java Tue Jan 13 13:28:42 2009 +0000 4.3 @@ -0,0 +1,80 @@ 4.4 +/* 4.5 + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 4.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 4.24 + * have any questions. 4.25 + */ 4.26 + 4.27 +/* 4.28 + * @test 4.29 + * @bug 6723444 4.30 + * 4.31 + * @summary javac fails to substitute type variables into a constructor's throws clause 4.32 + * @author Mark Mahieu 4.33 + * @compile/fail/ref=T6723444.out -XDstdout -XDrawDiagnostics T6723444.java 4.34 + * 4.35 + */ 4.36 +public class T6723444 { 4.37 + 4.38 + static class Foo<X extends Throwable> { 4.39 + Foo() throws X {} 4.40 + } 4.41 + 4.42 + <X extends Throwable> T6723444() 4.43 + throws X {} 4.44 + 4.45 + <X extends Throwable> T6723444(Foo<X> foo) 4.46 + throws X {} 4.47 + 4.48 + <X1 extends Throwable, X2 extends Throwable> T6723444(Foo<X1> foo, int i) 4.49 + throws X1, X2 {} 4.50 + 4.51 + public static void main(String[] args) throws Exception { 4.52 + 4.53 + // the following 8 statements should compile without error 4.54 + 4.55 + Foo<Exception> exFoo = new Foo<Exception>(); 4.56 + exFoo = new Foo<Exception>() {}; 4.57 + 4.58 + new<Exception> T6723444(); 4.59 + new<Exception> T6723444() {}; 4.60 + new T6723444(exFoo); 4.61 + new T6723444(exFoo) {}; 4.62 + new<Exception, Exception> T6723444(exFoo, 1); 4.63 + new<Exception, Exception> T6723444(exFoo, 1) {}; 4.64 + 4.65 + // the remaining statements should all raise an 4.66 + // unreported exception error 4.67 + 4.68 + new T6723444(exFoo, 1); 4.69 + new T6723444(exFoo, 1) {}; 4.70 + 4.71 + Foo<Throwable> thFoo = new Foo<Throwable>(); 4.72 + thFoo = new Foo<Throwable>() {}; 4.73 + 4.74 + new<Throwable> T6723444(); 4.75 + new<Throwable> T6723444() {}; 4.76 + new T6723444(thFoo); 4.77 + new T6723444(thFoo) {}; 4.78 + new T6723444(thFoo, 1); 4.79 + new T6723444(thFoo, 1) {}; 4.80 + new<Throwable, Throwable> T6723444(thFoo, 1); 4.81 + new<Throwable, Throwable> T6723444(thFoo, 1) {}; 4.82 + } 4.83 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/tools/javac/generics/6723444/T6723444.out Tue Jan 13 13:28:42 2009 +0000 5.3 @@ -0,0 +1,13 @@ 5.4 +T6723444.java:65:9: compiler.err.unreported.exception.need.to.catch.or.throw: X2 5.5 +T6723444.java:66:9: compiler.err.unreported.exception.need.to.catch.or.throw: X2 5.6 +T6723444.java:68:32: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.7 +T6723444.java:69:17: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.8 +T6723444.java:71:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.9 +T6723444.java:72:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.10 +T6723444.java:73:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.11 +T6723444.java:74:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.12 +T6723444.java:75:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.13 +T6723444.java:76:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.14 +T6723444.java:77:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.15 +T6723444.java:78:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable 5.16 +12 errors 5.17 \ No newline at end of file