<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Excessive copying of temporaries on ARM"
   href="http://llvm.org/bugs/show_bug.cgi?id=19924">19924</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Excessive copying of temporaries on ARM
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.4
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>llvm-bugs@quasiparticle.net
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Some code seems to confuse clang/LLVM massively under arm-none-eabi with
-ffreestanding. The code below allocates three temporaries on the stack and
copies from one to another, on all optimization levels.

This behaviour is not triggered under a number of slightly different
configurations:

 * no -ffreestanding, or for x86, or x86_64
 * T::status is larger than char
 * Struct::set cpy is Struct, not Struct&&
 * main x is allocated as x{}, x{{0,0}} or anything else, with or without x.x.*
writes
 * set called at most twice
 * set doesn't write cpy.x.status
 * T::status is preceded by another char member
 * or two
 * or by a short, but not a short and a char

I'm pretty sure there's a lot more in here that can flip this around. I've gone
through the standard am I'm convinced that this piece of code does not exhibit
undefined behaviour, and since clang does the right thing(tm) under a lot of
different circumstances, I think this is actually a corner case of some
optimizer pass.

Code:


struct T {
    void* p;
    char status;

    T() : p(0), status(0) {}
};

struct Struct {
    T x;

    Struct set()
    {
        auto&& cpy = Struct(*this);
        cpy.x.status++;
        return cpy;
    }
};

int main()
{
    Struct x;

    x.set().set().set();

    return 0;
}</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>