Compiler bug?
mpark
Posts: 1,305
Can anyone explain why this program prints "666 666" instead of "1234 666" as I expected?
I thought bug0._1234 would call bug1._1234 which would return 1234, not 666. Am I wrong?
Looking at the bytecode I see two copies of the "bug2" object and no "bug0" objects, so the
bug0._1234 call actually ends up being a call to bug2._666. It seems to me that the compiler,
in its zeal to eliminate duplicate objects, has mistakenly determined that "bug0" and "bug2"
are the same. However, the last time I suspected a compiler bug, I was wrong, so I'm not
even going to bring up the possibility of the compiler being at fault here.
I've attached a project archive.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Michael Park
PS, BTW, and FYI:
To search the forum, use search.parallax.com (do not use the Search button).
Check out the Propeller Wiki: propeller.wikispaces.com/
I thought bug0._1234 would call bug1._1234 which would return 1234, not 666. Am I wrong?
Looking at the bytecode I see two copies of the "bug2" object and no "bug0" objects, so the
bug0._1234 call actually ends up being a call to bug2._666. It seems to me that the compiler,
in its zeal to eliminate duplicate objects, has mistakenly determined that "bug0" and "bug2"
are the same. However, the last time I suspected a compiler bug, I was wrong, so I'm not
even going to bring up the possibility of the compiler being at fault here.
I've attached a project archive.
' buggy.spin CON _clkmode = xtal2 + pll8x ' Enable external clock range 5-10MHz and pll times 8. _xinfreq = 10_000_000 + 0000 ' Set frequency to 10 MHz. OBJ term : "pc_text" bug0 : "bug0" bug2 : "bug2" PUB Start term.start(12) [b]term.dec( bug0._1234 ) '<== Expected 1234, got 666[/b] term.out( " " ) term.dec( bug2._666 )
' bug0.spin OBJ bug_ : "bug1" bug1 : "bug1" PUB _1234 return bug1._1234
' bug1.spin PUB _1234 return 1234
' bug2.spin OBJ bug3 : "bug3" bug4 : "bug4" PUB _666 return bug4._666
' bug3.spin PUB Start return 1234
' bug4.spin OBJ bug3 : "bug3" PUB _666 return 666
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Michael Park
PS, BTW, and FYI:
To search the forum, use search.parallax.com (do not use the Search button).
Check out the Propeller Wiki: propeller.wikispaces.com/
Comments
Looking at only the method bytecode, object 0 and 2 are the same. I wonder if the compiler uses some form of hash to perform duplicate reduction and has missed something blindingly obvious ?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pull my finger!
In reality such a situation would be very unlikely. If you expect such a situation, you may need to make the two module bytecodes
different explicity, e.g. by adding deffering CON decalarations to both (kind of a module ID).
Adrian
As BradC says, the bytecode of Bug0 and Bug2 are exactly the same - both are "call the first
method of the second sub-object - and it does look like the compiler or linker has decided these
are the same so only one or the other needs to be referenced in the top-level program.
That suggests that when the compiler or linker is comparing objects to optimise away duplicates,
it compares only the actual bytecode of the object itself, not how it would be when linked with its
own sub-objects. However, when I tried different programs which should show the same flaw
they didn't.
There seems to be something about this particular code which causes the strange behaviour. I've
no idea what though.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Michael Park
PS, BTW, and FYI:
To search the forum, use search.parallax.com (do not use the Search button).
Check out the Propeller Wiki: propeller.wikispaces.com/
I believe you've got the explanation. My understanding is that the compiler looks at the generated byte codes, that's all. Admittedly, this is a degenerate example and would be difficult to duplicate with any "real" objects, but it at least needs to be formally documented.
exactly the same ( excluding X1sub.Spin and X2sub.Spin ). Something with the way the
objects are nested in the OP's post must be why that doesn't work.
One thing seems certain, though: a thorough test could really get messy!
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
I did try changing the names to _1234 and _666 just in case but no difference.
Going back to the OP's code, the Pc_Term object can be removed ( using result := instead) and OBJ bug3 : "bug3" in Bug4.spin can also be removed and the problem still remains. That gives an object tree of ...
That points to a correlation between Bug1 and Bug3 as the trigger. So I then tried this ...
That also fails to generate correct code, but only when BugX returns 1234, return 0 and code is okay. Bug4 can also be anything ( other than 1234 when object optimisation would be legit ). Fair enough, Bug1 and BugX are synonymous so one of those two can be optimised, so simplified ...
That too generates incorrect code, so why are Bug0 and Bug2 considered the same ? The really strange thing is that code for both Bug0 and Bug2 are included in the image, but the call to Bug2 has been replaced by a call to Bug0 in the method link table, so the compiler knows Bug2 hasn't been fully optimised away or it wouldn't include it.
Looking at the bytecode for just Bug0 and Bug2 method, that's the same no matter what optimisations are done by the compiler in all the testing so it has to be something else which causes the objects to be sometimes be considered synonymous and other times not.
Post Edited (hippy) : 8/9/2008 3:09:15 PM GMT
This generates correct code ...
Could it simply be that when comparing images for sub-objects when there's more than one the last sub-object isn't being included in the comparison ?
Post Edited (hippy) : 8/9/2008 3:02:50 PM GMT
I think some oddities were found before, but I think they were all design intents; I suspect this
particular case is a legitimate fencepost error.
If it were detailed in the manual what that actually did and it did indeed do that I'd accept it as a "trap" rather than a bug.
Post Edited (hippy) : 8/9/2008 4:26:38 PM GMT
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!