From daniel.smith at oracle.com Thu Sep 3 19:12:37 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 3 Sep 2015 13:12:37 -0600 Subject: Please reply to my JDK-8059640 issue comment In-Reply-To: <55AFCF71.5050101@oracle.com> References: <559AB728.80105@oracle.com> <55AFCF71.5050101@oracle.com> Message-ID: <27DAEE0D-791D-4BBC-A78D-1BFC1049C3A7@oracle.com> > On Jul 22, 2015, at 11:14 AM, Georgiy Rakov wrote: > > In the example you provided inconsistency occurs at the point of *invocation of* the method of an object derived from a method reference expression. But we can consider another example which contains inconsistency occurring at the point of *evaluation of* a method reference expression: > > interface MethodSupplier { void m(int a); } > > interface MyFunctionalInterface { int invokeMethodReference(int a); } > > class MethodSupplierImpl implements MethodSupplier { > @Override > public void m(int a) {} > } > > MyFunctionalInterface instance = null; > MethodSupplier ms = new MethodSupplierImpl(); > instance = ms::m; //inconsistency occurs here > instance.invokeMethodReference(1); > > Currently the behavior is Ok, that is provided MethodSupplierImpl is recompiled without implementing MethodSupplier, ICCE is thrown when executing "instance.invokeMethodReference(1)". But potentially it looks possible for the error to be thrown during executing "instance = ms::m" and suggested spec change doesn't encompass this case. So I wonder if it's worth encompassing such case for the suggested spec change. Would it be possible to detect the error at that point? Sure. Do we want to change the spec to do so? No. The currently-specified behavior is consistent with actual behavior, and is fine: the check that the receiver implements an interface happens at the point that the invocation is about to happen. > Could you please also tell if I understand correctly that suggested spec change specifies the possibility of throwing LinkageError during *evaluation of* method reference and not during *invocation of* the method of an object derived from a method reference expression. Yep. JDK-8059640 is only concerned with behavior that occurs during evaluation. The possibility of LinkageErrors occurring during invocation is already covered by the spec -- 15.13.3 says: "Run-time evaluation of the method invocation expression is as specified in ?15.12.4.3, ?15.12.4.4, and ?15.12.4.5". ?Dan From daniel.smith at oracle.com Thu Sep 3 19:24:13 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 3 Sep 2015 13:24:13 -0600 Subject: The type of instance creation expression with types arguments provided is not affected by 15.12.2.6? In-Reply-To: <55CB5125.7030105@oracle.com> References: <55CB5125.7030105@oracle.com> Message-ID: <605E2DF9-D8D2-4C0E-A02A-A7A8879B897D@oracle.com> > On Aug 12, 2015, at 7:59 AM, Georgiy Rakov wrote: > > Hello, > > following new spec presented in JDK-8073593 states: > Otherwise, the class instance creation expression does not use <> to elide class ***or interface*** type arguments. > > ***If C is not an anonymous class,*** let T be the type denoted by C followed by any class type arguments in the expression. The process specified in ?15.12.2, modified to handle constructors, is used to select one of the constructors of T and determine its throws clause. > ... > > Otherwise, the return type is T. > ... > > The type of the class instance creation expression is the return type of the chosen constructor, as defined above. > In particular it says that 15.12.2 is applied in order to determine the throws clause. If I understand correctly it means that the throws types can be changed by 15.12.2.6 if unchecked conversion was necessary for the chosen method (ctor) to be applicable. But 15.12.2.6 also changes the return type in the same case; yet the assertion presented above doesn't mention that the return type is determined by the process specified in 15.12.2 (only throws clause is mentioned). So could you please tell if I understand correctly that it means that the return type of instance creation expression is not changed as per 15.12.2.6 in this case. I'm asking about this because I've come across the fact that following code compiles successfully on JDK9b76: > class MyType {} > > class List { > List copyThis() { return null; } > } > > public class Test28 { > static void m2(List list1, List list2) {} > static List m1(U item) { > return null; > } > static void test() { > m2(new List>(), m1(new Foo(new MyType()).copyThis()).copyThis()); > } > } > > class Foo { > Foo(MyType a2){} > Foo copyThis() { > return null; > } > } > > > > In this code unchecked conversion is necessary in order for the Foo constructor to be applicable, so if 15.12.2.6 were to change the return type of constructor it would be raw type Foo, which finally would cause compilation failure due to the incompatible equality constraints on T inferred. So could you please also confirm that this is not a bug and javac behaves according to spec for the reasons presented above. FWIW, note that you're looking at established spec text from JLS 7, and JDK-8073593 has nothing to do with the issue. JLS 3 had the same problem, though the text was different. The mapping between constructors and overload resolution is not as clear as it should be. This is a known issue: see JDK-8034925. (Glad you noticed it too, though!) For now, it's fair to assume that javac, as the reference implementation, establishes the intended behavior, and that the spec should be updated to reflect that. ?Dan From daniel.smith at oracle.com Thu Sep 3 19:51:39 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 3 Sep 2015 13:51:39 -0600 Subject: The supertype of anonymous class is expected to be a raw type In-Reply-To: <55C0E38A.3050105@oracle.com> References: <55BF628D.7070502@oracle.com> <55BFB8B6.6030705@oracle.com> <55C0E38A.3050105@oracle.com> Message-ID: <3CDA0585-7BF5-419A-B691-C20D406CF048@oracle.com> > On Aug 4, 2015, at 10:08 AM, Georgiy Rakov wrote: > > So the conclusion I made earlier seems to be wrong now. However it looks strange that, say, constructor invocation type, determines anonymous class supertypes for diamond cases only. So could you please tell if this is really the intention of the spec. For instance code below outputs that just for diamond case anonymous class super class is not parameterized: > > When class type arguments are given, the super type is parameterized. > When class type arguments and ctor type arguments are given, the super type is parameterized. > When diamond is used, the super type is not parameterized. Yep, that's right. When diamond is involved, we have to erase the return type. When type arguments are explicit, javac does not perform erasure. Javac's behavior is probably correct, though the spec doesn't spell this out. As I just noted in the thread "The type of instance creation expression with types arguments provided is not affected by 15.12.2.6?", there's an existing bug to investigate the special treatment of constructors with explicit type arguments: JDK-8034925. Note that this question isn't specific to anonymous classes -- below is a case where erasure happens for a diamond constructor invocation but not for one with explicit type arguments: import java.util.List; class ErasedDiamond { ErasedDiamond(List arg) {} List getList() { return null; } static void test(List l) { new ErasedDiamond(l).getList().get(0).length(); // no error -- constructor produces a ErasedDiamond, 'getList' returns a List new ErasedDiamond<>(l).getList().get(0).length(); // error -- constructor produces a raw ErasedDiamond, 'getList' returns a raw List } } ?Dan From daniel.smith at oracle.com Thu Sep 3 20:22:48 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 3 Sep 2015 14:22:48 -0600 Subject: Non generic constructor thrown type (class type variable) is not erased despite of unchecked conversion In-Reply-To: <55E05BF3.2030903@oracle.com> References: <55E05BF3.2030903@oracle.com> Message-ID: <9507F9E5-8011-4431-B520-A086468ED8FA@oracle.com> I think this one also comes down to JDK-8034925: what is the "return type and thrown types of the method's type" (15.12.2.6) when the "method" is actually a constructor? It looks like the answer has to be: the type of the declaration, *after* substituting the class type arguments. So erasure is going to be applied to MyDerivedException, not the type variable E1. For comparison, here's how this works when working with methods of a generic class: public class ErasedThrows { static class CustomException extends Exception { void foo() {} } T m(Iterable arg) throws T { return null; } static void test(Iterable i) throws CustomException { new ErasedThrows().m(i).foo(); // m, as a member of ErasedThrows, has signature: // CustomException m(Iterable arg) throws CustomException // this gets erased, but that doesn't change the return or thrown type -- neither are Exception } } ?Dan > On Aug 28, 2015, at 7:02 AM, Georgiy Rakov wrote: > > Hello, > > let's consider following example. > class MyException extends Exception {} > > class MyDerivedException extends MyException {} > > > class MyType { > MyType(T t) {} > } > > public class Test31 { > public static void test() { > try { > MyDerivedException e1 = new MyDerivedException(); > > Foo foo = new Foo(e1, new MyType("")); > } catch (MyDerivedException e2) { > } > } > } > > class Foo { > public Foo(E1 e, MyType a) throws E1 { > throw e; > } > } > It compiles successfully on JDK9b78. Now let's consider reasoning presented below. > > 1. According to following assertion, 15.12.2 is used in order to determine the constructor thrown types: > ***If C is not an anonymous class,*** let T be the type denoted by C > followed by any class type arguments in the expression. The process > specified in ?15.12.2, modified to handle constructors, is used to > select one of the constructors of T and determine its throws clause [jls-15.9.3-120-B.1 ] > 2. According to my understanding the types in throws clause are determined in the last subsection of 15.12.2, that is in 15.12.2.6, which states: > If the chosen method is not generic, then [jls-15.12.2.6-100-C ]: > > If unchecked conversion was necessary for the method to be applicable, the parameter types of the invocation type are the parameter types of the method's type, and the return type and thrown types are given by the erasures of the return type and thrown types of the method's type [jls-15.12.2.6-100-C-A ]. > 3. So unchecked conversion is necessary in order for the constructor to be applicable because expression 'new MyType("")' of a raw type is passed to parameterized parameter 'MyType a'. > > Could you please tell if I understand correctly that JLS implies that when erasing constructor thrown types, the actual type which is erased is not E1 but E1 with following substitution applied [E1 := MyDerivedException]. According to my understanding JLS doesn't specify this explicitly, but as I see it such clarification could be useful. Could you please also tell if you think it's worth filing P4 issue about this. > > Thank you, > Gosha. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From aleksey.shipilev at oracle.com Fri Sep 4 08:47:39 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Fri, 04 Sep 2015 11:47:39 +0300 Subject: Indify String Concat progress In-Reply-To: <55E0E0F1.4090907@oracle.com> References: <55E0E0F1.4090907@oracle.com> Message-ID: <55E95AAB.7050004@oracle.com> On 08/29/2015 01:30 AM, Aleksey Shipilev wrote: > I have finally found time to further hack on this: > https://bugs.openjdk.java.net/browse/JDK-8085796 ... > Comments, suggestions, etc. are welcome. I am contemplating to "submit" > the JEP early next week, pending no blockers. Thanks for the comments (mostly delivered privately). I have submitted the JEP. -Aleksey -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From daniel.smith at oracle.com Fri Sep 4 16:52:35 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 4 Sep 2015 10:52:35 -0600 Subject: Generic constructor thrown type (constructor type variable) is not erased despite of unchecked conversion In-Reply-To: <55E07F52.8030904@oracle.com> References: <55E07F52.8030904@oracle.com> Message-ID: This looks like a legitimate javac bug. After some testing, it seems fairly widespread and longstanding -- the return type & throws clause erasure rule is apparently implement incorrectly: javac is performing a substitution before erasure. I've filed a bug: https://bugs.openjdk.java.net/browse/JDK-8135087 ?Dan > On Aug 28, 2015, at 9:33 AM, Georgiy Rakov wrote: > > Hello, > > let's consider following example. > class MyException extends Exception {} > > class MyDerivedException extends MyException {} > > > class MyType { > MyType(T t) {} > } > > public class Test32 { > public static void test() { > try { > MyDerivedException e1 = new MyDerivedException(); > > Foo foo = new Foo(e1, new MyType("")); > } catch (MyDerivedException e2) { > } > } > } > > class Foo { > public Foo(E1 e, MyType a) throws E1 { > throw e; > } > } > It compiles successfully on JDK9b78. Now let's consider reasoning presented below. 1. According to following assertion, 15.12.2 is used in order to determine the constructor thrown types: > ***If C is not an anonymous class,*** let T be the type denoted by C followed by any class type arguments in the expression. The process specified in ?15.12.2, modified to handle constructors, is used to select one of the constructors of T and determine its throws clause. > 2. According to my understanding the types in throws clause are determined in the last subsection of 15.12.2, that is in 15.12.2.6, which states: > If the chosen method is generic and the method invocation does not provide explicit type arguments, the invocation type is inferred as specified in ?18.5.2. > 3. 18.5.2 contains following assertion: > If unchecked conversion was necessary for the method to be applicable during constraint set reduction in ?18.5.1, then the parameter types of the invocation type of m are obtained by applying a' to the parameter types of m's type, and the return type and thrown types of the invocation type of m are given by the erasure of the return type and thrown types of m's type. (jls-18.5.2-100-F.1-A) > and 18.2.2. contains following assertions: > A constraint formula of the form ?S ? T? is reduced as follows: (jls-18.2.2-100) Otherwise, if T is a parameterized type of the form G, and there exists no type of the form G<...> that is a supertype of S, but the raw type G is a supertype of S, then the constraint reduces to true. (jls-18.2.2-100-D) The fourth and fifth cases are implicit uses of unchecked conversion (?5.1.9). These, along with any use of unchecked conversion in the first case, may result in compile-time unchecked warnings, and may influence a method's invocation type (?15.12.2.6). (jls-18.2.2-110) > 3.1. During reduction constraint [new MyType("") -> MyType] is reduced to [MyType -> MyType]. 3.2. [MyType -> MyType] is reduced to true according to jls-18.2.2-100-D. 3.3. Thus according to jls-18.2.2-110 step 3.2 is considered as applying unchecked conversion. 3.4. Hence according to jls-18.5.2-100-F.1-A the constructor exception type should be erased that is E1 should be erased to MyException which should have caused compilation failure, but compilation succeeds. 3.5. So if I understand correctly javac behaves as if jls-18.5.2-100-F.1-A specified that substitution a' is applied to m's thrown type first, and only after that ctor thrown type is erased. This looks like a spec issue, that is spec should have specified something like: "and the return type and thrown types of the invocation type of m are given by the erasure of the return type and thrown types of m2 where m2 is the result of applying a' to m's type" (I guess the same is true for the return type). Could you please tell if you agree that this is really a spec issue. Thank you, Georgiy. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Sat Sep 5 15:19:51 2015 From: bsrbnd at gmail.com (bsrbnd) Date: Sat, 5 Sep 2015 17:19:51 +0200 Subject: [PATCH] 8133135: NPE on anonymous class defined by qualified instance creation expression with diamond In-Reply-To: <55E46580.8070705@oracle.com> References: <55E46580.8070705@oracle.com> Message-ID: Just a little precision; clazz is reassigned with clazzid1 in method Attr.visitNewClass() (on line 1973) which implies that it differs from tree.clazz: if (tree.encl != null) { // We are seeing a qualified new, of the form // .new C <...> (...) ... [...] clazz = clazzid1; } It is then passed to Attr.visitAnonymousClassDefinition() and used to perform type inference. This is why recurcivity condition could be made on clazz.type instead of tree.clazz.type as shown in the first patch. But, I was also wondering if tree.clazz should really differs from clazz as we assign clazz.type to tree.clazz.type in Attr.visitNewClass() on line 2088 before calling Attr.visitAnonymousClassDefinition()? if (!constructorType.isErroneous()) { tree.clazz.type = clazz.type = constructorType.getReturnType(); tree.constructorType = types.createMethodTypeWithReturn(constructorType, syms.voidType); } If it shouldn't, tree.clazz have to match clazz and then recurcivity condition on tree.clazz.type could be right... This leads me to give next a second patch (only in Attr.visitNewClass()) with a slightly different meaning as explained above: diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1970,7 +1970,7 @@ ((JCTypeApply) clazz).arguments); } - clazz = clazzid1; + tree.clazz = clazz = clazzid1; } // Attribute clazz expression and store Regards, bsrbnd 2015-08-31 16:32 GMT+02:00 Maurizio Cimadamore : > Thanks, I'll take a look. > > Maurizio > > > On 31/08/15 14:40, bsrbnd wrote: >> >> Hi, >> >> As explained in issue 8133135, the following code produces a null >> pointer exception because the symbol of the anonymous class is not set >> during the attribute phase: >> >> class List {} >> >> class ClassOut { >> class ClassIn { public ClassIn() {}} >> } >> >> public class TestBug { >> public static List m(List list, T item) {return list;} >> >> >> public static void main(String[] args) { >> m(new List>(), new ClassOut().new >> ClassIn<>(){}); >> } >> } >> >> Method Attr.visitAnonymousClassDefinition() doesn't perform well type >> inference with diamond. Recurcivity condition on tree.clazz.type seems >> to be wrong because it never changes... instead, it should be made on >> clazz.type (or clazztype) to go deeper on the type resolution. >> >> The following patch shows a possible solution, I think (to be checked >> by someone who knows the code better than me...): >> >> diff --git >> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java >> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java >> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java >> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java >> @@ -2173,7 +2173,7 @@ >> final boolean isDiamond = TreeInfo.isDiamond(tree); >> if (isDiamond >> && ((tree.constructorType != null && >> inferenceContext.free(tree.constructorType)) >> - || (tree.clazz.type != null && >> inferenceContext.free(tree.clazz.type)))) { >> + || (clazz.type != null && >> inferenceContext.free(clazz.type)))) { >> final ResultInfo resultInfoForClassDefinition = >> this.resultInfo; >> >> inferenceContext.addFreeTypeListener(List.of(tree.constructorType, >> tree.clazz.type), >> instantiatedContext -> { >> >> Regards, >> >> bsrbnd > > From srikanth.adayapalam at oracle.com Mon Sep 7 10:52:48 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Mon, 07 Sep 2015 16:22:48 +0530 Subject: [PATCH] 8133135: NPE on anonymous class defined by qualified instance creation expression with diamond In-Reply-To: References: <55E46580.8070705@oracle.com> Message-ID: <55ED6C80.8020202@oracle.com> Hello ! Thanks for the patch. I can help take it forward. (I implemented <> with anonymous classes - I have been away on leave for some time and expect to have some cycles beginning this week.) Thanks! Srikanth On Saturday 05 September 2015 08:49 PM, bsrbnd wrote: > Just a little precision; > clazz is reassigned with clazzid1 in method Attr.visitNewClass() (on > line 1973) which implies that it differs from tree.clazz: > > if (tree.encl != null) { > // We are seeing a qualified new, of the form > // .new C <...> (...) ... > > [...] > > clazz = clazzid1; > } > > > It is then passed to Attr.visitAnonymousClassDefinition() and used to > perform type inference. > This is why recurcivity condition could be made on clazz.type instead > of tree.clazz.type as shown in the first patch. > > But, I was also wondering if tree.clazz should really differs from > clazz as we assign clazz.type to tree.clazz.type in > Attr.visitNewClass() on line 2088 before calling > Attr.visitAnonymousClassDefinition()? > > if (!constructorType.isErroneous()) { > tree.clazz.type = clazz.type = > constructorType.getReturnType(); > tree.constructorType = > types.createMethodTypeWithReturn(constructorType, syms.voidType); > } > > If it shouldn't, tree.clazz have to match clazz and then recurcivity > condition on tree.clazz.type could be right... > This leads me to give next a second patch (only in > Attr.visitNewClass()) with a slightly different meaning as explained > above: > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java > @@ -1970,7 +1970,7 @@ > ((JCTypeApply) clazz).arguments); > } > > - clazz = clazzid1; > + tree.clazz = clazz = clazzid1; > } > > // Attribute clazz expression and store > > Regards, > bsrbnd > > 2015-08-31 16:32 GMT+02:00 Maurizio Cimadamore : >> Thanks, I'll take a look. >> >> Maurizio >> >> >> On 31/08/15 14:40, bsrbnd wrote: >>> Hi, >>> >>> As explained in issue 8133135, the following code produces a null >>> pointer exception because the symbol of the anonymous class is not set >>> during the attribute phase: >>> >>> class List {} >>> >>> class ClassOut { >>> class ClassIn { public ClassIn() {}} >>> } >>> >>> public class TestBug { >>> public static List m(List list, T item) {return list;} >>> >>> >>> public static void main(String[] args) { >>> m(new List>(), new ClassOut().new >>> ClassIn<>(){}); >>> } >>> } >>> >>> Method Attr.visitAnonymousClassDefinition() doesn't perform well type >>> inference with diamond. Recurcivity condition on tree.clazz.type seems >>> to be wrong because it never changes... instead, it should be made on >>> clazz.type (or clazztype) to go deeper on the type resolution. >>> >>> The following patch shows a possible solution, I think (to be checked >>> by someone who knows the code better than me...): >>> >>> diff --git >>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java >>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java >>> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java >>> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java >>> @@ -2173,7 +2173,7 @@ >>> final boolean isDiamond = TreeInfo.isDiamond(tree); >>> if (isDiamond >>> && ((tree.constructorType != null && >>> inferenceContext.free(tree.constructorType)) >>> - || (tree.clazz.type != null && >>> inferenceContext.free(tree.clazz.type)))) { >>> + || (clazz.type != null && >>> inferenceContext.free(clazz.type)))) { >>> final ResultInfo resultInfoForClassDefinition = >>> this.resultInfo; >>> >>> inferenceContext.addFreeTypeListener(List.of(tree.constructorType, >>> tree.clazz.type), >>> instantiatedContext -> { >>> >>> Regards, >>> >>> bsrbnd >> From georgiy.rakov at oracle.com Fri Sep 11 18:06:32 2015 From: georgiy.rakov at oracle.com (Georgiy Rakov) Date: Fri, 11 Sep 2015 21:06:32 +0300 Subject: Subtyping constraint and unchecked conversion In-Reply-To: <55F31025.5010601@oracle.com> References: <55F2ACAC.2060801@oracle.com> <55F30143.3050901@oracle.com> <55F30CF0.6060300@oracle.com> <55F31025.5010601@oracle.com> Message-ID: <55F31828.8040002@oracle.com> Hello, let's consider following example: class MyList { } class Foo { } public class Test36 { public static MyList m1(U item) {return null; } public static >void m2(MyList l) { } public static void run() { m2(m1(new Foo())); } } It compiles successfully on JDK9b80. However according to my understanding compilation should fail, because: 1. Originally we have following bounds: U <: Object; T <: Foo and constraints: Foo <: U MyList <: MyList 2. The last constraint is reduced as it follows: MyList <: MyList => U <= ? extends T => U <: T 3. When U <: T is created following transitivity chain appears: Foo <: U, U <: T, T <: Foo so incorporating U <: T implies following constraint: Foo <: Foo 4. Since raw type is not a subtype of corresponding generic type parameterization, and unchecked conversion is not applied here too, compile time error should occur, but it doesn't. If it were a type compatibility constraint then it will be reduced to true, but this is a subtyping constraint. Additionally, Xlint outputs following: javac -Xlint:unchecked Test36.java Test36.java:10: warning: [unchecked] unchecked method invocation: method m2 in class Test36 is applied to given types m2(m1(new Foo())); ^ required: MyList found: MyList where T is a type-variable: T extends Foo declared in method m2(MyList) 1 warning But it's not clear why unchecked conversion occurs here. What is reported by Xlint is that the parameterized type is converted to another paramterized type, the former has a raw type as its type argument but it's not clear what spec assertions specify how unchecked conversion is applied to these type arguments. In general this looks like a javac bug. Could you please tell if it really is. Thank you, Georgiy. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- class MyList { } class Foo { } public class Test36 { public static MyList m1(U item) { return null; } public static > void m2(MyList l) { } public static void run() { m2(m1(new Foo())); } } From forax at univ-mlv.fr Mon Sep 14 07:15:53 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 14 Sep 2015 09:15:53 +0200 (CEST) Subject: Off by one bug in com.sun/tools.javac.jvm.ClassReader In-Reply-To: <1526756427.70542.1442214451341.JavaMail.zimbra@u-pem.fr> Message-ID: <928747990.74160.1442214953793.JavaMail.zimbra@u-pem.fr> Hi gang, I think Andreas Stefik has found a bug in com.sun.tools.javac.jvm.ClassReader in the code that parse the LocalVariableTable and try to guess that a variable is a parameter (to have a nice completion in NetBeans i suppose). At line 1068 [1], the code should be int newSize = Math.max(register + 1, parameterNameIndices.length + 8); otherwise the line 1072 will throw an AIOOBE. see this thread on the ASM mailing list for the whole story: http://mail.ow2.org/wws/arc/asm/2015-09/msg00005.html cheers, R?mi http://hg.openjdk.java.net/jdk8u/jdk8u-dev/langtools/file/ebe1e9d17713/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java#l1068 From maurizio.cimadamore at oracle.com Mon Sep 14 10:07:01 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 14 Sep 2015 11:07:01 +0100 Subject: Off by one bug in com.sun/tools.javac.jvm.ClassReader In-Reply-To: <928747990.74160.1442214953793.JavaMail.zimbra@u-pem.fr> References: <928747990.74160.1442214953793.JavaMail.zimbra@u-pem.fr> Message-ID: <55F69C45.6010103@oracle.com> Hi Remi, thanks for the report; filed: https://bugs.openjdk.java.net/browse/JDK-8136453 Maurizio On 14/09/15 08:15, Remi Forax wrote: > Hi gang, > I think Andreas Stefik has found a bug in com.sun.tools.javac.jvm.ClassReader in the code that parse the LocalVariableTable > and try to guess that a variable is a parameter (to have a nice completion in NetBeans i suppose). > > At line 1068 [1], the code should be > int newSize = Math.max(register + 1, parameterNameIndices.length + 8); > otherwise the line 1072 will throw an AIOOBE. > > see this thread on the ASM mailing list for the whole story: > http://mail.ow2.org/wws/arc/asm/2015-09/msg00005.html > > cheers, > R?mi > > http://hg.openjdk.java.net/jdk8u/jdk8u-dev/langtools/file/ebe1e9d17713/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java#l1068 From bsrbnd at gmail.com Mon Sep 14 13:11:36 2015 From: bsrbnd at gmail.com (bsrbnd) Date: Mon, 14 Sep 2015 15:11:36 +0200 Subject: [PATCH] 8129740: Runtime exception when passing lambda in inner class constructor Message-ID: Hi, As explained in issue 8129740, the following code produces a runtime exception ("uninitialized this"): public class Bug { Object vb=new Object(); public class Inner { Object vi=new Object(); public Inner(Runnable r) {r.run();} public Inner(Object o) {System.out.println(o);} public Inner() { this(()->System.out.println(vb)); // KO (bug 8129740 runtime exception) } } public static void main(String[] args) { new Bug().new Inner(); } } class Other { public Object o=new Object(); } With respect to JLS 8.8.7.1 (p. 264, l. 1-4), I think (if I've not missed anything) that this example should probably run without exception because "vb" is not within "Inner" class but in the outer-class. For example, all the following statements compile and run according to jls 8.8.7.1: this(vb); this(()->System.out.println(new Other().o)); this(new Runnable() {public void run() {System.out.println(vb);}}); And the following ones doesn't compile, according to jls: this(vi); this(()->System.out.println(vi)); this(new Runnable() {public void run() {System.out.println(vi);}}); But, if the runtime exception is "right" (as said in issue 8129740), we can detect in the attribute phase the special case of an outer member access within a lambda expression in a this/super call as shown in the following patch. Method Attr.visitLambda() keeps a track in the AttrContext if we are in a this/super call and method Attr.visitIdent() produces an error message for that case (notice that "noOuterThisPath" on line 3209 never changes). Regards, bsrbnd diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2327,6 +2327,7 @@ } //create an environment for attribution of the lambda expression final Env localEnv = lambdaEnv(that, env); + localEnv.info.isLambdaInSelfCall = localEnv.info.isSelfCall; boolean needsRecovery = resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK; try { @@ -3207,6 +3208,7 @@ // (`noOuterThisPath'). Env symEnv = env; boolean noOuterThisPath = false; + boolean isLambdaInSelfCall = symEnv.info.isLambdaInSelfCall; if (env.enclClass.sym.owner.kind != PCK && // we are in an inner class sym.kind.matches(KindSelector.VAL_MTH) && sym.owner.kind == TYP && @@ -3238,7 +3240,7 @@ // In a constructor body, // if symbol is a field or instance method, check that it is // not accessed before the supertype constructor is called. - if ((symEnv.info.isSelfCall || noOuterThisPath) && + if ((symEnv.info.isSelfCall || isLambdaInSelfCall || noOuterThisPath) && sym.kind.matches(KindSelector.VAL_MTH) && sym.owner.kind == TYP && (sym.flags() & STATIC) == 0) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java @@ -72,6 +72,8 @@ * Is this an attribution environment for an instance creation expression? */ boolean isNewClass = false; + + boolean isLambdaInSelfCall = false; /** Are arguments to current function applications boxed into an array for varargs? */ @@ -112,6 +114,7 @@ info.isSpeculative = isSpeculative; info.isAnonymousDiamond = isAnonymousDiamond; info.isNewClass = isNewClass; + info.isLambdaInSelfCall = isLambdaInSelfCall; return info; } From forax at univ-mlv.fr Mon Sep 14 13:18:55 2015 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Mon, 14 Sep 2015 15:18:55 +0200 (CEST) Subject: Off by one bug in com.sun/tools.javac.jvm.ClassReader In-Reply-To: <55F69C45.6010103@oracle.com> References: <928747990.74160.1442214953793.JavaMail.zimbra@u-pem.fr> <55F69C45.6010103@oracle.com> Message-ID: <244302866.437476.1442236735411.JavaMail.zimbra@u-pem.fr> Thank Maurizio ! R?mi ----- Mail original ----- > De: "Maurizio Cimadamore" > ?: "Remi Forax" , compiler-dev at openjdk.java.net > Envoy?: Lundi 14 Septembre 2015 12:07:01 > Objet: Re: Off by one bug in com.sun/tools.javac.jvm.ClassReader > > Hi Remi, > thanks for the report; filed: > > https://bugs.openjdk.java.net/browse/JDK-8136453 > > Maurizio > > On 14/09/15 08:15, Remi Forax wrote: > > Hi gang, > > I think Andreas Stefik has found a bug in > > com.sun.tools.javac.jvm.ClassReader in the code that parse the > > LocalVariableTable > > and try to guess that a variable is a parameter (to have a nice completion > > in NetBeans i suppose). > > > > At line 1068 [1], the code should be > > int newSize = Math.max(register + 1, parameterNameIndices.length + 8); > > otherwise the line 1072 will throw an AIOOBE. > > > > see this thread on the ASM mailing list for the whole story: > > http://mail.ow2.org/wws/arc/asm/2015-09/msg00005.html > > > > cheers, > > R?mi > > > > http://hg.openjdk.java.net/jdk8u/jdk8u-dev/langtools/file/ebe1e9d17713/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java#l1068 > > From aleksey.shipilev at oracle.com Thu Sep 17 11:17:16 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 17 Sep 2015 14:17:16 +0300 Subject: Indify String Concat progress In-Reply-To: <55E95AAB.7050004@oracle.com> References: <55E0E0F1.4090907@oracle.com> <55E95AAB.7050004@oracle.com> Message-ID: <55FAA13C.1000905@oracle.com> On 09/04/2015 11:47 AM, Aleksey Shipilev wrote: > On 08/29/2015 01:30 AM, Aleksey Shipilev wrote: >> I have finally found time to further hack on this: >> https://bugs.openjdk.java.net/browse/JDK-8085796 > > ... > >> Comments, suggestions, etc. are welcome. I am contemplating to "submit" >> the JEP early next week, pending no blockers. > > Thanks for the comments (mostly delivered privately). I have submitted > the JEP. Still looking for comments for a submitted Indy String Concat JEP: https://bugs.openjdk.java.net/browse/JDK-8085796 Or, should I also send this to core-libs-dev@? Thanks, -Aleksey -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From bsrbnd at gmail.com Thu Sep 17 11:46:07 2015 From: bsrbnd at gmail.com (bsrbnd) Date: Thu, 17 Sep 2015 13:46:07 +0200 Subject: [PATCH] 8129740: Runtime exception when passing lambda in inner class constructor In-Reply-To: References: Message-ID: Hi, Just two precisions: 1) If you run the compiled example, a "java.lang.VerifyError (uninitializedThis)" is thrown, not a runtime exception (sorry for that mistake): Exception in thread "main" java.lang.VerifyError: Bad type on operand stack Exception Details: Location: Bug$Inner.(LBug;)V @3: invokedynamic Reason: Type uninitializedThis (current frame, stack[2]) is not assignable to 'Bug$Inner' 2) The output of javap on "Inner" class gives us a good explaination. The lambda expression is translated into an instance method (to access instance members of the class and outer-class) and thus "this" is used by "invokedynamic" before calling the constructor which leads to the VerifiyError: public class Bug$Inner { java.lang.Object vi; final Bug this$0; public Bug$Inner(Bug, java.lang.Runnable); public Bug$Inner(Bug, java.lang.Object); public Bug$Inner(Bug); private void lambda$new$0(); } public Bug$Inner(Bug); Code: 0: aload_0 1: aload_1 2: aload_0 3: invokedynamic #8, 0 // InvokeDynamic #0:run:(LBug$Inner;)Ljava/lang/Runnable; 8: invokespecial #9 // Method "":(LBug;Ljava/lang/Runnable;)V 11: return If the lambda expression doesn't access instance members of the class (but static members or instance members of other classes), the lamda expression is translated into a static method an the "invokedynamic" doesn't need "this". For example: this(()->System.out.println(new Other().o)); gives: public class Bug$Inner { java.lang.Object vi; final Bug this$0; public Bug$Inner(Bug, java.lang.Runnable); public Bug$Inner(Bug, java.lang.Object); public Bug$Inner(Bug); private static void lambda$new$0(); } public Bug$Inner(Bug); Code: 0: aload_0 1: aload_1 2: invokedynamic #8, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; 7: invokespecial #9 // Method "":(LBug;Ljava/lang/Runnable;)V 10: return Thus, jls 8.8.7.1 seems to be respected (the error appears to be "right" in issue 8129740) and then javac should (I think) give an error message as shown in the patch below. Regards, bsrbnd 2015-09-14 15:11 GMT+02:00 bsrbnd : > Hi, > > As explained in issue 8129740, the following code produces a runtime > exception ("uninitialized this"): > > public class Bug { > Object vb=new Object(); > > public class Inner { > Object vi=new Object(); > > public Inner(Runnable r) {r.run();} > public Inner(Object o) {System.out.println(o);} > public Inner() { > this(()->System.out.println(vb)); // KO (bug 8129740 > runtime exception) > } > } > public static void main(String[] args) { > new Bug().new Inner(); > } > } > > class Other { > public Object o=new Object(); > } > > With respect to JLS 8.8.7.1 (p. 264, l. 1-4), I think (if I've not > missed anything) that this example should probably run without > exception because "vb" is not within "Inner" class but in the > outer-class. > > For example, all the following statements compile and run according to > jls 8.8.7.1: > this(vb); > this(()->System.out.println(new Other().o)); > this(new Runnable() {public void run() {System.out.println(vb);}}); > > And the following ones doesn't compile, according to jls: > this(vi); > this(()->System.out.println(vi)); > this(new Runnable() {public void run() {System.out.println(vi);}}); > > But, if the runtime exception is "right" (as said in issue 8129740), > we can detect in the attribute phase the special case of an outer > member access within a lambda expression in a this/super call as shown > in the following patch. > Method Attr.visitLambda() keeps a track in the AttrContext if we are > in a this/super call and method Attr.visitIdent() produces an error > message for that case (notice that "noOuterThisPath" on line 3209 > never changes). > > Regards, > bsrbnd > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java > @@ -2327,6 +2327,7 @@ > } > //create an environment for attribution of the lambda expression > final Env localEnv = lambdaEnv(that, env); > + localEnv.info.isLambdaInSelfCall = localEnv.info.isSelfCall; > boolean needsRecovery = > resultInfo.checkContext.deferredAttrContext().mode == > DeferredAttr.AttrMode.CHECK; > try { > @@ -3207,6 +3208,7 @@ > // (`noOuterThisPath'). > Env symEnv = env; > boolean noOuterThisPath = false; > + boolean isLambdaInSelfCall = symEnv.info.isLambdaInSelfCall; > if (env.enclClass.sym.owner.kind != PCK && // we are in an inner class > sym.kind.matches(KindSelector.VAL_MTH) && > sym.owner.kind == TYP && > @@ -3238,7 +3240,7 @@ > // In a constructor body, > // if symbol is a field or instance method, check that it is > // not accessed before the supertype constructor is called. > - if ((symEnv.info.isSelfCall || noOuterThisPath) && > + if ((symEnv.info.isSelfCall || isLambdaInSelfCall || > noOuterThisPath) && > sym.kind.matches(KindSelector.VAL_MTH) && > sym.owner.kind == TYP && > (sym.flags() & STATIC) == 0) { > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java > @@ -72,6 +72,8 @@ > * Is this an attribution environment for an instance creation expression? > */ > boolean isNewClass = false; > + > + boolean isLambdaInSelfCall = false; > > /** Are arguments to current function applications boxed into an > array for varargs? > */ > @@ -112,6 +114,7 @@ > info.isSpeculative = isSpeculative; > info.isAnonymousDiamond = isAnonymousDiamond; > info.isNewClass = isNewClass; > + info.isLambdaInSelfCall = isLambdaInSelfCall; > return info; > }