[clang] f53f2f2 - Extend ptr32 support to be applied on typedef
Muiez Ahmed via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 9 08:09:21 PDT 2022
Author: Ariel Burton
Date: 2022-08-09T11:08:52-04:00
New Revision: f53f2f232f794a257c270f4c273b9c9000421c81
URL: https://github.com/llvm/llvm-project/commit/f53f2f232f794a257c270f4c273b9c9000421c81
DIFF: https://github.com/llvm/llvm-project/commit/f53f2f232f794a257c270f4c273b9c9000421c81.diff
LOG: Extend ptr32 support to be applied on typedef
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.
Differential Revision: https://reviews.llvm.org/D130123
Added:
Modified:
clang/lib/Sema/SemaType.cpp
clang/test/CodeGen/address-space-ptr32.c
clang/test/Sema/MicrosoftExtensions.c
clang/test/Sema/MicrosoftExtensions.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 11a6715cd9d21..14b2d2e74f3f2 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -7158,17 +7158,25 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
}
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;
+ } else if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(Desugared)) {
+ Desugared = ET->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;
@@ -7189,14 +7197,11 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
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
diff --git a/clang/test/CodeGen/address-space-ptr32.c b/clang/test/CodeGen/address-space-ptr32.c
index a2914e39bee4d..618db6906351d 100644
--- a/clang/test/CodeGen/address-space-ptr32.c
+++ b/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);
+}
diff --git a/clang/test/Sema/MicrosoftExtensions.c b/clang/test/Sema/MicrosoftExtensions.c
index d0ca16269cceb..50077d9031488 100644
--- a/clang/test/Sema/MicrosoftExtensions.c
+++ b/clang/test/Sema/MicrosoftExtensions.c
@@ -173,8 +173,28 @@ int * __ptr32 __ptr32 wrong8; // expected-warning {{attribute '__ptr32' is alrea
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}}
diff --git a/clang/test/Sema/MicrosoftExtensions.cpp b/clang/test/Sema/MicrosoftExtensions.cpp
index cb9ad20486335..d2ce2e200f246 100644
--- a/clang/test/Sema/MicrosoftExtensions.cpp
+++ b/clang/test/Sema/MicrosoftExtensions.cpp
@@ -1,6 +1,5 @@
// RUN: %clang_cc1 -triple i686-windows %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
// RUN: %clang_cc1 -triple x86_64-windows %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
-// expected-no-diagnostics
// Check that __ptr32/__ptr64 can be compared.
int test_ptr_comparison(int *__ptr32 __uptr p32u, int *__ptr32 __sptr p32s,
@@ -9,3 +8,23 @@ int test_ptr_comparison(int *__ptr32 __uptr p32u, int *__ptr32 __sptr p32s,
(p32u == p64) +
(p32s == p64);
}
+
+template<typename T>
+void bad(T __ptr32 a) { // expected-error {{'__ptr32' attribute only applies to pointer arguments}}`
+ (*a) += 1;
+}
+
+template<int size_expected, typename T>
+void f(T a) {
+ (*a) += sizeof(a);
+ static_assert(sizeof(a) == size_expected, "instantiated template argument has unexpected size");
+}
+void g(int *p) {
+ // instantiate for default sized pointer
+ f<sizeof(void*)>(p);
+}
+
+void h(int *__ptr32 p) {
+ // instantiate for 32-bit pointer
+ f<4>(p);
+}
More information about the cfe-commits
mailing list