Ariel-Burton created this revision.
Ariel-Burton added reviewers: akhuang, rnk, rsmith.
Herald added a project: All.
Ariel-Burton requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Earlier, if the QualType was sugared, then we would error out
as it was not a pointer type, for example,

typedef int *int_star;

int_star __ptr32  p;

Now, if ptr32 is given we apply it if the raw Canonical Type
(i.e., the desugared type) is a PointerType, instead of only
checking whether the sugared type is a pointer type.

As before, we still disallow ptr32 usage if the pointer is used
as a pointer to a member.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130123

Files:
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/address-space-ptr32.c
  clang/test/Sema/MicrosoftExtensions.c

Index: clang/test/Sema/MicrosoftExtensions.c
===================================================================
--- clang/test/Sema/MicrosoftExtensions.c
+++ clang/test/Sema/MicrosoftExtensions.c
@@ -173,8 +173,28 @@
 
 int *(__ptr32 __sptr wrong9); // expected-error {{'__sptr' attribute only applies to pointer arguments}} // expected-error {{'__ptr32' attribute only applies to pointer arguments}}
 
+int *(__ptr32 wrong10); // expected-error {{'__ptr32' attribute only applies to pointer arguments}}
+
+int *(__ptr64 wrong11); // expected-error {{'__ptr64' attribute only applies to pointer arguments}}
+
+int *(__ptr32 __ptr64 wrong12); // expected-error {{'__ptr32' attribute only applies to pointer arguments}} // expected-error {{'__ptr64' attribute only applies to pointer arguments}}
+
 typedef int *T;
-T __ptr32 wrong10; // expected-error {{'__ptr32' attribute only applies to pointer arguments}}
+T __ptr32 ok1;
+T __ptr64 ok2;
+T __ptr32 __ptr64 wrong13; // expected-error {{'__ptr32' and '__ptr64' attributes are not compatible}}
+
+typedef int *__ptr32 T1;
+T1 ok3;
+T1 __ptr32 wrong14;  // expected-warning {{attribute '__ptr32' is already applied}}
+T1 __ptr64 wrong15;  // expected-error {{'__ptr32' and '__ptr64' attributes are not compatible}}
+
+typedef int *__ptr64 T2;
+T2 ok4;
+T2 __ptr64 wrong16;  // expected-warning {{attribute '__ptr64' is already applied}}
+T2 __ptr32 wrong17;  // expected-error {{'__ptr32' and '__ptr64' attributes are not compatible}}
+
+typedef int *__ptr32 __ptr64 wrong18; // expected-error {{'__ptr32' and '__ptr64' attributes are not compatible}}
 
 typedef char *my_va_list;
 void __va_start(my_va_list *ap, ...); // expected-note {{passing argument to parameter 'ap' here}}
Index: clang/test/CodeGen/address-space-ptr32.c
===================================================================
--- clang/test/CodeGen/address-space-ptr32.c
+++ clang/test/CodeGen/address-space-ptr32.c
@@ -1,10 +1,40 @@
 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-windows-msvc -fms-extensions -emit-llvm < %s | FileCheck %s
 
+_Static_assert(sizeof(void *) == 8, "sizeof(void *) has unexpected value.  Expected 8.");
+
 int foo(void) {
+  // CHECK: define dso_local i32 @foo
+  // CHECK: %a = alloca i32 (i32) addrspace(270)*, align 4
+  // CHECK: ret i32 4
   int (*__ptr32 a)(int);
   return sizeof(a);
 }
 
-// CHECK: define dso_local i32 @foo
-// CHECK: %a = alloca i32 (i32) addrspace(270)*, align 4
-// CHECK: ret i32 4
+int bar(void) {
+  // CHECK: define dso_local i32 @bar
+  // CHECK: %p = alloca i32 addrspace(270)*, align 4
+  // CHECK: ret i32 4
+  int *__ptr32 p;
+  return sizeof(p);
+}
+
+
+int baz(void) {
+  // CHECK: define dso_local i32 @baz
+  // CHECK: %p = alloca i32 addrspace(270)*, align 4
+  // CHECK: ret i32 4
+  typedef int *__ptr32 IP32_PTR;
+
+  IP32_PTR p;
+  return sizeof(p);
+}
+
+int fugu(void) {
+  // CHECK: define dso_local i32 @fugu
+  // CHECK: %p = alloca i32 addrspace(270)*, align 4
+  // CHECK: ret i32 4
+  typedef int *int_star;
+
+  int_star __ptr32 p;
+  return sizeof(p);
+}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -7111,17 +7111,22 @@
   }
 
   std::bitset<attr::LastAttr> Attrs;
-  attr::Kind NewAttrKind = A->getKind();
   QualType Desugared = Type;
-  const AttributedType *AT = dyn_cast<AttributedType>(Type);
-  while (AT) {
+  for (;;) {
+    if (const TypedefType *TT = dyn_cast<TypedefType>(Desugared)) {
+      Desugared = TT->desugar();
+      continue;
+    }
+    const AttributedType *AT = dyn_cast<AttributedType>(Desugared);
+    if (!AT)
+      break;
     Attrs[AT->getAttrKind()] = true;
     Desugared = AT->getModifiedType();
-    AT = dyn_cast<AttributedType>(Desugared);
   }
 
   // You cannot specify duplicate type attributes, so if the attribute has
   // already been applied, flag it.
+  attr::Kind NewAttrKind = A->getKind();
   if (Attrs[NewAttrKind]) {
     S.Diag(PAttr.getLoc(), diag::warn_duplicate_attribute_exact) << PAttr;
     return true;
@@ -7142,14 +7147,11 @@
     return true;
   }
 
-  // Pointer type qualifiers can only operate on pointer types, but not
-  // pointer-to-member types.
-  //
-  // FIXME: Should we really be disallowing this attribute if there is any
-  // type sugar between it and the pointer (other than attributes)? Eg, this
-  // disallows the attribute on a parenthesized pointer.
-  // And if so, should we really allow *any* type attribute?
+  // Check the raw (i.e., desugared) Canonical type to see if it
+  // is a pointer type.
   if (!isa<PointerType>(Desugared)) {
+    // Pointer type qualifiers can only operate on pointer types, but not
+    // pointer-to-member types.
     if (Type->isMemberPointerType())
       S.Diag(PAttr.getLoc(), diag::err_attribute_no_member_pointers) << PAttr;
     else
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D130123: [Phabricator... Ariel Burton via Phabricator via cfe-commits

Reply via email to