Skip to content

Commit 6767751

Browse files
committed
Update style, and increase test coverage
1 parent 1c541ff commit 6767751

File tree

2 files changed

+85
-16
lines changed

2 files changed

+85
-16
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,27 +1829,30 @@ static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call) {
18291829
static ExprResult GetVTablePointer(Sema &S, CallExpr *Call) {
18301830
if (S.checkArgCount(Call, 1))
18311831
return ExprError();
1832-
ExprResult ThisArg = S.DefaultFunctionArrayLvalueConversion(Call->getArg(0));
1833-
if (ThisArg.isInvalid())
1832+
Expr *ThisArg = Call->getArg(0);
1833+
ExprResult ThisValue = S.DefaultFunctionArrayLvalueConversion(ThisArg);
1834+
if (ThisValue.isInvalid())
18341835
return ExprError();
1835-
Call->setArg(0, ThisArg.get());
1836-
const Expr *Subject = Call->getArg(0);
1837-
QualType SubjectType = Subject->getType();
1838-
const CXXRecordDecl *SubjectRecord = SubjectType->getPointeeCXXRecordDecl();
1839-
if (!SubjectType->isPointerType() || !SubjectRecord) {
1840-
S.Diag(Subject->getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1841-
<< 0 << SubjectType;
1836+
Call->setArg(0, ThisValue.get());
1837+
QualType ThisType = ThisArg->getType();
1838+
if (ThisType->canDecayToPointerType() && ThisType->isArrayType())
1839+
ThisType = S.Context.getDecayedType(ThisType);
1840+
1841+
const CXXRecordDecl *SubjectRecord = ThisType->getPointeeCXXRecordDecl();
1842+
if (!SubjectRecord) {
1843+
S.Diag(ThisArg->getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1844+
<< /*isPolymorphic=*/0 << ThisType;
18421845
return ExprError();
18431846
}
18441847
if (S.RequireCompleteType(
1845-
Subject->getBeginLoc(), SubjectType->getPointeeType(),
1848+
ThisArg->getBeginLoc(), ThisType->getPointeeType(),
18461849
diag::err_get_vtable_pointer_requires_complete_type)) {
18471850
return ExprError();
18481851
}
18491852

18501853
if (!SubjectRecord->isPolymorphic()) {
1851-
S.Diag(Subject->getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1852-
<< 1 << SubjectRecord;
1854+
S.Diag(ThisArg->getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1855+
<< /*isPolymorphic=*/ 1 << SubjectRecord;
18531856
return ExprError();
18541857
}
18551858
QualType ReturnType = S.Context.getPointerType(S.Context.VoidTy.withConst());

clang/test/CodeGenCXX/builtin-get-vtable-pointer.cpp

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -O1 -disable-llvm-passes -no-enable-noundef-analysis -o - | FileCheck --check-prefix=CHECK-NOAUTH %s
2-
// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination -emit-llvm -O1 -disable-llvm-passes -no-enable-noundef-analysis -o - | FileCheck --check-prefix=CHECK-TYPEAUTH %s
3-
// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-vtable-pointer-address-discrimination -emit-llvm -O1 -disable-llvm-passes -no-enable-noundef-analysis -o - | FileCheck --check-prefix=CHECK-ADDRESSAUTH %s
4-
// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-address-discrimination -emit-llvm -O1 -disable-llvm-passes -no-enable-noundef-analysis -o - | FileCheck --check-prefix=CHECK-BOTHAUTH %s
1+
// RUN: %clang_cc1 %s -x c++ -std=c++23 -triple x86_64-apple-darwin10 -emit-llvm -O1 -disable-llvm-passes -no-enable-noundef-analysis -o - | FileCheck --check-prefix=CHECK-NOAUTH %s
2+
// RUN: %clang_cc1 %s -x c++ -std=c++23 -triple arm64-apple-ios -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination -emit-llvm -O1 -disable-llvm-passes -no-enable-noundef-analysis -o - | FileCheck --check-prefix=CHECK-TYPEAUTH %s
3+
// RUN: %clang_cc1 %s -x c++ -std=c++23 -triple arm64-apple-ios -fptrauth-calls -fptrauth-vtable-pointer-address-discrimination -emit-llvm -O1 -disable-llvm-passes -no-enable-noundef-analysis -o - | FileCheck --check-prefix=CHECK-ADDRESSAUTH %s
4+
// RUN: %clang_cc1 %s -x c++ -std=c++23 -triple arm64-apple-ios -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-address-discrimination -emit-llvm -O1 -disable-llvm-passes -no-enable-noundef-analysis -o - | FileCheck --check-prefix=CHECK-BOTHAUTH %s
55
// FIXME: Assume load should not require -fstrict-vtable-pointers
66

77
namespace test1 {
@@ -27,7 +27,16 @@ struct D : virtual A {
2727
struct E : D, B {
2828
};
2929

30+
template <class A, class B> struct same_type {
31+
static const bool value = false;
32+
};
33+
34+
template <class A> struct same_type<A, A> {
35+
static const bool value = true;
36+
};
37+
3038
const void *a(A *o) {
39+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
3140
// CHECK-NOAUTH: define ptr @_ZN5test11aEPNS_1AE(ptr %o) #0 {
3241
// CHECK-TYPEAUTH: define ptr @_ZN5test11aEPNS_1AE(ptr %o) #0 {
3342
return __builtin_get_vtable_pointer(o);
@@ -51,6 +60,7 @@ const void *a(A *o) {
5160
}
5261

5362
const void *b(B *o) {
63+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
5464
// CHECK-TYPEAUTH: define ptr @_ZN5test11bEPNS_1BE(ptr %o) #0 {
5565
// CHECK-NOAUTH: define ptr @_ZN5test11bEPNS_1BE(ptr %o) #0 {
5666
return __builtin_get_vtable_pointer(o);
@@ -72,6 +82,7 @@ const void *b(B *o) {
7282
}
7383

7484
const void *b_as_A(B *o) {
85+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
7586
// CHECK-NOAUTH: define ptr @_ZN5test16b_as_AEPNS_1BE(ptr %o) #0 {
7687
return __builtin_get_vtable_pointer((A *)o);
7788
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
@@ -92,6 +103,7 @@ const void *b_as_A(B *o) {
92103
}
93104

94105
const void *c(C *o) {
106+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
95107
// CHECK-NOAUTH: define ptr @_ZN5test11cEPNS_1CE(ptr %o) #0 {
96108
return __builtin_get_vtable_pointer(o);
97109
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
@@ -112,6 +124,7 @@ const void *c(C *o) {
112124
}
113125

114126
const void *c_as_Z(C *o) {
127+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
115128
// CHECK-NOAUTH: define ptr @_ZN5test16c_as_ZEPNS_1CE(ptr %o) #0 {
116129
return __builtin_get_vtable_pointer((Z *)o);
117130
// CHECK-NOAUTH: %0 = load ptr, ptr %o.addr, align 8
@@ -133,6 +146,7 @@ const void *c_as_Z(C *o) {
133146
}
134147

135148
const void *c_as_B(C *o) {
149+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
136150
// CHECK-NOAUTH: define ptr @_ZN5test16c_as_BEPNS_1CE(ptr %o) #0 {
137151
return __builtin_get_vtable_pointer((B *)o);
138152
// CHECK-NOAUTH: %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
@@ -158,6 +172,7 @@ const void *c_as_B(C *o) {
158172
}
159173

160174
const void *d(D *o) {
175+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
161176
// CHECK-NOAUTH: define ptr @_ZN5test11dEPNS_1DE(ptr %o) #0 {
162177
return __builtin_get_vtable_pointer(o);
163178
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
@@ -180,6 +195,7 @@ const void *d(D *o) {
180195
}
181196

182197
const void *d_as_A(D *o) {
198+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
183199
// CHECK-NOAUTH: define ptr @_ZN5test16d_as_AEPNS_1DE(ptr %o) #0 {
184200
return __builtin_get_vtable_pointer((A *)o);
185201
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
@@ -207,6 +223,7 @@ const void *d_as_A(D *o) {
207223
}
208224

209225
const void *e(E *o) {
226+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
210227
// CHECK-NOAUTH: define ptr @_ZN5test11eEPNS_1EE(ptr %o) #0 {
211228
return __builtin_get_vtable_pointer(o);
212229
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
@@ -229,6 +246,7 @@ const void *e(E *o) {
229246
}
230247

231248
const void *e_as_B(E *o) {
249+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
232250
// CHECK-NOAUTH: define ptr @_ZN5test16e_as_BEPNS_1EE(ptr %o) #0 {
233251
return __builtin_get_vtable_pointer((B *)o);
234252
// CHECK-NOAUTH: %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
@@ -253,6 +271,7 @@ const void *e_as_B(E *o) {
253271
}
254272

255273
const void *e_as_D(E *o) {
274+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
256275
// CHECK-NOAUTH: define ptr @_ZN5test16e_as_DEPNS_1EE(ptr %o) #0 {
257276
return __builtin_get_vtable_pointer((D *)o);
258277
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
@@ -274,12 +293,58 @@ const void *e_as_D(E *o) {
274293
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
275294
}
276295

296+
extern "C" const void *aArrayParameter(A aArray[]) {
297+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(aArray)), const void*>::value);
298+
// CHECK-NOAUTH: [[THIS_OBJ:%.*]] = load ptr, ptr %aArray.addr
299+
// CHECK-NOAUTH: %vtable = load ptr, ptr [[THIS_OBJ]]
300+
// CHECK-TYPEAUTH: [[THIS_OBJ:%.*]] = load ptr, ptr %aArray.addr
301+
// CHECK-TYPEAUTH: %vtable = load ptr, ptr [[THIS_OBJ]]
302+
// CHECK-TYPEAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
303+
// CHECK-TYPEAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 48388)
304+
// CHECK-ADDRESSAUTH: [[VTABLE_ADDR:%.*]] = load ptr, ptr %aArray.addr, align 8, !tbaa !2
305+
// CHECK-ADDRESSAUTH: %vtable = load ptr, ptr %0, align 8, !tbaa !7
306+
// CHECK-ADDRESSAUTH: [[VTABLE_ADDRI:%.*]] = ptrtoint ptr [[VTABLE_ADDR]] to i64
307+
// CHECK-ADDRESSAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
308+
// CHECK-ADDRESSAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 [[VTABLE_ADDRI]])
309+
// CHECK-BOTHAUTH: [[VTABLE_ADDR:%.*]] = load ptr, ptr %aArray.addr, align 8, !tbaa !2
310+
// CHECK-BOTHAUTH: %vtable = load ptr, ptr [[VTABLE_ADDR]], align 8, !tbaa !7
311+
// CHECK-BOTHAUTH: [[VTABLE_ADDRI:%.*]] = ptrtoint ptr [[VTABLE_ADDR]] to i64
312+
// CHECK-BOTHAUTH: [[VTABLE_DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTABLE_ADDRI]], i64 48388)
313+
// CHECK-BOTHAUTH: [[VTABLE_PTR:%.*]] = ptrtoint ptr %vtable to i64
314+
// CHECK-BOTHAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLE_PTR]], i32 2, i64 [[VTABLE_DISC]])
315+
return __builtin_get_vtable_pointer(aArray);
316+
}
317+
318+
extern "C" const void *aArrayLocal() {
319+
A array[] = { A() };
320+
static_assert(same_type<decltype(__builtin_get_vtable_pointer(array)), const void*>::value);
321+
// CHECK-NOAUTH: [[THIS_OBJ:%.*]] = getelementptr inbounds [1 x %"struct.test1::A"], ptr %array
322+
// CHECK-NOAUTH: %vtable = load ptr, ptr %arraydecay
323+
// CHECK-TYPEAUTH: %arraydecay = getelementptr inbounds [1 x %"struct.test1::A"]
324+
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %arraydecay
325+
// CHECK-TYPEAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
326+
// CHECK-TYPEAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 48388)
327+
// CHECK-ADDRESSAUTH: %arraydecay = getelementptr inbounds [1 x %"struct.test1::A"], ptr %array, i64 0, i64 0
328+
// CHECK-ADDRESSAUTH: %vtable = load ptr, ptr %arraydecay, align 8, !tbaa !7
329+
// CHECK-ADDRESSAUTH: [[VTABLE_ADDRI:%.*]] = ptrtoint ptr %arraydecay to i64
330+
// CHECK-ADDRESSAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
331+
// CHECK-ADDRESSAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 [[VTABLE_ADDRI]])
332+
// CHECK-BOTHAUTH: %arraydecay = getelementptr inbounds [1 x %"struct.test1::A"], ptr %array, i64 0, i64 0
333+
// CHECK-BOTHAUTH: %vtable = load ptr, ptr %arraydecay, align 8, !tbaa !7
334+
// CHECK-BOTHAUTH: [[VTABLE_ADDRI:%.*]] = ptrtoint ptr %arraydecay to i64
335+
// CHECK-BOTHAUTH: [[VTABLE_DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 %0, i64 48388)
336+
// CHECK-BOTHAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
337+
// CHECK-BOTHAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 [[VTABLE_DISC]])
338+
return __builtin_get_vtable_pointer(array);
339+
}
340+
277341
void test() {
278342
A aInstance;
279343
B bInstance;
280344
C cInstance;
281345
D dInstance;
282346
E eInstance;
347+
E eArray[] = { E() };
283348
a(&aInstance);
284349
a(&bInstance);
285350
a((B *)&cInstance);
@@ -300,5 +365,6 @@ void test() {
300365
e(&eInstance);
301366
e_as_B(&eInstance);
302367
e_as_D(&eInstance);
368+
(void)__builtin_get_vtable_pointer(eArray);
303369
}
304370
} // namespace test1

0 commit comments

Comments
 (0)