<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 6/19/2012 7:14 AM, SHIVA PRASAD
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAJh=txJPZA+9D3HRU9ex_yFFcK6pkKHt6vJROEhxCWUO5T=wKw@mail.gmail.com"
      type="cite">Dear LLVM Members,
      <div><br>
        <div>        The below source code from gcc test
          suite replicates the problem which i am facing.  When it is
          built with clang, it throws an <span
            style="background-color:rgb(255,0,0)">abort</span>(highlighted).</div>
        <div>The following are my observations - </div>
        <div><br>
        </div>
        <div>1. The object(tmp) is not getting destroyed immediately
          after the exception is thrown.  In case of Clang, the object
          is getting destroyed at a later point of time.</div>
        <div>2. In case of gcc, the scope of the object created inside
          the try-catch block is limited to the block.  Once the
          exception is thrown, the object(tmp) is destroyed.</div>
        <div>3. The assembly files for both clang and gcc were generated
          and compared, wherein the sequence of operations look similar.</div>
        <div>4. I also tried the MS-Visual Studio compiler, which gives
          a result similar to gcc.</div>
      </div>
    </blockquote>
    <br>
    This looks specific to clang, not to LLVM, so moving to cfe-dev.<br>
    <br>
    [Source code below not elided for anyone on cfe-dev who isn't on
    llvmdev; I have more comments trailing, so scroll down].<br>
    <blockquote
cite="mid:CAJh=txJPZA+9D3HRU9ex_yFFcK6pkKHt6vJROEhxCWUO5T=wKw@mail.gmail.com"
      type="cite">
      <div>
        <div>
          <div>As per my understanding of the C++ standard, the object
            has to be destroyed as soon as the exception is thrown.  </div>
          <div>Please let me know which is the correct behavior and
            suggest me the changes required.</div>
          <div><br>
          </div>
          <div><br>
          </div>
          <div>
            <div>Thanks & Regards,</div>
            <div>Shivaprasad</div>
            <div><a moz-do-not-send="true"
                href="mailto:shivahms@gmail.com">shivahms@gmail.com</a></div>
          </div>
          <div><br>
          </div>
          <div>/******************************************************************Source
            Code
Start*******************************************************************/</div>
          <div>extern "C" void abort ();</div>
          <div><br>
          </div>
          <div>int thrown;</div>
          <div><br>
          </div>
          <div>int as;</div>
          <div>struct a {</div>
          <div>  a () { ++as; }</div>
          <div>  ~a () { --as; if (thrown++ == 0) throw 42; }</div>
          <div>};</div>
          <div><br>
          </div>
          <div>int f (a const&) { return 1; }</div>
          <div>int f (a const&, a const&) { return 1; }</div>
          <div><br>
          </div>
          <div>int bs;</div>
          <div>int as_sav;</div>
          <div>struct b {</div>
          <div>  b (...) { ++bs; }</div>
          <div>  ~b ()   { --bs; as_sav = as; }</div>
          <div>};</div>
          <div><br>
          </div>
          <div>bool p;</div>
          <div>void g()</div>
          <div>{</div>
          <div>  if (p) throw 42;</div>
          <div>}</div>
          <div><br>
          </div>
          <div><span style="background-color:rgb(255,255,102)">int main
              () {</span></div>
          <div><span style="background-color:rgb(255,255,102)">  thrown
              = 0;</span></div>
          <div><span style="background-color:rgb(255,255,102)">  try {</span></div>
          <div><span style="background-color:rgb(255,255,102)">    b
              tmp(f (a(), a()));</span></div>
          <div><span style="background-color:rgb(255,255,102)"><br>
            </span></div>
          <div><span style="background-color:rgb(255,255,102)">    g();</span></div>
          <div><span style="background-color:rgb(255,255,102)">  }</span></div>
          <div><span style="background-color:rgb(255,255,102)">  catch
              (...) {}</span></div>
          <div><br>
          </div>
          <div>  // We throw when the first a is destroyed, which should
            destroy b before</div>
          <div>  // the other a.</div>
          <div>  if (as_sav != 1)</div>
          <div>   <span style="background-color:rgb(255,0,0)"> abort ();</span></div>
          <div><br>
          </div>
          <div>  thrown = 0;</div>
          <div>  try {</div>
          <div>    b tmp(f (a()));</div>
          <div><br>
          </div>
          <div>    g();</div>
          <div>  }</div>
          <div>  catch (...) {}</div>
          <div><br>
          </div>
          <div>  if (bs != 0)</div>
          <div>    abort ();</div>
          <div>}</div>
          <div>/******************************************************************Source
            Code
            End*******************************************************************/</div>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
    What clang is generating can be approximated by the following
    pseudocode:<br>
    atmp1, atmp2, btmp = alloca space for temporaries<br>
    call a::a on atmp1<br>
    try {<br>
      call a::a on atmp2<br>
      try {<br>
        call f(atmp1, atmp2)<br>
        call b::b on btmp<br>
      } catch {<br>
      } finally {<br>
        call a::~a on atmp2<br>
      }<br>
    } catch {<br>
    } finally {<br>
      call a::~a on atmp1<br>
    }<br>
    // NOW b is "constructed"<br>
    <br>
    Looking at the output IR, the best interpretation I can give is that
    Clang is cleaning up the temporary arguments before calling the new
    variable constructed. The question, of course, is whether or not
    this is legal per the C++ spec. C++11 section 12.2, par 3 states
    that<br>
    <blockquote type="cite">Temporary objects are destroyed as the last
      step<br>
      in evaluating the full-expression (1.9) that (lexically) contains
      the point where they were created.</blockquote>
    <br>
    Section 1.9, par 10 has an example which states that the full
    expression associated with the call to the constructor in this case
    is indeed the actual constructor call.<br>
    <br>
    Section 15.2, par 1 states:<br>
    <blockquote type="cite">As control passes from a throw-expression to
      a handler, destructors are invoked for all automatic objects<br>
      constructed since the try block was entered. The automatic objects
      are destroyed in the reverse order of the<br>
      completion of their construction.</blockquote>
    <br>
    I'm not 100% what the correct interpretation is in this case. It
    comes down to whether b should be considered constructed before or
    after the full expression of the declarator is completed.<br>
    <pre class="moz-signature" cols="72">-- 
Joshua Cranmer
News submodule owner
DXR coauthor</pre>
  </body>
</html>