<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - Stackcoloring and setjmp/longjmp can miscompile"
   href="https://bugs.llvm.org/show_bug.cgi?id=45489">45489</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Stackcoloring and setjmp/longjmp can miscompile
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </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>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>diogo.sampaio@arm.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=23339" name="attach_23339" title="C Source reproducer and log files">attachment 23339</a> <a href="attachment.cgi?id=23339&action=edit" title="C Source reproducer and log files">[details]</a></span>
C Source reproducer and log files

If I do understand the attached MIR dumps, there is a bug in Stackcoloring by
merging variables alive before and after the longjmp call.

The relevant part of the C++ code is this one:
signed int main(void) {
  {
    S37 P0;         <= This variable shares stack slot with S18 P1 way below.
Ps: The initialization gets inlined.
    jmp_buf jb1;
    if (!setjmp(jb1)) {
      bar(jb1, P0); <= The pointer is incremented by 72 due the copy. function
bar is has a noreturn attribute and it just calls longjmp.
    }
  }
  {
    char *V6 = (char *)alloca(128);
    __asm volatile("" : : "r"(V6));
  }

  {
    __attribute((aligned(16))) char V7[16];
    __asm volatile("" : : "r"(&V7[0]));
  }

  __asm volatile("" : : "r"(__builtin_return_address(0)));

  S18 P1; <= Although the initialization is inligned, it still writes to the
correct address, thanks to Local Stack Slot Allocation and that it does not
write to the beginning of the variable.
  jmp_buf jb2;
  if (!setjmp(jb2)) {
    foo(jb2, P1); <= When making the copy of P1, it decides that is is the same
slot of S37. When reading P1, it is 72 bytes misaligned and reads just trash.
foo also has attribute noreturn.
  }

  return 0;
}


But this is the overall idea of the issue:
>From what I see, Stackcoloring merges two local objects into a single slot.
Object S37 is alive before the call of longjmp and object S18 is alive after
calling longjmp. The fact that bar has attribute noreturn allows optimizations
to the copy of S18. Thus, the variable holding the pointer to the shared stack
pointer slot is incremented during the copy to call bar. Function bar calls
longjmp, but as such changes to the shared slot pointer are recorded in the
spilled stack, it's value is not restored with the longjmp call. After that,
the object pointer to access S37 is misaligned by the size of the S18. That can
only be detected because S18 initialization does not write to the beginning of
the struct, so it uses a different variable as pointer (defined by Local Stack
Slot Allocation), and it is not spilled.

The before and after MIR for Stackcoloring, Local Stack Slot Allocation and
greedy register allocation are attached.


Trigging this fault is quite complicated, my reproducer mixes lto and no-lto
compiled files. Source files and build script, assuming you have required
aarch64 libraries in place, are attached.


=== Obs:
Disabling inlining or Local Stack Slot Allocation as well removes the error,
but solely because it avoids spillings. The noreturn attribute in bar is
important, as it allows the compiler to increment the pointer of P0 when doing
a copy, as no further use of it is known.</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>