Fwd: [jvm-l] Newly introduced OpenJDK javac bug?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 9 07:24:45 PDT 2011


Remi, your analysis is correct.

Consider the method call:

method("str", 1);

Now, you have two potentially applicable methods, namely

- method(String str, int num, Object... data)
- method(String str, Object... data)

Since both are varargs method, both methods can only be applicable by 
variable arity method conversion (see JLS 15.12.2.4). Both methods are 
applicable (note that the second method is applicable since there exist 
a method invocation conversion to go from int to Object).

Since both are applicable we have now to choose the most specific (see 
15.12.2.5) - the rules says that:

"In addition, one variable arity member method named m is more specific 
than another variable arity member method of the same name if either:

*) One member method has n parameters and the other has k parameters, 
where n >= k. The types of the parameters of the first member method are 
T1, . . . , Tn-1 , Tn[], the types of the parameters of the other method 
are U1, . . . , Uk-1, Uk[]. [...] otherwise let Si = Ui, 1 < i <=k. Then:

    - for all j from 1 to k-1, Tj <: Sj, and,
    - for all j from k to n, Tj <: Sk, and,

*) One member method has k parameters and the other has n parameters, 
where n>=k. The types of the parameters of the first method are U1, . . 
. , Uk-1, Uk[], the types of the parameters of the other method are T1, 
. . ., Tn-1, Tn[]. [...] otherwise let Si = Ti, 1 <i <= n. Then:

    - for all j from 1 to k-1 , Uj <: Sj, and,
    - for all j from k to n , Uk <: Sj, and,"

*** Part 1

So, is M1 = method(String str, int num, Object... data) more specific 
than M2 = method(String str, Object... data) ? Since arity of M1 is 
bigger than arity of M2, the first bullet apply. More specifically, n is 
3, k is 2, T = { String, int, Object }, while S = U = { String, Object 
}. We have to prove that:

    - for all j from 1 to 1 (as k is 2), Tj <: Sj, and,
    - for all j from 2 to 3, Tj <: S2, and,

Which means:

j = 1 --> T1 <: S1 ? Yes, because String <: String
j = 1 --> T2 <: S2 ? No, because int is not a subtype of Object

Which means method(String str, int num, Object... data) is not more 
specific than method(String str, Object... data). Let's try the other 
way around.

*** Part 2

So, is M1 = method(String str, Object... data) more specific than M2 = 
method(String str, int i, Object... data) ? Since arity of M1 is smaller 
than arity of M2, the second bullet apply. More specifically, n is 2, k 
is 3, U = { String, Object }, S = T = { String, int, Object }. We have 
to prove that:

    - for all j from 1 to 2 (as k is 3), Uj <: Sj, and,
    - for all j from 3 to 3, Uj <: S3, and,

Which means:

j = 1 --> U1 <: S1 ? Yes, because String <: String
j = 1 --> U2 <: S2 ? No, because int is not a subtype of Object

Which means method(String str, Object... data) is not more specific than 
method(String str, int i, Object... data). The conclusion is that 
neither method is more specific than the other, so the compile-time 
error is legitimate.

Maurizio



On 09/06/11 14:51, Rémi Forax wrote:
> add compiler dev-list to the loop.
>
> My analysis is that this is a fix for a previously existing bug,
> so the behavior of javac is now correct.
>
> With method("str", 1), no method are applicable without considering 
> boxing and varargs,
> so we ends up with phase 3. Here, both boxing and varargs are enabled so
> the two method are applicable and not one is most specific.
> So the call is ambiguous.
>
> Rémi
>
> -------- Original Message --------
> Subject: 	[jvm-l] Newly introduced OpenJDK javac bug?
> Date: 	Thu, 9 Jun 2011 08:26:04 -0500
> From: 	Charles Oliver Nutter <headius at headius.com>
> Reply-To: 	jvm-languages at googlegroups.com
> To: 	JVM Languages <jvm-languages at googlegroups.com>
> CC: 	Mark Reinhold <mark.reinhold at oracle.com>
>
>
>
> Recent OpenJDK 7 builds seem to have introduced a bug into javac.
> Correct me if I'm wrong.
>
> https://gist.github.com/1016436
>
> public class Foo {
>      public static void main(String[] args) {
> 	method("str");
> 	method("str", 1);
> 	method("str", 1, "data");
>      }
>
>      public static void method(String str, int num, Object... data) {
> 	// do nothing
>      }
>
>      public static void method(String str, Object... data) {
> 	// do nothing
>      }
> }
>
> It seems that the order in which it attempts to apply varargs and
> boxing has changed. On OpenJDK/Hotspot 1.6.x and OpenJDK 7 builds
> prior to 143, this compiles fine and calls the first signature for all
> calls. My interpretation of the Java specification is that this is
> correct behavior; the more exact signature that requires no boxing is
> chosen rather than the second signature which does require boxing.
>
> However on later builds, we get the following errors for this case:
>
> Foo.java:4: error: reference to method is ambiguous, both method
> method(String,int,Object...) in Foo and method
> method(String,Object...) in Foo match
> 	method("str", 1);
> 	^
> Foo.java:5: error: reference to method is ambiguous, both method
> method(String,int,Object...) in Foo and method
> method(String,Object...) in Foo match
> 	method("str", 1, "data");
>
> Both invocations fall through to phase 3 of method selection, variable
> arity. But in this case, I believe the first signature (with int)
> should resolve as "more specific" than the second, and should be
> chosen for both invocations. I admit it's a grey area, however, and I
> can't find a specific clause in the Java spec to back me up.
>
> I'm not sure who to talk to about this, or whether I'm right in
> thinking this is a new bug in javac. Thoughts?
>
> - Charlie
>
> -- 
> You received this message because you are subscribed to the Google Groups "JVM Languages" group.
> To post to this group, send email tojvm-languages at googlegroups.com.
> To unsubscribe from this group, send email tojvm-languages+unsubscribe at googlegroups.com.
> For more options, visit this group athttp://groups.google.com/group/jvm-languages?hl=en.
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20110609/4c4490fb/attachment.html 


More information about the compiler-dev mailing list