Bug 14966 – Comparing two std.xml.Document result in infinite recursion

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-08-26T19:45:00Z
Last change time
2016-04-05T14:02:47Z
Keywords
pull
Assigned to
nobody
Creator
doob

Comments

Comment #0 by doob — 2015-08-26T19:45:26Z
Comment #1 by dlang-bugzilla — 2015-09-01T10:56:23Z
Please post a simple test case, sample stack trace... this is not a good bug report.
Comment #2 by doob — 2015-09-01T13:58:31Z
It's so obvious, that's why I didn't provide a test case. The content of the XML doesn't matter. I added a test case with a stack trace at the bottom. I think the issue is that implementation of Document.opEquals: override bool opEquals(Object o) { const doc = toType!(const Document)(o); return (prolog != doc.prolog ) ? false : ( (super != cast(const Element)doc) ? false : ( (epilog != doc.epilog ) ? false : ( true ))); } I suspect the issue is the super call. I'm guessing since the implementation of ==/!= was changed to call object.opEquals, which then calls opEquals on the object. The object will be dynamically resolved to Document and then call Document.opEquals again, resulting in infinite recursion. I was planning to ask about this in the newsgroup if this is a regression but forgot about it. Test case: $ cat main.d import std.xml; void main() { auto xml = ` <?xml version="1.0" encoding="UTF-8"?> <foo></foo> `; auto a = new Document(xml); auto b = new Document(xml); auto c = a == b; } $ dmd main.d && lldb main (lldb) target create "main" Current executable set to 'main' (x86_64). (lldb) r Process 68379 launched: '/Users/jacob/development/d/main' (x86_64) Process 68379 stopped * thread #1: tid = 0x4ad39f, 0x00000001000156f4 main`_d_isbaseof2 + 8, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7fff5f3fffa8) frame #0: 0x00000001000156f4 main`_d_isbaseof2 + 8 main`_d_isbaseof2: -> 0x1000156f4 <+8>: pushq %rbx 0x1000156f5 <+9>: pushq %r12 0x1000156f7 <+11>: pushq %r13 0x1000156f9 <+13>: pushq %r14 (lldb) bt * thread #1: tid = 0x4ad39f, 0x00000001000156f4 main`_d_isbaseof2 + 8, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7fff5f3fffa8) * frame #0: 0x00000001000156f4 main`_d_isbaseof2 + 8 frame #1: 0x00000001000156d1 main`_d_dynamic_cast + 45 frame #2: 0x00000001000361b8 main`D3std3xml31__T6toTypeTxC3std3xml8DocumentZ6toTypeFC6ObjectZxC3std3xml8Document + 20 frame #3: 0x00000001000322f9 main`D3std3xml8Document8opEqualsMxFC6ObjectZb + 21 frame #4: 0x0000000100001a59 main`D6object8opEqualsFC6ObjectC6ObjectZb + 109 frame #5: 0x00000001000019e5 main`D6object8opEqualsFxC6ObjectxC6ObjectZb + 13 frame #6: 0x0000000100032334 main`D3std3xml8Document8opEqualsMxFC6ObjectZb + 80 frame #7: 0x0000000100001a59 main`D6object8opEqualsFC6ObjectC6ObjectZb + 109 frame #8: 0x00000001000019e5 main`D6object8opEqualsFxC6ObjectxC6ObjectZb + 13 frame #9: 0x0000000100032334 main`D3std3xml8Document8opEqualsMxFC6ObjectZb + 80 frame #10: 0x0000000100001a59 main`D6object8opEqualsFC6ObjectC6ObjectZb + 109 . . . frame #196537: 0x0000000100001a59 main`D6object8opEqualsFC6ObjectC6ObjectZb + 109 frame #196538: 0x0000000100001236 main`_Dmain + 102 frame #196539: 0x0000000100016b1c main`D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv + 40 frame #196540: 0x0000000100016a61 main`D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 45 frame #196541: 0x0000000100016ac1 main`D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 45 frame #196542: 0x0000000100016a61 main`D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 45 frame #196543: 0x00000001000169d4 main`_d_run_main + 504 frame #196544: 0x0000000100001254 main`main + 20 frame #196545: 0x00007fff9a0295c9 libdyld.dylib`start + 1 frame #196546: 0x00007fff9a0295c9 libdyld.dylib`start + 1 (lldb)
Comment #3 by dlang-bugzilla — 2015-09-01T14:01:30Z
(In reply to Jacob Carlborg from comment #2) > It's so obvious, that's why I didn't provide a test case. Ideally, bug reports should contain enough information so that people unfamiliar with the code in question could reproduce the problem - this is so anyone can check whether the bug has been fixed in the meanwhile, check if it's a regression, reduce the test case to a minimum one etc.
Comment #4 by r.sagitario — 2016-04-03T16:35:33Z
Comment #5 by dfj1esp02 — 2016-04-04T10:07:12Z
(In reply to Jacob Carlborg from comment #2) > I suspect the issue is the super call. I'm guessing since the implementation > of ==/!= was changed to call object.opEquals, which then calls opEquals on > the object. Awww, when?
Comment #6 by r.sagitario — 2016-04-04T18:26:19Z
> Awww, when? I don't think this has to do with how Object.opEqual is called. The offending lines were changed a number of times, but I'd say none of them worked correctly (or there must have been a compiler change regarding super.calls). I suspect the bug is also in the original commit from 2008.
Comment #7 by github-bugzilla — 2016-04-05T14:02:46Z