<div dir="ltr">Hi Richard,<div><br></div><div>Thanks for the reply.</div><div><br></div><div><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jul 7, 2014 at 9:38 AM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div><div class="h5">On Tue, Jul 1, 2014 at 2:22 AM, suyog sarda <span dir="ltr"><<a href="mailto:sardask01@gmail.com" target="_blank">sardask01@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div><div>
<div><div>Hi,<br><br></div>This is a gcc test case<br><br><i>extern "C" int printf (const char *, ...);<br>
<br>int c;<br>int r;<br><br>struct A<br>{<br>
A() { printf ("A()\n"); if (c++) r = 1; }<br> A(const A&) { printf ("A(const A&)\n"); ++c; }<br> ~A() { printf ("~A()\n"); --c; }<br>};<br><br>struct B<br>{<br> B(int, const A& = A()) { printf ("B()\n"); }<br>
};<br><br>int main()<br>{<br> B b[] = { 0, 1 };<br> return r;<br>}</i><br><br></div>Output from Clang (latest trunk):<br><br><i>A()<br>B()<br>A()<br>B()<br>~A()<br>~A()</i><br><br></div>Output from gcc 4.8 :<br><br><i>A()<br>
B()<br>~A()<br>A()<br>B()<br>~A() </i><br><br></div>As we can see, the destructor of temporary objects are not called immediately in case of clang.<br>The temporary A passed to the constructor for b[0] should have been destroyed before going on to construct b[1]. <br>
<br></div>According to standards,<br></div><br clear="all">The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:<br>
— A temporary bound to a reference member in a constructor’s ctor-initializer ( 12.6.2) persists until the constructor exits.<br>— A temporary bound to a reference parameter in a function call ( 5.2.2) persists until the completion of the full-expression containing the call.<br>
<br></div>So even though A's temporary is bound to reference, it should get destroyed as soon as b[0] gets constructed before going forward to construct b[1].<br></div></div></div></div></div></blockquote><div><br></div>
</div></div><div>We (incorrectly, per the C++ standard) treat top-level aggregate initialization as a full-expression. However, I'm not entirely convinced that this is a bug in Clang rather than a bug in the standard, especially in C++11. As a demonstration of why this might be a standard defect:</div>
<div><br></div><div>typedef B BA[];</div><div><br></div><div>void f() {</div><div> BA x = { 1, 2 }; // A(), B(), ~A(), A(), B(), ~A()</div><div> auto &&y = BA { 1, 2 }; // A(), B(), A(), B(), ~A(), ~A()</div><div>
} // ~B(), ~B(), ~B(), ~B()</div><div class=""><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div><div><div><div></div>This seems similar to <a href="http://llvm.org/bugs/show_bug.cgi?id=16476" target="_blank">http://llvm.org/bugs/show_bug.cgi?id=16476</a></div>
</div></div></div></blockquote><div><br></div></div><div>It looks similar, but I think they're completely separate. That issue is about end-of-scope cleanups and interleaving of lifetime-extended temporaries with array elements. In this case, there is no lifetime-extension.</div>
</div></div></div></blockquote><div><br></div><div>Even i noted while debugging that when it checks for lifetime extension, it returns a nullptr, which indicates, it isn't extending lifetime of the temporary.<br></div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div class="">
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div>Richard, any comment/help on this from you will be most welcomed (Since bug 16476 was filed by you :)). Does this require major change in code and handling of temporaries?<br>
</div></div></div></blockquote><div><br></div></div><div>It would probably be straightforward to track where the full-expression boundaries actually are during IR generation. As noted above, I'm not yet convinced that Clang is the right place to fix this. =)</div>
</div></div></div></blockquote><div><br></div><div>I will try to look into IR generation and update if any new findings on this. </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div class="">
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div></div>Is this also related to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1634" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1634</a> ?</div>
</div></blockquote><div><br></div></div><div>Not in this instance, but there are nearby issues that are related (in particular, destruction order if a temporary's destructor throws). </div></div></div></div>
</blockquote></div><br>Thanks for your valuable review. :)<br clear="all"><div><br></div>-- <br>With regards,<br>Suyog Sarda<br>
</div></div>