Summary: | [1.5][compiler] Bad bytecode generated with varargs + generics | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Product: | [Eclipse Project] JDT | Reporter: | Osvaldo Pinali Doederlein <opinali> | ||||||||
Component: | Core | Assignee: | Philipe Mulet <philippe_mulet> | ||||||||
Status: | CLOSED FIXED | QA Contact: | |||||||||
Severity: | major | ||||||||||
Priority: | P3 | CC: | thanson | ||||||||
Version: | 3.1 | ||||||||||
Target Milestone: | 3.1 RC2 | ||||||||||
Hardware: | PC | ||||||||||
OS: | Windows 2000 | ||||||||||
Whiteboard: | |||||||||||
Attachments: |
|
Description
Osvaldo Pinali Doederlein
2005-06-09 16:31:33 EDT
FYI, I just re-tested with I20050609-1228, bug is still there. Thre is another important detail: the bug depends on the types of all variable arguments in some odd way. For example, audit("osvaldo", "localhost", "logged", "X", "Y"); audit("osvaldo", "localhost", "logged", new Float(0), new java.awt.Point(0)); will both compile correctly. The first call is OK, maybe just because all variable arguments are the same type. But in the second call, there are args of different types, and the compiler works too. The suspect cause is that the compilers is confused only when the vararg list begins with an argument that has the same type as the last non-variable argument. This is the case of all places in my app code where this bug happened, and it surely explains why the bug is very rare, and may hint at the root cause: perhaps some problem in disambiguation of fixed vs. variable arguments, plus the generics factor... Created attachment 22762 [details]
Apply on HEAD
Proposed fix.
Philippe, please verify the part with Scope.greaterLowerBound(bounds)[0].
I get a code gen similar to what javac is doing.
And it runs fine.
Created attachment 22763 [details]
Apply on HEAD
Regression test
Created attachment 22764 [details]
Apply on HEAD
New patch that is using locals to acces bounds.
I suspect this is not the proper fix. The wildcard represents here an intersection type, and the glb there is ignoring the first bound which could carry useful information. I believe, it should rather simply use the erasure when generating arguments. We would result in constructing an Object[] here, which is fine as it is all the method is expecting anyway. My fix would rather be to use the expected type from codegen binding varargs type, i.e. in Statement#generateArguments, introduce 'codeGenVarArgsType' and used it for #newArray(...) invocations. ArrayBinding varArgsType = (ArrayBinding) params[varArgIndex]; // parameterType has to be an array type ArrayBinding codeGenVarArgsType = (ArrayBinding) binding.original().parameters[varArgIndex].erasure(); Released VarargsTest#test30 (from patch). Fixed in latest. Just wondering... there is one subtle aspect of ths bug that you may want to consider as a separate bug: the fact that the compiler's classfile assembling phase agreed to write a .class with an invalid entry in the constant pool - const #22 = Asciz ; const #23 = class #22; // "" AFAIK a class named "" is not possible in any circumstances, not even for synthetic or obfuscated code. If the code that writes the classfile would validate this, it would flag the problem instead of covering bugs from the front-end compiler and silently producing a invalid, unverifiable classfile. Our infrastructure relies on the compiler to behave. Checking for this rare situation to occur would penalize normal compilation. Though I agree it would help finding bugs in general. I see. Perhaps a good case for asserts, since Eclipse 3.0+ requires J2SE 1.4+? When reporting bugs like this one and also bug 97440, it takes a reasonable effort to produce a good bug report including test code that's simple, easy to reproduce, and doesn't carry much code that cannot be disclosed publicly... so it'd be nice if I could run Eclipse with -vmargs:ea, even if 10X slower, and get some clues. Verify in I20050610-1200. Closing. *** Bug 108497 has been marked as a duplicate of this bug. *** |