Changeset View
Changeset View
Standalone View
Standalone View
clang/test/CodeGenCXX/cfi-mfcall.cpp
// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-mfcall -fsanitize-trap=cfi-mfcall -fvisibility hidden -emit-llvm -o - %s | FileCheck %s | // RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-mfcall -fsanitize-trap=cfi-mfcall -fvisibility hidden -emit-llvm -o - %s | FileCheck %s | ||||
// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-mfcall -fsanitize-trap=cfi-mfcall -fvisibility default -emit-llvm -o - %s | FileCheck --check-prefix=DEFAULT %s | // RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-mfcall -fsanitize-trap=cfi-mfcall -fvisibility default -emit-llvm -o - %s | FileCheck --check-prefix=DEFAULT %s | ||||
// With -fwhole-program-vtables we should get the member function pointer type | |||||
// test, even without hidden visibility. | |||||
// RUN: %clang_cc1 -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck %s --check-prefix=WPV | |||||
struct B1 {}; | struct B1 {}; | ||||
struct B2 {}; | struct B2 {}; | ||||
struct B3 : B2 {}; | struct B3 : B2 {}; | ||||
struct S : B1, B3 {}; | struct S : B1, B3 {}; | ||||
// DEFAULT-NOT: llvm.type.test | // DEFAULT-NOT: llvm.type.test | ||||
void f(S *s, void (S::*p)()) { | void f(S *s, void (S::*p)()) { | ||||
// WPV: [[OFFSET:%.*]] = sub i64 {{.*}}, 1 | |||||
// WPV: [[VFPTR:%.*]] = getelementptr i8, i8* %{{.*}}, i64 [[OFFSET]] | |||||
// WPV: [[TT:%.*]] = call i1 @llvm.type.test(i8* [[VFPTR]], metadata !"_ZTSM1SFvvE.virtual") | |||||
// CHECK: [[OFFSET:%.*]] = sub i64 {{.*}}, 1 | // CHECK: [[OFFSET:%.*]] = sub i64 {{.*}}, 1 | ||||
// CHECK: [[VFPTR:%.*]] = getelementptr i8, i8* %{{.*}}, i64 [[OFFSET]] | // CHECK: [[VFPTR:%.*]] = getelementptr i8, i8* %{{.*}}, i64 [[OFFSET]] | ||||
// CHECK: [[TT:%.*]] = call i1 @llvm.type.test(i8* [[VFPTR]], metadata !"_ZTSM1SFvvE.virtual") | // CHECK: [[TT:%.*]] = call i1 @llvm.type.test(i8* [[VFPTR]], metadata !"_ZTSM1SFvvE.virtual") | ||||
// CHECK: br i1 [[TT]], label {{.*}}, label %[[TRAP1:[^,]*]] | // CHECK: br i1 [[TT]], label {{.*}}, label %[[TRAP1:[^,]*]] | ||||
// CHECK: [[TRAP1]]: | // CHECK: [[TRAP1]]: | ||||
// CHECK-NEXT: llvm.trap | // CHECK-NEXT: llvm.trap | ||||
Show All 11 Lines |