<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 - std::make_signed and std::make_unsigned don't work for _ExtInt types"
   href="https://bugs.llvm.org/show_bug.cgi?id=51083">51083</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::make_signed and std::make_unsigned don't work for _ExtInt types
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>All
          </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>All Bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>richard-llvm@metafoo.co.uk
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>std::is_integral, std::is_signed, std::is_unsigned, std::integral,
std::unsigned_integral all work for _ExtInt types, because they use compiler
intrinsics.

But std::make_signed and std::make_unsigned are implemented directly in libc++
via a hard-coded list of remappings instead. They end up (approximately) using
the rules for enum types and character types, picking the lowest rank standard
integer type with the same size as the given type. This, for example, picks
`signed char` when given `unsigned _ExtInt(3)` and fails when given `unsigned
_ExtInt(129)`.

That seems like the wrong outcome to me, and is inconsistent with the behavior
of std::is_signed and friends. I think make_[un]signed should treat _ExtInt as
being a signed integer type and should treat unsigned _ExtInt as being an
unsigned integer type, so make_signed_t<unsigned _ExtInt(N)> should yield
_ExtInt(N) and symmetrically for make_unsigned_t.

Presumably we should add compiler intrinsics __make_signed and __make_unsigned
and use them from libc++ so that extended integer types can be made to behave
properly.</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>