Fri, 28 Jan 2011 12:03:49 +0000
6313164: javac generates code that fails byte code verification for the varargs feature
Summary: method applicability check should fail if formal varargs element type is not accessible
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Jan 28 12:01:07 2011 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Jan 28 12:03:49 2011 +0000 1.3 @@ -60,6 +60,7 @@ 1.4 1.5 private final Names names; 1.6 private final Log log; 1.7 + private final Resolve rs; 1.8 private final Symtab syms; 1.9 private final Enter enter; 1.10 private final Infer infer; 1.11 @@ -91,6 +92,7 @@ 1.12 1.13 names = Names.instance(context); 1.14 log = Log.instance(context); 1.15 + rs = Resolve.instance(context); 1.16 syms = Symtab.instance(context); 1.17 enter = Enter.instance(context); 1.18 infer = Infer.instance(context);
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Jan 28 12:01:07 2011 +0000 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Jan 28 12:03:49 2011 +0000 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -485,11 +485,8 @@ 2.11 @Override 2.12 public Type inst(List<Type> inferred, Types types) throws NoInstanceException { 2.13 List<Type> formals = types.subst(mt2.argtypes, tvars, inferred); 2.14 - if (!rs.argumentsAcceptable(capturedArgs, formals, 2.15 - allowBoxing, useVarargs, warn)) { 2.16 - // inferred method is not applicable 2.17 - throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", formals, argtypes); 2.18 - } 2.19 + // check that actuals conform to inferred formals 2.20 + checkArgumentsAcceptable(env, capturedArgs, formals, allowBoxing, useVarargs, warn); 2.21 // check that inferred bounds conform to their bounds 2.22 checkWithinBounds(all_tvars, 2.23 types.subst(inferredTypes, tvars, inferred), warn); 2.24 @@ -500,17 +497,27 @@ 2.25 }}; 2.26 return mt2; 2.27 } 2.28 - else if (!rs.argumentsAcceptable(capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn)) { 2.29 - // inferred method is not applicable 2.30 - throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", mt.getParameterTypes(), argtypes); 2.31 - } 2.32 else { 2.33 + // check that actuals conform to inferred formals 2.34 + checkArgumentsAcceptable(env, capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn); 2.35 // return instantiated version of method type 2.36 return mt; 2.37 } 2.38 } 2.39 //where 2.40 2.41 + private void checkArgumentsAcceptable(Env<AttrContext> env, List<Type> actuals, List<Type> formals, 2.42 + boolean allowBoxing, boolean useVarargs, Warner warn) { 2.43 + try { 2.44 + rs.checkRawArgumentsAcceptable(env, actuals, formals, 2.45 + allowBoxing, useVarargs, warn); 2.46 + } 2.47 + catch (Resolve.InapplicableMethodException ex) { 2.48 + // inferred method is not applicable 2.49 + throw invalidInstanceException.setMessage(ex.getDiagnostic()); 2.50 + } 2.51 + } 2.52 + 2.53 /** Try to instantiate argument type `that' to given type `to'. 2.54 * If this fails, try to insantiate `that' to `to' where 2.55 * every occurrence of a type variable in `tvars' is replaced
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 28 12:01:07 2011 +0000 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 28 12:03:49 2011 +0000 3.3 @@ -331,7 +331,7 @@ 3.4 throws Infer.InferenceException { 3.5 boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles; 3.6 if (useVarargs && (m.flags() & VARARGS) == 0) 3.7 - throw inapplicableMethodException.setMessage(null); 3.8 + throw inapplicableMethodException.setMessage(); 3.9 Type mt = types.memberType(site, m); 3.10 3.11 // tvars is the list of formal type variables for which type arguments 3.12 @@ -386,7 +386,7 @@ 3.13 useVarargs, 3.14 warn); 3.15 3.16 - checkRawArgumentsAcceptable(argtypes, mt.getParameterTypes(), 3.17 + checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(), 3.18 allowBoxing, useVarargs, warn); 3.19 return mt; 3.20 } 3.21 @@ -411,19 +411,21 @@ 3.22 3.23 /** Check if a parameter list accepts a list of args. 3.24 */ 3.25 - boolean argumentsAcceptable(List<Type> argtypes, 3.26 + boolean argumentsAcceptable(Env<AttrContext> env, 3.27 + List<Type> argtypes, 3.28 List<Type> formals, 3.29 boolean allowBoxing, 3.30 boolean useVarargs, 3.31 Warner warn) { 3.32 try { 3.33 - checkRawArgumentsAcceptable(argtypes, formals, allowBoxing, useVarargs, warn); 3.34 + checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn); 3.35 return true; 3.36 } catch (InapplicableMethodException ex) { 3.37 return false; 3.38 } 3.39 } 3.40 - void checkRawArgumentsAcceptable(List<Type> argtypes, 3.41 + void checkRawArgumentsAcceptable(Env<AttrContext> env, 3.42 + List<Type> argtypes, 3.43 List<Type> formals, 3.44 boolean allowBoxing, 3.45 boolean useVarargs, 3.46 @@ -460,6 +462,14 @@ 3.47 elt); 3.48 argtypes = argtypes.tail; 3.49 } 3.50 + //check varargs element type accessibility 3.51 + if (!isAccessible(env, elt)) { 3.52 + Symbol location = env.enclClass.sym; 3.53 + throw inapplicableMethodException.setMessage("inaccessible.varargs.type", 3.54 + elt, 3.55 + Kinds.kindName(location), 3.56 + location); 3.57 + } 3.58 } 3.59 return; 3.60 } 3.61 @@ -474,6 +484,10 @@ 3.62 this.diagnostic = null; 3.63 this.diags = diags; 3.64 } 3.65 + InapplicableMethodException setMessage() { 3.66 + this.diagnostic = null; 3.67 + return this; 3.68 + } 3.69 InapplicableMethodException setMessage(String key) { 3.70 this.diagnostic = key != null ? diags.fragment(key) : null; 3.71 return this; 3.72 @@ -482,6 +496,10 @@ 3.73 this.diagnostic = key != null ? diags.fragment(key, args) : null; 3.74 return this; 3.75 } 3.76 + InapplicableMethodException setMessage(JCDiagnostic diag) { 3.77 + this.diagnostic = diag; 3.78 + return this; 3.79 + } 3.80 3.81 public JCDiagnostic getDiagnostic() { 3.82 return diagnostic;
4.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Jan 28 12:01:07 2011 +0000 4.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Jan 28 12:03:49 2011 +0000 4.3 @@ -831,6 +831,10 @@ 4.4 compiler.misc.varargs.trustme.on.virtual.varargs=\ 4.5 Instance method {0} is not final. 4.6 4.7 +# 0: type, 1: kind, 2: symbol 4.8 +compiler.misc.inaccessible.varargs.type=\ 4.9 + formal varargs element type {0} is not accessible from {1} {2} 4.10 + 4.11 # In the following string, {1} will always be the detail message from 4.12 # java.io.IOException. 4.13 # 0: symbol, 1: string 4.14 @@ -1564,11 +1568,6 @@ 4.15 inferred: {0}\n\ 4.16 bound(s): {1} 4.17 4.18 -compiler.misc.inferred.do.not.conform.to.params=\ 4.19 - actual arguments do not conform to inferred formal arguments\n\ 4.20 - required: {0}\n\ 4.21 - found: {1} 4.22 - 4.23 # 0: symbol 4.24 compiler.misc.diamond=\ 4.25 {0}<>
5.1 --- a/test/tools/javac/diags/examples.not-yet.txt Fri Jan 28 12:01:07 2011 +0000 5.2 +++ b/test/tools/javac/diags/examples.not-yet.txt Fri Jan 28 12:03:49 2011 +0000 5.3 @@ -63,7 +63,6 @@ 5.4 compiler.misc.fatal.err.cant.close.loader # JavacProcessingEnvironment 5.5 compiler.misc.file.does.not.contain.package 5.6 compiler.misc.illegal.start.of.class.file 5.7 -compiler.misc.inferred.do.not.conform.to.params # UNUSED (hard to see if very complex inference scenario might require this though, so leaving it in, as per JLS3) 5.8 compiler.misc.kindname.annotation 5.9 compiler.misc.kindname.enum 5.10 compiler.misc.kindname.package
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/diags/examples/InaccessibleVarargsType/InaccessibleVarargsType.java Fri Jan 28 12:03:49 2011 +0000 6.3 @@ -0,0 +1,31 @@ 6.4 +/* 6.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + */ 6.26 + 6.27 +// key: compiler.misc.inaccessible.varargs.type 6.28 +// key: compiler.err.cant.apply.symbol.1 6.29 + 6.30 +import p1.B; 6.31 + 6.32 +class InaccessibleVarargsType { 6.33 + { new B().foo(new B(), new B()); } 6.34 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/diags/examples/InaccessibleVarargsType/p1/A.java Fri Jan 28 12:03:49 2011 +0000 7.3 @@ -0,0 +1,28 @@ 7.4 +/* 7.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. 7.11 + * 7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.15 + * version 2 for more details (a copy is included in the LICENSE file that 7.16 + * accompanied this code). 7.17 + * 7.18 + * You should have received a copy of the GNU General Public License version 7.19 + * 2 along with this work; if not, write to the Free Software Foundation, 7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.21 + * 7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.23 + * or visit www.oracle.com if you need additional information or have any 7.24 + * questions. 7.25 + */ 7.26 + 7.27 +package p1; 7.28 + 7.29 +class A { 7.30 + A() { } 7.31 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/tools/javac/diags/examples/InaccessibleVarargsType/p1/B.java Fri Jan 28 12:03:49 2011 +0000 8.3 @@ -0,0 +1,29 @@ 8.4 +/* 8.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. 8.11 + * 8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.15 + * version 2 for more details (a copy is included in the LICENSE file that 8.16 + * accompanied this code). 8.17 + * 8.18 + * You should have received a copy of the GNU General Public License version 8.19 + * 2 along with this work; if not, write to the Free Software Foundation, 8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.21 + * 8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.23 + * or visit www.oracle.com if you need additional information or have any 8.24 + * questions. 8.25 + */ 8.26 + 8.27 +package p1; 8.28 + 8.29 +public class B extends A { 8.30 + public B() {} 8.31 + public void foo(A... args) { } 8.32 +}
9.1 --- a/test/tools/javac/generics/inference/6638712/T6638712c.out Fri Jan 28 12:01:07 2011 +0000 9.2 +++ b/test/tools/javac/generics/inference/6638712/T6638712c.out Fri Jan 28 12:03:49 2011 +0000 9.3 @@ -1,2 +1,2 @@ 9.4 -T6638712c.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, sort, T[],java.util.Comparator<? super T>, java.lang.Enum[],java.util.Comparator<java.lang.Enum<?>>, kindname.class, T6638712c, (compiler.misc.inferred.do.not.conform.to.params: java.lang.Enum[],java.util.Comparator<? super java.lang.Enum>, java.lang.Enum[],java.util.Comparator<java.lang.Enum<?>>) 9.5 +T6638712c.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, sort, T[],java.util.Comparator<? super T>, java.lang.Enum[],java.util.Comparator<java.lang.Enum<?>>, kindname.class, T6638712c, (compiler.misc.no.conforming.assignment.exists: java.util.Comparator<java.lang.Enum<?>>, java.util.Comparator<? super java.lang.Enum>) 9.6 1 error
10.1 --- a/test/tools/javac/generics/inference/6638712/T6638712d.out Fri Jan 28 12:01:07 2011 +0000 10.2 +++ b/test/tools/javac/generics/inference/6638712/T6638712d.out Fri Jan 28 12:03:49 2011 +0000 10.3 @@ -1,2 +1,2 @@ 10.4 -T6638712d.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.inferred.do.not.conform.to.params: java.lang.String,java.util.List<java.util.List<java.lang.String>>, int,java.util.List<java.util.List<java.lang.String>>) 10.5 +T6638712d.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.no.conforming.assignment.exists: int, java.lang.String) 10.6 1 error
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/tools/javac/varargs/6313164/T6313164.java Fri Jan 28 12:03:49 2011 +0000 11.3 @@ -0,0 +1,18 @@ 11.4 +/* 11.5 + * @test /nodynamiccopyright/ 11.6 + * @bug 6313164 11.7 + * @author mcimadamore 11.8 + * @summary javac generates code that fails byte code verification for the varargs feature 11.9 + * @compile/fail/ref=T6313164.out -XDrawDiagnostics T6313164.java 11.10 + */ 11.11 +import p1.*; 11.12 + 11.13 +class T6313164 { 11.14 + { B b = new B(); 11.15 + b.foo1(new B(), new B()); //error - A not accesible 11.16 + b.foo2(new B(), new B()); //ok - A not accessible, but foo2(Object...) applicable 11.17 + b.foo3(null, null); //error - A (inferred) not accesible 11.18 + b.foo4(null, null); //error - A (inferred in 15.12.2.8 - no resolution backtrack) not accesible 11.19 + b.foo4(new B(), new C()); //ok - A (inferred in 15.12.2.7) not accessible, but foo4(Object...) applicable 11.20 + } 11.21 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/test/tools/javac/varargs/6313164/T6313164.out Fri Jan 28 12:03:49 2011 +0000 12.3 @@ -0,0 +1,6 @@ 12.4 +T6313164.java:12:8: compiler.err.cant.apply.symbol.1: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) 12.5 +T6313164.java:14:13: compiler.err.invalid.inferred.types: X, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) 12.6 +T6313164.java:15:13: compiler.err.invalid.inferred.types: X, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) 12.7 +- compiler.note.unchecked.filename: B.java 12.8 +- compiler.note.unchecked.recompile 12.9 +3 errors
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/test/tools/javac/varargs/6313164/p1/A.java Fri Jan 28 12:03:49 2011 +0000 13.3 @@ -0,0 +1,28 @@ 13.4 +/* 13.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.7 + * 13.8 + * This code is free software; you can redistribute it and/or modify it 13.9 + * under the terms of the GNU General Public License version 2 only, as 13.10 + * published by the Free Software Foundation. 13.11 + * 13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13.15 + * version 2 for more details (a copy is included in the LICENSE file that 13.16 + * accompanied this code). 13.17 + * 13.18 + * You should have received a copy of the GNU General Public License version 13.19 + * 2 along with this work; if not, write to the Free Software Foundation, 13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 13.21 + * 13.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 13.23 + * or visit www.oracle.com if you need additional information or have any 13.24 + * questions. 13.25 + */ 13.26 + 13.27 +package p1; 13.28 + 13.29 +class A { 13.30 + A() { } 13.31 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/test/tools/javac/varargs/6313164/p1/B.java Fri Jan 28 12:03:49 2011 +0000 14.3 @@ -0,0 +1,35 @@ 14.4 +/* 14.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.7 + * 14.8 + * This code is free software; you can redistribute it and/or modify it 14.9 + * under the terms of the GNU General Public License version 2 only, as 14.10 + * published by the Free Software Foundation. 14.11 + * 14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14.15 + * version 2 for more details (a copy is included in the LICENSE file that 14.16 + * accompanied this code). 14.17 + * 14.18 + * You should have received a copy of the GNU General Public License version 14.19 + * 2 along with this work; if not, write to the Free Software Foundation, 14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 14.21 + * 14.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 14.23 + * or visit www.oracle.com if you need additional information or have any 14.24 + * questions. 14.25 + */ 14.26 + 14.27 +package p1; 14.28 + 14.29 +public class B extends A { 14.30 + public B() {} 14.31 + public void foo1(A... args) { } 14.32 + public void foo2(A... args) { } 14.33 + public void foo2(Object... args) { } 14.34 + public <X extends A> void foo3(X... args) { } 14.35 + public <X extends A> void foo4(X... args) { } 14.36 + public void foo4(Object... args) { } 14.37 + 14.38 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/test/tools/javac/varargs/6313164/p1/C.java Fri Jan 28 12:03:49 2011 +0000 15.3 @@ -0,0 +1,26 @@ 15.4 +/* 15.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.7 + * 15.8 + * This code is free software; you can redistribute it and/or modify it 15.9 + * under the terms of the GNU General Public License version 2 only, as 15.10 + * published by the Free Software Foundation. 15.11 + * 15.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15.15 + * version 2 for more details (a copy is included in the LICENSE file that 15.16 + * accompanied this code). 15.17 + * 15.18 + * You should have received a copy of the GNU General Public License version 15.19 + * 2 along with this work; if not, write to the Free Software Foundation, 15.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 15.21 + * 15.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 15.23 + * or visit www.oracle.com if you need additional information or have any 15.24 + * questions. 15.25 + */ 15.26 + 15.27 +package p1; 15.28 + 15.29 +public class C extends A { }