Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCXX / ubsan-devirtualized-calls.cpp
blob8a4dc0427b7b8c2cdf82ffa796be128aae04f0d5
1 // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s
3 struct Base1 {
4 virtual void f1() {}
5 };
7 struct Base2 {
8 virtual void f1() {}
9 };
11 struct Derived1 final : Base1 {
12 void f1() override {}
15 struct Derived2 final : Base1, Base2 {
16 void f1() override {}
19 struct Derived3 : Base1 {
20 void f1() override /* nofinal */ {}
23 struct Derived4 final : Base1 {
24 void f1() override final {}
27 // CHECK: [[UBSAN_TI_DERIVED1_1:@[0-9]+]] = private unnamed_addr global {{.*}} ptr @_ZTI8Derived1
28 // CHECK: [[UBSAN_TI_DERIVED2_1:@[0-9]+]] = private unnamed_addr global {{.*}} ptr @_ZTI8Derived2
29 // CHECK: [[UBSAN_TI_DERIVED2_2:@[0-9]+]] = private unnamed_addr global {{.*}} ptr @_ZTI8Derived2
30 // CHECK: [[UBSAN_TI_DERIVED3:@[0-9]+]] = private unnamed_addr global {{.*}} ptr @_ZTI8Derived3
31 // CHECK: [[UBSAN_TI_BASE1:@[0-9]+]] = private unnamed_addr global {{.*}} ptr @_ZTI5Base1
32 // CHECK: [[UBSAN_TI_DERIVED4_1:@[0-9]+]] = private unnamed_addr global {{.*}} ptr @_ZTI8Derived4
33 // CHECK: [[UBSAN_TI_DERIVED4_2:@[0-9]+]] = private unnamed_addr global {{.*}} ptr @_ZTI8Derived4
35 // CHECK-LABEL: define {{(dso_local )?}}void @_Z2t1v
36 void t1() {
37 Derived1 d1;
38 static_cast<Base1 *>(&d1)->f1(); //< Devirt Base1::f1 to Derived1::f1.
39 // CHECK: %[[D1:[0-9]+]] = ptrtoint ptr %d1 to i{{[0-9]+}}, !nosanitize
40 // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED1_1]], i{{[0-9]+}} %[[D1]]
43 // CHECK-LABEL: define {{(dso_local )?}}void @_Z2t2v
44 void t2() {
45 Derived2 d2;
46 static_cast<Base1 *>(&d2)->f1(); //< Devirt Base1::f1 to Derived2::f1.
47 // CHECK: %[[D2_1:[0-9]+]] = ptrtoint ptr %d2 to i{{[0-9]+}}, !nosanitize
48 // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED2_1]], i{{[0-9]+}} %[[D2_1]]
51 // CHECK-LABEL: define {{(dso_local )?}}void @_Z2t3v
52 void t3() {
53 Derived2 d2;
54 static_cast<Base2 *>(&d2)->f1(); //< Devirt Base2::f1 to Derived2::f1.
55 // CHECK: %[[D2_2:[0-9]+]] = ptrtoint ptr %d2 to i{{[0-9]+}}, !nosanitize
56 // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED2_2]], i{{[0-9]+}} %[[D2_2]]
59 // CHECK-LABEL: define {{(dso_local )?}}void @_Z2t4v
60 void t4() {
61 Base1 p;
62 Derived3 *badp = static_cast<Derived3 *>(&p); //< Check that &p isa Derived3.
63 // CHECK: %[[P1:[0-9]+]] = ptrtoint ptr %p to i{{[0-9]+}}, !nosanitize
64 // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED3]], i{{[0-9]+}} %[[P1]]
66 static_cast<Base1 *>(badp)->f1(); //< No devirt, test 'badp isa Base1'.
67 // We were able to skip the null check on the first type check because 'p'
68 // is backed by an alloca. We can't skip the second null check because 'badp'
69 // is a (bitcast (load ...)).
70 // CHECK: call void @__ubsan_handle_type_mismatch
72 // CHECK: %[[BADP1:[0-9]+]] = ptrtoint ptr {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
73 // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_BASE1]], i{{[0-9]+}} %[[BADP1]]
76 // CHECK-LABEL: define {{(dso_local )?}}void @_Z2t5v
77 void t5() {
78 Base1 p;
79 Derived4 *badp = static_cast<Derived4 *>(&p); //< Check that &p isa Derived4.
80 // CHECK: %[[P1:[0-9]+]] = ptrtoint ptr %p to i{{[0-9]+}}, !nosanitize
81 // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_1]], i{{[0-9]+}} %[[P1]]
83 static_cast<Base1 *>(badp)->f1(); //< Devirt Base1::f1 to Derived4::f1.
84 // CHECK: call void @__ubsan_handle_type_mismatch
86 // CHECK: %[[BADP1:[0-9]+]] = ptrtoint ptr {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
87 // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_2]], i{{[0-9]+}} %[[BADP1]]