Skip to content

Commit 24f33cd

Browse files
committed
Add tests for constexpr, lambda, and concept
Check that ptrauth qualifiers match exactly in qualification conversion.
1 parent 02299cb commit 24f33cd

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

clang/lib/Sema/SemaOverload.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3657,6 +3657,10 @@ static bool isQualificationConversionStep(QualType FromType, QualType ToType,
36573657
ToQuals.removeObjCGCAttr();
36583658
}
36593659

3660+
// __ptrauth qualifiers must match exactly.
3661+
if (FromQuals.getPointerAuth() != ToQuals.getPointerAuth())
3662+
return false;
3663+
36603664
// -- for every j > 0, if const is in cv 1,j then const is in cv
36613665
// 2,j, and similarly for volatile.
36623666
if (!CStyle && !ToQuals.compatiblyIncludes(FromQuals, Ctx))

clang/test/SemaCXX/ptrauth-qualifier.cpp

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -triple arm64-apple-ios -std=c++11 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
2-
// RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c++11 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
1+
// RUN: %clang_cc1 -triple arm64-apple-ios -std=c++20 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
2+
// RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c++20 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
33

44
#define AQ __ptrauth(1,1,50)
55
#define AQ2 __ptrauth(1,1,51)
@@ -140,3 +140,57 @@ int test_call_diag() {
140140
test_bad_call_diag(&ptr3); // expected-error {{no matching function for call to 'test_bad_call_diag'}}
141141
test_bad_call_diag2(&ptr1); // expected-error {{no matching function for call to 'test_bad_call_diag2'}}
142142
}
143+
144+
namespace test_constexpr {
145+
constexpr int i = 100;
146+
constexpr const int * AQ p = &i;
147+
constexpr const int * const AQ *pp = &p;
148+
constexpr int i1 = **((const int * const AQ *)pp);
149+
constexpr int i2 = **((const int * const AQ2 *)pp);
150+
// expected-error@-1 {{constexpr variable 'i2' must be initialized by a constant expression}}
151+
// expected-note@-2 {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
152+
}
153+
154+
namespace test_lambda {
155+
void test() {
156+
int * AQ v0;
157+
int * AQ *v1;
158+
159+
[v0, v1]() {
160+
static_assert(__is_same(decltype(v0), int * AQ));
161+
static_assert(__is_same(decltype(v1), int * AQ *));
162+
}();
163+
164+
[v2 = v0, v3 = v1]() {
165+
static_assert(__is_same(decltype(v2), int *));
166+
static_assert(__is_same(decltype(v3), int * AQ *));
167+
}();
168+
}
169+
}
170+
171+
namespace test_concept {
172+
template <typename T> struct is_qualified {
173+
static constexpr bool value = false;
174+
};
175+
176+
template <typename T> struct is_qualified<T * AQ> {
177+
static constexpr bool value = true;
178+
};
179+
180+
template <typename T>
181+
concept Ptrauthable = is_qualified<T>::value;
182+
// expected-note@-1 {{because 'is_qualified<int *>::value' evaluated to false}}
183+
// expected-note@-2 {{because 'is_qualified<int *__ptrauth(1,1,51)>::value' evaluated to false}}
184+
185+
template <typename T>
186+
requires(Ptrauthable<T>)
187+
struct S {};
188+
// expected-note@-2 {{because 'int *' does not satisfy 'Ptrauthable'}}
189+
// expected-note@-3 {{because 'int *__ptrauth(1,1,51)' does not satisfy 'Ptrauthable'}}
190+
191+
S<int * AQ> s0;
192+
S<int *> s1;
193+
// expected-error@-1 {{constraints not satisfied for class template 'S' [with T = int *]}}
194+
S<int * AQ2> s1;
195+
// expected-error@-1 {{constraints not satisfied for class template 'S' [with T = int *__ptrauth(1,1,51)]}}
196+
}

0 commit comments

Comments
 (0)