cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
371 lines
20 KiB
C++
371 lines
20 KiB
C++
// 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
|
|
// 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
|
|
// 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
|
|
// 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
|
|
// FIXME: Assume load should not require -fstrict-vtable-pointers
|
|
|
|
namespace test1 {
|
|
struct A {
|
|
A();
|
|
virtual void bar();
|
|
};
|
|
|
|
struct B : A {
|
|
B();
|
|
virtual void foo();
|
|
};
|
|
|
|
struct Z : A {};
|
|
struct C : Z, B {
|
|
C();
|
|
virtual void wibble();
|
|
};
|
|
|
|
struct D : virtual A {
|
|
};
|
|
|
|
struct E : D, B {
|
|
};
|
|
|
|
template <class A, class B> struct same_type {
|
|
static const bool value = false;
|
|
};
|
|
|
|
template <class A> struct same_type<A, A> {
|
|
static const bool value = true;
|
|
};
|
|
|
|
const void *a(A *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test11aEPNS_1AE(ptr %o) #0 {
|
|
// CHECK-TYPEAUTH: define ptr @_ZN5test11aEPNS_1AE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer(o);
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %0 = load ptr, ptr %o.addr, align 8
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %1 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %2 = call i64 @llvm.ptrauth.auth(i64 %1, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %3 = inttoptr i64 %2 to ptr
|
|
// CHECK-TYPEAUTH: %4 = load volatile i8, ptr %3, align 8
|
|
// CHECK-ADDRESSAUTH: %2 = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: %3 = call i64 @llvm.ptrauth.auth(i64 %2, i32 2, i64 %1)
|
|
// CHECK-ADDRESSAUTH: %4 = inttoptr i64 %3 to ptr
|
|
// CHECK-ADDRESSAUTH: %5 = load volatile i8, ptr %4, align 8
|
|
// CHECK-BOTHAUTH: [[T1:%.*]] = ptrtoint ptr %0 to i64
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *b(B *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-TYPEAUTH: define ptr @_ZN5test11bEPNS_1BE(ptr %o) #0 {
|
|
// CHECK-NOAUTH: define ptr @_ZN5test11bEPNS_1BE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer(o);
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %1 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %2 = call i64 @llvm.ptrauth.auth(i64 %1, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %3 = inttoptr i64 %2 to ptr
|
|
// CHECK-TYPEAUTH: %4 = load volatile i8, ptr %3, align 8
|
|
// CHECK-ADDRESSAUTH: %2 = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: %3 = call i64 @llvm.ptrauth.auth(i64 %2, i32 2, i64 %1)
|
|
// CHECK-ADDRESSAUTH: %4 = inttoptr i64 %3 to ptr
|
|
// CHECK-ADDRESSAUTH: %5 = load volatile i8, ptr %4, align 8
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 %1, i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *b_as_A(B *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test16b_as_AEPNS_1BE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer((A *)o);
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %1 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %2 = call i64 @llvm.ptrauth.auth(i64 %1, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %3 = inttoptr i64 %2 to ptr
|
|
// CHECK-TYPEAUTH: %4 = load volatile i8, ptr %3, align 8
|
|
// CHECK-ADDRESSAUTH: %2 = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: %3 = call i64 @llvm.ptrauth.auth(i64 %2, i32 2, i64 %1)
|
|
// CHECK-ADDRESSAUTH: %4 = inttoptr i64 %3 to ptr
|
|
// CHECK-ADDRESSAUTH: %5 = load volatile i8, ptr %4, align 8
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 %1, i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *c(C *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test11cEPNS_1CE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer(o);
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %1 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %2 = call i64 @llvm.ptrauth.auth(i64 %1, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %3 = inttoptr i64 %2 to ptr
|
|
// CHECK-TYPEAUTH: %4 = load volatile i8, ptr %3, align 8
|
|
// CHECK-ADDRESSAUTH: %2 = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: %3 = call i64 @llvm.ptrauth.auth(i64 %2, i32 2, i64 %1)
|
|
// CHECK-ADDRESSAUTH: %4 = inttoptr i64 %3 to ptr
|
|
// CHECK-ADDRESSAUTH: %5 = load volatile i8, ptr %4, align 8
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 %1, i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *c_as_Z(C *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test16c_as_ZEPNS_1CE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer((Z *)o);
|
|
// CHECK-NOAUTH: %0 = load ptr, ptr %o.addr, align 8
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %1 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %2 = call i64 @llvm.ptrauth.auth(i64 %1, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %3 = inttoptr i64 %2 to ptr
|
|
// CHECK-TYPEAUTH: %4 = load volatile i8, ptr %3, align 8
|
|
// CHECK-ADDRESSAUTH: %2 = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: %3 = call i64 @llvm.ptrauth.auth(i64 %2, i32 2, i64 %1)
|
|
// CHECK-ADDRESSAUTH: %4 = inttoptr i64 %3 to ptr
|
|
// CHECK-ADDRESSAUTH: %5 = load volatile i8, ptr %4, align 8
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 %1, i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *c_as_B(C *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test16c_as_BEPNS_1CE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer((B *)o);
|
|
// CHECK-NOAUTH: %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
|
|
// CHECK-NOAUTH: br label %cast.end
|
|
// CHECK-NOAUTH: %cast.result = phi ptr [ %add.ptr, %cast.notnull ], [ null, %entry ]
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %cast.result, align 8
|
|
// CHECK-TYPEAUTH: %cast.result = phi ptr [ %add.ptr, %cast.notnull ], [ null, %entry ]
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %cast.result, align 8
|
|
// CHECK-TYPEAUTH: %2 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %3 = call i64 @llvm.ptrauth.auth(i64 %2, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %4 = inttoptr i64 %3 to ptr
|
|
// CHECK-TYPEAUTH: %5 = load volatile i8, ptr %4, align 8
|
|
// CHECK-ADDRESSAUTH: %2 = ptrtoint ptr %cast.result to i64
|
|
// CHECK-ADDRESSAUTH: %3 = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: %4 = call i64 @llvm.ptrauth.auth(i64 %3, i32 2, i64 %2)
|
|
// CHECK-ADDRESSAUTH: %5 = inttoptr i64 %4 to ptr
|
|
// CHECK-ADDRESSAUTH: %6 = load volatile i8, ptr %5, align 8
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 %2, i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *d(D *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test11dEPNS_1DE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer(o);
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %1 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %2 = call i64 @llvm.ptrauth.auth(i64 %1, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %3 = inttoptr i64 %2 to ptr
|
|
// CHECK-TYPEAUTH: %4 = load volatile i8, ptr %3, align 8
|
|
// CHECK-ADDRESSAUTH: %1 = ptrtoint ptr %0 to i64
|
|
// CHECK-ADDRESSAUTH: %2 = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: %3 = call i64 @llvm.ptrauth.auth(i64 %2, i32 2, i64 %1)
|
|
// CHECK-ADDRESSAUTH: %4 = inttoptr i64 %3 to ptr
|
|
// CHECK-ADDRESSAUTH: %5 = load volatile i8, ptr %4, align 8
|
|
// CHECK-BOTHAUTH: [[T1:%.*]] = ptrtoint ptr %0 to i64
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *d_as_A(D *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test16d_as_AEPNS_1DE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer((A *)o);
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-NOAUTH: %vbase.offset.ptr = getelementptr i8, ptr %vtable, i64 -32
|
|
// CHECK-NOAUTH: %vbase.offset = load i64, ptr %vbase.offset.ptr, align 8
|
|
// CHECK-NOAUTH: %add.ptr = getelementptr inbounds i8, ptr %0, i64 %vbase.offset
|
|
// CHECK-NOAUTH: %cast.result = phi ptr [ %add.ptr, %cast.notnull ], [ null, %entry ]
|
|
// CHECK-NOAUTH: %vtable1 = load ptr, ptr %cast.result, align 8
|
|
// CHECK-TYPEAUTH: %vtable1 = load ptr, ptr %cast.result, align 8
|
|
// CHECK-TYPEAUTH: %5 = ptrtoint ptr %vtable1 to i64
|
|
// CHECK-TYPEAUTH: %6 = call i64 @llvm.ptrauth.auth(i64 %5, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %7 = inttoptr i64 %6 to ptr
|
|
// CHECK-TYPEAUTH: %8 = load volatile i8, ptr %7, align 8
|
|
// CHECK-ADDRESSAUTH: %6 = ptrtoint ptr %cast.result to i64
|
|
// CHECK-ADDRESSAUTH: %7 = ptrtoint ptr %vtable1 to i64
|
|
// CHECK-ADDRESSAUTH: %8 = call i64 @llvm.ptrauth.auth(i64 %7, i32 2, i64 %6)
|
|
// CHECK-ADDRESSAUTH: %9 = inttoptr i64 %8 to ptr
|
|
// CHECK-ADDRESSAUTH: %10 = load volatile i8, ptr %9, align 8
|
|
// CHECK-BOTHAUTH: [[T1:%.*]] = ptrtoint ptr %cast.result to i64
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable1 to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *e(E *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test11eEPNS_1EE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer(o);
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %1 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %2 = call i64 @llvm.ptrauth.auth(i64 %1, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %3 = inttoptr i64 %2 to ptr
|
|
// CHECK-TYPEAUTH: %4 = load volatile i8, ptr %3, align 8
|
|
// CHECK-ADDRESSAUTH: [[T1:%.*]] = ptrtoint ptr %0 to i64
|
|
// CHECK-ADDRESSAUTH: [[T2:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: [[T3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T2]], i32 2, i64 [[T1]])
|
|
// CHECK-ADDRESSAUTH: [[T4:%.*]] = inttoptr i64 [[T3]] to ptr
|
|
// CHECK-ADDRESSAUTH: [[T5:%.*]] = load volatile i8, ptr [[T4]], align 8
|
|
// CHECK-BOTHAUTH: [[T1:%.*]] = ptrtoint ptr %0 to i64
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *e_as_B(E *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test16e_as_BEPNS_1EE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer((B *)o);
|
|
// CHECK-NOAUTH: %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
|
|
// CHECK-NOAUTH: %cast.result = phi ptr [ %add.ptr, %cast.notnull ], [ null, %entry ]
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %cast.result, align 8
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %cast.result, align 8
|
|
// CHECK-TYPEAUTH: %2 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %3 = call i64 @llvm.ptrauth.auth(i64 %2, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %4 = inttoptr i64 %3 to ptr
|
|
// CHECK-TYPEAUTH: %5 = load volatile i8, ptr %4, align 8
|
|
// CHECK-ADDRESSAUTH: [[T1:%.*]] = ptrtoint ptr %cast.result to i64
|
|
// CHECK-ADDRESSAUTH: [[T2:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: [[T3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T2]], i32 2, i64 [[T1]])
|
|
// CHECK-ADDRESSAUTH: [[T4:%.*]] = inttoptr i64 [[T3]] to ptr
|
|
// CHECK-ADDRESSAUTH: [[T5:%.*]] = load volatile i8, ptr [[T4]], align 8
|
|
// CHECK-BOTHAUTH: [[T1:%.*]] = ptrtoint ptr %cast.result to i64
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
const void *e_as_D(E *o) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(o)), const void*>::value);
|
|
// CHECK-NOAUTH: define ptr @_ZN5test16e_as_DEPNS_1EE(ptr %o) #0 {
|
|
return __builtin_get_vtable_pointer((D *)o);
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %0, align 8
|
|
// CHECK-TYPEAUTH: %1 = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: %2 = call i64 @llvm.ptrauth.auth(i64 %1, i32 2, i64 48388)
|
|
// CHECK-TYPEAUTH: %3 = inttoptr i64 %2 to ptr
|
|
// CHECK-TYPEAUTH: %4 = load volatile i8, ptr %3, align 8
|
|
// CHECK-ADDRESSAUTH: [[T1:%.*]] = ptrtoint ptr %0 to i64
|
|
// CHECK-ADDRESSAUTH: [[T2:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: [[T3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T2]], i32 2, i64 [[T1]])
|
|
// CHECK-ADDRESSAUTH: [[T4:%.*]] = inttoptr i64 [[T3]] to ptr
|
|
// CHECK-ADDRESSAUTH: [[T5:%.*]] = load volatile i8, ptr [[T4]], align 8
|
|
// CHECK-BOTHAUTH: [[T1:%.*]] = ptrtoint ptr %0 to i64
|
|
// CHECK-BOTHAUTH: [[T2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 48388)
|
|
// CHECK-BOTHAUTH: [[T3:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[T4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T3]], i32 2, i64 [[T2]])
|
|
// CHECK-BOTHAUTH: [[T5:%.*]] = inttoptr i64 [[T4]] to ptr
|
|
// CHECK-BOTHAUTH: [[T6:%.*]] = load volatile i8, ptr [[T5]], align 8
|
|
}
|
|
|
|
extern "C" const void *aArrayParameter(A aArray[]) {
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(aArray)), const void*>::value);
|
|
// CHECK-NOAUTH: [[THIS_OBJ:%.*]] = load ptr, ptr %aArray.addr
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr [[THIS_OBJ]]
|
|
// CHECK-TYPEAUTH: [[THIS_OBJ:%.*]] = load ptr, ptr %aArray.addr
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr [[THIS_OBJ]]
|
|
// CHECK-TYPEAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 48388)
|
|
// CHECK-ADDRESSAUTH: [[VTABLE_ADDR:%.*]] = load ptr, ptr %aArray.addr, align 8, !tbaa !2
|
|
// CHECK-ADDRESSAUTH: %vtable = load ptr, ptr %0, align 8, !tbaa !7
|
|
// CHECK-ADDRESSAUTH: [[VTABLE_ADDRI:%.*]] = ptrtoint ptr [[VTABLE_ADDR]] to i64
|
|
// CHECK-ADDRESSAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 [[VTABLE_ADDRI]])
|
|
// CHECK-BOTHAUTH: [[VTABLE_ADDR:%.*]] = load ptr, ptr %aArray.addr, align 8, !tbaa !2
|
|
// CHECK-BOTHAUTH: %vtable = load ptr, ptr [[VTABLE_ADDR]], align 8, !tbaa !7
|
|
// CHECK-BOTHAUTH: [[VTABLE_ADDRI:%.*]] = ptrtoint ptr [[VTABLE_ADDR]] to i64
|
|
// CHECK-BOTHAUTH: [[VTABLE_DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTABLE_ADDRI]], i64 48388)
|
|
// CHECK-BOTHAUTH: [[VTABLE_PTR:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLE_PTR]], i32 2, i64 [[VTABLE_DISC]])
|
|
return __builtin_get_vtable_pointer(aArray);
|
|
}
|
|
|
|
extern "C" const void *aArrayLocal() {
|
|
A array[] = { A() };
|
|
static_assert(same_type<decltype(__builtin_get_vtable_pointer(array)), const void*>::value);
|
|
// CHECK-NOAUTH: [[THIS_OBJ:%.*]] = getelementptr inbounds [1 x %"struct.test1::A"], ptr %array
|
|
// CHECK-NOAUTH: %vtable = load ptr, ptr %arraydecay
|
|
// CHECK-TYPEAUTH: %arraydecay = getelementptr inbounds [1 x %"struct.test1::A"]
|
|
// CHECK-TYPEAUTH: %vtable = load ptr, ptr %arraydecay
|
|
// CHECK-TYPEAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-TYPEAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 48388)
|
|
// CHECK-ADDRESSAUTH: %arraydecay = getelementptr inbounds [1 x %"struct.test1::A"], ptr %array, i64 0, i64 0
|
|
// CHECK-ADDRESSAUTH: %vtable = load ptr, ptr %arraydecay, align 8, !tbaa !7
|
|
// CHECK-ADDRESSAUTH: [[VTABLE_ADDRI:%.*]] = ptrtoint ptr %arraydecay to i64
|
|
// CHECK-ADDRESSAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-ADDRESSAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 [[VTABLE_ADDRI]])
|
|
// CHECK-BOTHAUTH: %arraydecay = getelementptr inbounds [1 x %"struct.test1::A"], ptr %array, i64 0, i64 0
|
|
// CHECK-BOTHAUTH: %vtable = load ptr, ptr %arraydecay, align 8, !tbaa !7
|
|
// CHECK-BOTHAUTH: [[VTABLE_ADDRI:%.*]] = ptrtoint ptr %arraydecay to i64
|
|
// CHECK-BOTHAUTH: [[VTABLE_DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 %0, i64 48388)
|
|
// CHECK-BOTHAUTH: [[VTABLEI:%.*]] = ptrtoint ptr %vtable to i64
|
|
// CHECK-BOTHAUTH: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI]], i32 2, i64 [[VTABLE_DISC]])
|
|
return __builtin_get_vtable_pointer(array);
|
|
}
|
|
|
|
void test() {
|
|
A aInstance;
|
|
B bInstance;
|
|
C cInstance;
|
|
D dInstance;
|
|
E eInstance;
|
|
E eArray[] = { E() };
|
|
a(&aInstance);
|
|
a(&bInstance);
|
|
a((B *)&cInstance);
|
|
a(&dInstance);
|
|
a((D *)&eInstance);
|
|
a((B *)&eInstance);
|
|
b(&bInstance);
|
|
b(&cInstance);
|
|
b(&eInstance);
|
|
b_as_A(&bInstance);
|
|
c(&cInstance);
|
|
c_as_Z(&cInstance);
|
|
c_as_B(&cInstance);
|
|
d(&dInstance);
|
|
d(&eInstance);
|
|
d_as_A(&dInstance);
|
|
d_as_A(&eInstance);
|
|
e(&eInstance);
|
|
e_as_B(&eInstance);
|
|
e_as_D(&eInstance);
|
|
(void)__builtin_get_vtable_pointer(eArray);
|
|
}
|
|
} // namespace test1
|