When -fexperimental-call-graph-section flag is set, it adds type metadata to all the functions whose addresses are taken and does not have local linkage. When this flag is set along with CFI, the type metadata is added to all the vtable functions including destructors. This changes which functions are to be treated as CFI functions and includes such vtable entries to become part of the CFI check jumptables. To disambiguate intentions of CFI and callgraph mechanisms, this patch renames metadata set by callgraph mechanism to !callgraph (MD_callgraph). This prevents inflating the list of CFI functions when callgraph section is enabled along with CFI.
148 lines
5.0 KiB
C++
148 lines
5.0 KiB
C++
// Tests that we assign appropriate identifiers to indirect calls and targets
|
|
// specifically for C++ class and instance methods.
|
|
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux -fexperimental-call-graph-section \
|
|
// RUN: -emit-llvm -o %t %s
|
|
// RUN: FileCheck --check-prefix=FT %s < %t
|
|
// RUN: FileCheck --check-prefix=CST %s < %t
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Class definitions (check for indirect target metadata)
|
|
|
|
class Cls1 {
|
|
public:
|
|
// FT-LABEL: define {{.*}} ptr @_ZN4Cls18receiverEPcPf(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS1RECEIVER:![0-9]+]]
|
|
static int *receiver(char *a, float *b) { return 0; }
|
|
};
|
|
|
|
class Cls2 {
|
|
public:
|
|
int *(*fp)(char *, float *);
|
|
|
|
// FT-LABEL: define {{.*}} i32 @_ZN4Cls22f1Ecfd(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS2F1:![0-9]+]]
|
|
int f1(char a, float b, double c) { return 0; }
|
|
|
|
// FT-LABEL: define {{.*}} ptr @_ZN4Cls22f2EPcPfPd(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS2F2:![0-9]+]]
|
|
int *f2(char *a, float *b, double *c) { return 0; }
|
|
|
|
// FT-LABEL: define {{.*}} void @_ZN4Cls22f3E4Cls1(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS2F3F4:![0-9]+]]
|
|
void f3(Cls1 a) {}
|
|
|
|
// FT-LABEL: define {{.*}} void @_ZN4Cls22f4E4Cls1(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS2F3F4]]
|
|
void f4(const Cls1 a) {}
|
|
|
|
// FT-LABEL: define {{.*}} void @_ZN4Cls22f5EP4Cls1(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS2F5:![0-9]+]]
|
|
void f5(Cls1 *a) {}
|
|
|
|
// FT-LABEL: define {{.*}} void @_ZN4Cls22f6EPK4Cls1(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS2F6:![0-9]+]]
|
|
void f6(const Cls1 *a) {}
|
|
|
|
// FT-LABEL: define {{.*}} void @_ZN4Cls22f7ER4Cls1(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS2F7:![0-9]+]]
|
|
void f7(Cls1 &a) {}
|
|
|
|
// FT-LABEL: define {{.*}} void @_ZN4Cls22f8ERK4Cls1(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS2F8:![0-9]+]]
|
|
void f8(const Cls1 &a) {}
|
|
|
|
// FT-LABEL: define {{.*}} void @_ZNK4Cls22f9Ev(
|
|
// FT-SAME: {{.*}} !callgraph [[F_TCLS2F9:![0-9]+]]
|
|
void f9() const {}
|
|
};
|
|
|
|
// FT: [[F_TCLS1RECEIVER]] = !{!"_ZTSFPiPcPfE.generalized"}
|
|
// FT: [[F_TCLS2F1]] = !{!"_ZTSFicfdE.generalized"}
|
|
// FT: [[F_TCLS2F2]] = !{!"_ZTSFPiPcPfPdE.generalized"}
|
|
// FT: [[F_TCLS2F3F4]] = !{!"_ZTSFv4Cls1E.generalized"}
|
|
// FT: [[F_TCLS2F5]] = !{!"_ZTSFvP4Cls1E.generalized"}
|
|
// FT: [[F_TCLS2F6]] = !{!"_ZTSFvPK4Cls1E.generalized"}
|
|
// FT: [[F_TCLS2F7]] = !{!"_ZTSFvR4Cls1E.generalized"}
|
|
// FT: [[F_TCLS2F8]] = !{!"_ZTSFvRK4Cls1E.generalized"}
|
|
// FT: [[F_TCLS2F9]] = !{!"_ZTSKFvvE.generalized"}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Callsites (check for indirect callsites' callee_type metadata )
|
|
|
|
// CST-LABEL: define {{.*}} @_Z3foov
|
|
void foo() {
|
|
Cls2 ObjCls2;
|
|
ObjCls2.fp = &Cls1::receiver;
|
|
|
|
// CST: call noundef ptr %{{.*}}, !callee_type [[F_TCLS1RECEIVER_CT:![0-9]+]]
|
|
ObjCls2.fp(0, 0);
|
|
|
|
auto fp_f1 = &Cls2::f1;
|
|
auto fp_f2 = &Cls2::f2;
|
|
auto fp_f3 = &Cls2::f3;
|
|
auto fp_f4 = &Cls2::f4;
|
|
auto fp_f5 = &Cls2::f5;
|
|
auto fp_f6 = &Cls2::f6;
|
|
auto fp_f7 = &Cls2::f7;
|
|
auto fp_f8 = &Cls2::f8;
|
|
auto fp_f9 = &Cls2::f9;
|
|
|
|
Cls2 *ObjCls2Ptr = &ObjCls2;
|
|
Cls1 Cls1Param;
|
|
|
|
// CST: call noundef i32 %{{.*}}, !callee_type [[F_TCLS2F1_CT:![0-9]+]]
|
|
(ObjCls2Ptr->*fp_f1)(0, 0, 0);
|
|
|
|
// CST: call noundef ptr %{{.*}}, !callee_type [[F_TCLS2F2_CT:![0-9]+]]
|
|
(ObjCls2Ptr->*fp_f2)(0, 0, 0);
|
|
|
|
// CST: call void %{{.*}}, !callee_type [[F_TCLS2F3F4_CT:![0-9]+]]
|
|
(ObjCls2Ptr->*fp_f3)(Cls1Param);
|
|
|
|
// CST: call void %{{.*}}, !callee_type [[F_TCLS2F3F4_CT:![0-9]+]]
|
|
(ObjCls2Ptr->*fp_f4)(Cls1Param);
|
|
|
|
// CST: call void %{{.*}}, !callee_type [[F_TCLS2F5_CT:![0-9]+]]
|
|
(ObjCls2Ptr->*fp_f5)(&Cls1Param);
|
|
|
|
// CST: call void %{{.*}}, !callee_type [[F_TCLS2F6_CT:![0-9]+]]
|
|
(ObjCls2Ptr->*fp_f6)(&Cls1Param);
|
|
|
|
// CST: call void %{{.*}}, !callee_type [[F_TCLS2F7_CT:![0-9]+]]
|
|
(ObjCls2Ptr->*fp_f7)(Cls1Param);
|
|
|
|
// CST: call void %{{.*}}, !callee_type [[F_TCLS2F8_CT:![0-9]+]]
|
|
(ObjCls2Ptr->*fp_f8)(Cls1Param);
|
|
|
|
// CST: call void %{{.*}}, !callee_type [[F_TCLS2F9_CT:![0-9]+]]
|
|
(ObjCls2Ptr->*fp_f9)();
|
|
}
|
|
|
|
// CST: [[F_TCLS1RECEIVER_CT]] = !{[[F_TCLS1RECEIVER:![0-9]+]]}
|
|
// CST: [[F_TCLS1RECEIVER]] = !{!"_ZTSFPiPcPfE.generalized"}
|
|
|
|
// CST: [[F_TCLS2F1_CT]] = !{[[F_TCLS2F1:![0-9]+]]}
|
|
// CST: [[F_TCLS2F1]] = !{!"_ZTSFicfdE.generalized"}
|
|
|
|
// CST: [[F_TCLS2F2_CT]] = !{[[F_TCLS2F2:![0-9]+]]}
|
|
// CST: [[F_TCLS2F2]] = !{!"_ZTSFPiPcPfPdE.generalized"}
|
|
|
|
// CST: [[F_TCLS2F3F4_CT]] = !{[[F_TCLS2F3F4:![0-9]+]]}
|
|
// CST: [[F_TCLS2F3F4]] = !{!"_ZTSFv4Cls1E.generalized"}
|
|
|
|
// CST: [[F_TCLS2F5_CT]] = !{[[F_TCLS2F5:![0-9]+]]}
|
|
// CST: [[F_TCLS2F5]] = !{!"_ZTSFvP4Cls1E.generalized"}
|
|
|
|
// CST: [[F_TCLS2F6_CT]] = !{[[F_TCLS2F6:![0-9]+]]}
|
|
// CST: [[F_TCLS2F6]] = !{!"_ZTSFvPK4Cls1E.generalized"}
|
|
|
|
// CST: [[F_TCLS2F7_CT]] = !{[[F_TCLS2F7:![0-9]+]]}
|
|
// CST: [[F_TCLS2F7]] = !{!"_ZTSFvR4Cls1E.generalized"}
|
|
|
|
// CST: [[F_TCLS2F8_CT]] = !{[[F_TCLS2F8:![0-9]+]]}
|
|
// CST: [[F_TCLS2F8]] = !{!"_ZTSFvRK4Cls1E.generalized"}
|
|
|
|
// CST: [[F_TCLS2F9_CT]] = !{[[F_TCLS2F9:![0-9]+]]}
|
|
// CST: [[F_TCLS2F9]] = !{!"_ZTSKFvvE.generalized"}
|