<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Nov 7, 2013, at 7:43 AM, Timur Iskhodzhanov <<a href="mailto:timurrrr@google.com">timurrrr@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Hi John,<br><br>I've noticed Clang doesn't devirtualize all vcalls in ctors/dtors.<br></div></blockquote><div dir="auto"><br></div>This sounds bad, please file a bugzilla!</div><div dir="auto"><br></div><div dir="auto">-Chris</div><div dir="auto"><br><blockquote type="cite"><div style="font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>e.g. for this code:<br>--------------------------<br>struct A { virtual void a(); };<br>struct B { virtual void b(); };<br>struct C : virtual A, virtual B {<br> C();<br> virtual void key_function();<br> virtual void a();<br> virtual void b();<br>};<br><br>C::C() { a(); b(); }<br>void C::key_function() {}<br>--------------------------<br>the assembly for C::C() at -O3 is<br>--------------------------<br>_ZN1CC1Ev: # complete ctor<br> pushq %rbx<br> movq %rdi, %rbx<br> movq $_ZTV1C+40, (%rbx)<br> movq $_ZTV1C+88, 8(%rbx)<br> callq _ZN1C1aEv # call to C::a is devirtualized<br> movq (%rbx), %rax<br> movq %rbx, %rdi<br> popq %rbx<br> jmpq *16(%rax) # call to C::b is not!<br>...<br>_ZN1CC2Ev: # base ctor<br> pushq %rbx<br> movq %rdi, %rbx<br> movq (%rsi), %rax<br> movq %rax, (%rbx)<br> movq 8(%rsi), %rcx<br> movq -32(%rax), %rax<br> movq %rcx, (%rbx,%rax)<br> movq 16(%rsi), %rax<br> movq (%rbx), %rcx<br> movq -40(%rcx), %rcx<br> movq %rax, (%rbx,%rcx)<br> movq (%rbx), %rax<br> callq *(%rax) # looks like even C::a is not devirtualized<br> movq (%rbx), %rax<br> movq %rbx, %rdi<br> popq %rbx<br> jmpq *16(%rax) # call C::b is not devirtualized<br>--------------------------<br>The same pattern holds if I define C::C() as "b(); a();" - only the<br>first vcall in the complete ctor is devirtualized.<br><br>Does this look like a bug to you?<br>GCC devirtualizes all four calls in this example...<br><br>I also have a somewhat related ABI question.<br>Is there any reason to keep virtual this-adjusting thunks in the<br>vtable when the class is fully constructed?<br>I think all the offsets between bases are known statically at the end<br>of the complete object constructor, so a special "final vtable" with<br>only static this adjusting thunks can be used instead of a regular<br>vtable?<br>Am I missing something?<br><br>--<br>Thanks,<br>Timur<br>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></div></blockquote></div><br></body></html>