<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 - [MS] Implement full support for __ptr32, __ptr64, __sptr, __uptr"
   href="https://bugs.llvm.org/show_bug.cgi?id=42359">42359</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[MS] Implement full support for __ptr32, __ptr64, __sptr, __uptr
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>8.0
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>Windows NT
          </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>Frontend
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>akhuang@google.com
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>rnk@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Clang parses these qualifiers as attributes, but they don't have any semantic
meaning. A Chromium developer used a Windows typedef that happened to have one
of these qualifiers and ran into issues with it: <a href="https://crbug.com/972185">https://crbug.com/972185</a>

Clang should implement these qualifiers, since we accept them without warning.

Consider this program: 

typedef void *__ptr32 PVOID;
template <typename T> struct Foo { static_assert(sizeof(T) == 4, "asdf"); };
template struct Foo<PVOID>;
void *getp2(PVOID p) {
  static_assert(sizeof(p) == 4, "asdf");
  return *p;
}

Today we retain __ptr32 as sugar, like this:
|-TypedefDecl 0x1b842c987c0 <t.cpp:1:1, col:23> col:23 referenced PVOID 'void *
__ptr32':'void *'
| `-AttributedType 0x1b842c98770 'void * __ptr32' sugar
|   |-PointerType 0x1b842c98180 'void *'
|   | `-BuiltinType 0x1b842c97980 'void'
|   `-PointerType 0x1b842c98180 'void *'
|     `-BuiltinType 0x1b842c97980 'void'

We need to change the canonical type of PVOID to be something other than
'void*', so that the static_asserts pass inside and outside of the template. I
think we could implement this as an address space qualifier on the pointee type
of the pointer, or we could add some other kind of qualifiers.

I believe the qualifiers are ignored if the pointer size matches the default
for the current compilation mode, so Foo<void*> and Foo<void*__ptr64> are the
same in x64. I wonder how the __sptr / __uptr qualifiers are treated.

For codegen, we have to truncate, sign extend, or zero extend when converting
between different kinds of pointers, depending on the __sptr / __uptr
qualifier. I think this roughly corresponds to userspace address, or kernel
address.

I think it makes sense to lower these down to i32 and i64 types as appropriate,
since we need to load and store them and use sign and zero extension on them.</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>