<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>