<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 - Undefined behavior in undefined behavior santizer for shifts"
   href="https://bugs.llvm.org/show_bug.cgi?id=44597">44597</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Undefined behavior in undefined behavior santizer for shifts
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>compiler-rt
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </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>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>ubsan
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>cullmann@absint.de
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Hi,

we did some experiments with the shift sanitizer.

For the following code:

int main() {
  signed char c = -2;

  c = c << 4; // Okay integer promotion, sanitizer datastructure says 32-bit
wide operand

  c = -2;

  c <<= 4; // Integer promotion is done, but sanitizer datastructure says 8-bit
wide operand
  // Consequence -> This eventually causes undefined behaviour in
getSIntValue() [Sanitizer Handler Library] since shifting a negative 32-bit
value by (128-8) bits to the left.

  return 0;
}

the second call to the shift sanitizer routine will get a sext32 extended value
but has a getIntegerBitWidth of 8 internally in its data structures.

That will lead to "shift overflow" for the signed shift in:

SIntMax Value::getSIntValue() const {
  CHECK(getType().isSignedIntegerTy());
  if (isInlineInt()) {
    // Val was zero-extended to ValueHandle. Sign-extend from original width
    // to SIntMax.
    const unsigned ExtraBits =
      sizeof(SIntMax) * 8 - getType().getIntegerBitWidth();
    return SIntMax(Val) << ExtraBits >> ExtraBits;
  }

I would propose to change this

return SIntMax(Val) << ExtraBits >> ExtraBits;

to

return SIntMax(UIntMax(Val) << ExtraBits) >> ExtraBits;

to avoid the undefined left shift on a signed value that shifts some bits out.

Or are we confused here?</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>