<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><span class="vcard"><a class="email" href="mailto:rnk@google.com" title="Reid Kleckner <rnk@google.com>"> <span class="fn">Reid Kleckner</span></a>
</span> changed
          <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED INVALID - Assignment to struct passed by value modifies caller's stack frame"
   href="https://bugs.llvm.org/show_bug.cgi?id=33075">bug 33075</a>
          <br>
             <table border="1" cellspacing="0" cellpadding="8">
          <tr>
            <th>What</th>
            <th>Removed</th>
            <th>Added</th>
          </tr>

         <tr>
           <td style="text-align:right;">CC</td>
           <td>
                
           </td>
           <td>rnk@google.com
           </td>
         </tr>

         <tr>
           <td style="text-align:right;">Status</td>
           <td>NEW
           </td>
           <td>RESOLVED
           </td>
         </tr>

         <tr>
           <td style="text-align:right;">Resolution</td>
           <td>---
           </td>
           <td>INVALID
           </td>
         </tr></table>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED INVALID - Assignment to struct passed by value modifies caller's stack frame"
   href="https://bugs.llvm.org/show_bug.cgi?id=33075#c1">Comment # 1</a>
              on <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED INVALID - Assignment to struct passed by value modifies caller's stack frame"
   href="https://bugs.llvm.org/show_bug.cgi?id=33075">bug 33075</a>
              from <span class="vcard"><a class="email" href="mailto:rnk@google.com" title="Reid Kleckner <rnk@google.com>"> <span class="fn">Reid Kleckner</span></a>
</span></b>
        <pre>This is correct behavior. The caller should not expect arguments passed in
memory to retain their original values, just as it would not expect the
argument registers to be preserved.

GCC does the same thing:
<a href="https://godbolt.org/g/vZybVN">https://godbolt.org/g/vZybVN</a>

I had to modify the example to escape 's' to preserve the dead store of 666.

ABIs have been this way forever. Legacy ABIs (32-bit x86) pass all arguments in
memory, and for those ABIs, compilers typically store to argument memory at
-O0. They don't do a copy.

Consider:

$ echo 'void f(int a) { ++a; }' | gcc -x c - -m32 -S -o -
        .file   ""
        .text
        .globl  _f
        .def    _f;     .scl    2;      .type   32;     .endef
_f:
        pushl   %ebp
        movl    %esp, %ebp
        addl    $1, 8(%ebp)
        nop
        popl    %ebp</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>