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