Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
08d0dc1
[𝘀𝗽𝗿] initial version
Prabhuk Nov 20, 2024
feeeeff
Reorder commits. Fix clang codegen tests.
Prabhuk Dec 10, 2024
2ece26f
Update OB name from `type` to `callee_type`.
Prabhuk Mar 12, 2025
96c1d4e
Fix EOF newlines.
Prabhuk Mar 12, 2025
bfb4b1a
Add requested tests part 1.
Prabhuk Mar 13, 2025
5bfc9de
Update comments in tests.
Prabhuk Mar 13, 2025
ccf13f2
Updated the test as reviewers suggested.
Prabhuk Mar 13, 2025
158babd
Scoped enum. Simplify test.
Prabhuk Mar 13, 2025
fc860ab
Remove unnecessary cast.
Prabhuk Mar 13, 2025
7847eb0
Remove unnecessary asserts. Remove autos for better readability.
Prabhuk Mar 13, 2025
ba49de6
Reorder IR metadata and rename temporary var names in test.
Prabhuk Mar 13, 2025
1aba048
Add RISC-V support. Clean up test files.
Prabhuk Mar 14, 2025
c6d8515
Clean up test files.
Prabhuk Mar 15, 2025
c8154ed
Address review comments.
Prabhuk Mar 19, 2025
3e00a85
Emit callee_type metadata instead of operand bundle.
Prabhuk Apr 19, 2025
7228076
Address review comments.
Prabhuk Apr 19, 2025
2cb23b7
Rebase on top of llvm stack.
Prabhuk Apr 23, 2025
11c0913
Address review comments.
Prabhuk Apr 23, 2025
b7fbe09
Address review comments.
Prabhuk Apr 23, 2025
3eb7a45
Address review comments.
Prabhuk Apr 23, 2025
ffa1779
Address review comments.
Prabhuk Apr 24, 2025
f10586e
Rebase on parent.
Prabhuk Apr 24, 2025
5ddaf26
Rebase on parent.
Prabhuk Apr 24, 2025
346e5b3
Rebase on parent.
Prabhuk Apr 28, 2025
2d30d64
Rebase on parent.
Prabhuk Apr 29, 2025
bdc76a9
Rebase on parent.
Prabhuk May 1, 2025
e5157f6
Rebase on parent.
Prabhuk May 5, 2025
02b2b3f
Rebase on parent change.
Prabhuk May 10, 2025
67eab8a
Rebase on parent changes.
Prabhuk May 13, 2025
c183666
Rebase on parent.
Prabhuk May 13, 2025
083270f
Rebase on parent
Prabhuk May 14, 2025
fac07fd
Rebase on main.
Prabhuk May 14, 2025
e193a40
Rebase on parent.
Prabhuk May 27, 2025
599b585
Rebase change.
Prabhuk May 27, 2025
e41d689
Rebase.
Prabhuk Jun 11, 2025
397fd64
Rebase on parent
Prabhuk Jun 11, 2025
842f976
Rebase on top of main.
Prabhuk Jul 10, 2025
13c0ffa
Rebase on parent.
Prabhuk Jul 18, 2025
8ee6932
Rebase on parent
Prabhuk Jul 18, 2025
e179dc9
Rebase on top of parent change.
Prabhuk Jul 18, 2025
cb81b8a
Rebase on parent.
Prabhuk Jul 18, 2025
ad6905d
Rebase on parent.
Prabhuk Jul 18, 2025
d892b83
Address review comments.
Prabhuk Jul 18, 2025
fcb1497
Rebase on parent.
Prabhuk Jul 21, 2025
dfb1dc4
Simplify MD exists check.
Prabhuk Jul 21, 2025
b902d6e
Rebase.
Prabhuk Jul 22, 2025
7c4b302
Rebase on parent change.
Prabhuk Jul 23, 2025
aa0c1d1
Rebase on main.
Prabhuk Jul 23, 2025
985522c
Rebase.
Prabhuk Jul 23, 2025
0382f0f
Rebase on parent.
Prabhuk Jul 28, 2025
e4c653f
Rebase on llvm changes.
Prabhuk Jul 28, 2025
6195f97
Rebase on main.
Prabhuk Jul 30, 2025
6b8eb94
Rebase on parent.
Prabhuk Jul 31, 2025
3788ce7
Rebase on parent.
Prabhuk Jul 31, 2025
0ca9184
Rebase on main.
Prabhuk Jul 31, 2025
1f16b6a
Make Driver flag experimental.
Prabhuk Jul 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
Expand All @@ -38,7 +37,6 @@
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Type.h"
Expand Down Expand Up @@ -5785,7 +5783,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
auto *TypeIdMD = CGM.CreateMetadataIdentifierGeneralized(CST);
auto *TypeIdMDVal =
llvm::MetadataAsValue::get(getLLVMContext(), TypeIdMD);
BundleList.emplace_back("type", TypeIdMDVal);
BundleList.emplace_back("callee_type", TypeIdMDVal);
}
}

Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6195,6 +6195,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
}
if (CallOrInvoke)
*CallOrInvoke = LocalCallOrInvoke;

return Call;
}

Expand Down
5 changes: 3 additions & 2 deletions clang/lib/CodeGen/CGObjCMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2214,8 +2214,9 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,

llvm::CallBase *CallSite;
CGCallee Callee = CGCallee::forDirect(BitcastFn);
RValue rvalue =
CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);
RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
&CallSite);

// Mark the call as noreturn if the method is marked noreturn and the
// receiver cannot be null.
if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3032,8 +3032,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
// are non-canonical then we need type metadata in order to produce the local
// jump table.
if (!CodeGenOpts.SanitizeCfiCrossDso ||
!CodeGenOpts.SanitizeCfiCanonicalJumpTables ||
CodeGenOpts.CallGraphSection)
!CodeGenOpts.SanitizeCfiCanonicalJumpTables)
CreateFunctionTypeMetadataForIcall(FD, F);

if (LangOpts.Sanitize.has(SanitizerKind::KCFI))
Expand Down
197 changes: 99 additions & 98 deletions clang/test/CodeGen/call-graph-section-1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,101 +10,102 @@
// Class definitions (check for indirect target metadata)

class Cls1 {
public:
// FT-DAG: define {{.*}} ptr @_ZN4Cls18receiverEPcPf({{.*}} !type [[F_TCLS1RECEIVER:![0-9]+]]
static int *receiver(char *a, float *b) { return 0; }
};

class Cls2 {
public:
int *(*fp)(char *, float *);

// FT-DAG: define {{.*}} i32 @_ZN4Cls22f1Ecfd({{.*}} !type [[F_TCLS2F1:![0-9]+]]
int f1(char a, float b, double c) { return 0; }

// FT-DAG: define {{.*}} ptr @_ZN4Cls22f2EPcPfPd({{.*}} !type [[F_TCLS2F2:![0-9]+]]
int *f2(char *a, float *b, double *c) { return 0; }

// FT-DAG: define {{.*}} void @_ZN4Cls22f3E4Cls1({{.*}} !type [[F_TCLS2F3F4:![0-9]+]]
void f3(Cls1 a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f4E4Cls1({{.*}} !type [[F_TCLS2F3F4]]
void f4(const Cls1 a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f5EP4Cls1({{.*}} !type [[F_TCLS2F5:![0-9]+]]
void f5(Cls1 *a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f6EPK4Cls1({{.*}} !type [[F_TCLS2F6:![0-9]+]]
void f6(const Cls1 *a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f7ER4Cls1({{.*}} !type [[F_TCLS2F7:![0-9]+]]
void f7(Cls1 &a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f8ERK4Cls1({{.*}} !type [[F_TCLS2F8:![0-9]+]]
void f8(const Cls1 &a) {}

// FT-DAG: define {{.*}} void @_ZNK4Cls22f9Ev({{.*}} !type [[F_TCLS2F9:![0-9]+]]
void f9() const {}
};

// FT-DAG: [[F_TCLS1RECEIVER]] = !{i64 0, !"_ZTSFPvS_S_E.generalized"}
// FT-DAG: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFPvS_S_S_E.generalized"}
// FT-DAG: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFicfdE.generalized"}
// FT-DAG: [[F_TCLS2F3F4]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"}
// FT-DAG: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvPvE.generalized"}
// FT-DAG: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvPKvE.generalized"}
// FT-DAG: [[F_TCLS2F7]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"}
// FT-DAG: [[F_TCLS2F8]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"}
// FT-DAG: [[F_TCLS2F9]] = !{i64 0, !"_ZTSKFvvE.generalized"}

////////////////////////////////////////////////////////////////////////////////
// Callsites (check for indirect callsite operand bundles)

// CST-LABEL: define {{.*}} @_Z3foov
void foo() {
Cls2 ObjCls2;
ObjCls2.fp = &Cls1::receiver;

// CST: call noundef ptr %{{.*}} [ "type"(metadata !"_ZTSFPvS_S_E.generalized") ]
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 %{{.*}} [ "type"(metadata !"_ZTSFicfdE.generalized") ]
(ObjCls2Ptr->*fp_f1)(0, 0, 0);

// CST: call noundef ptr %{{.*}} [ "type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
(ObjCls2Ptr->*fp_f2)(0, 0, 0);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFv4Cls1E.generalized") ]
(ObjCls2Ptr->*fp_f3)(Cls1Param);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFv4Cls1E.generalized") ]
(ObjCls2Ptr->*fp_f4)(Cls1Param);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPvE.generalized") ]
(ObjCls2Ptr->*fp_f5)(&Cls1Param);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPKvE.generalized") ]
(ObjCls2Ptr->*fp_f6)(&Cls1Param);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvR4Cls1E.generalized") ]
(ObjCls2Ptr->*fp_f7)(Cls1Param);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvRK4Cls1E.generalized") ]
(ObjCls2Ptr->*fp_f8)(Cls1Param);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSKFvvE.generalized") ]
(ObjCls2Ptr->*fp_f9)();
}
public:
// FT-DAG: define {{.*}} ptr @_ZN4Cls18receiverEPcPf({{.*}} !type [[F_TCLS1RECEIVER:![0-9]+]]
static int *receiver(char *a, float *b) { return 0; }
};

class Cls2 {
public:
int *(*fp)(char *, float *);

// FT-DAG: define {{.*}} i32 @_ZN4Cls22f1Ecfd({{.*}} !type [[F_TCLS2F1:![0-9]+]]
int f1(char a, float b, double c) { return 0; }

// FT-DAG: define {{.*}} ptr @_ZN4Cls22f2EPcPfPd({{.*}} !type [[F_TCLS2F2:![0-9]+]]
int *f2(char *a, float *b, double *c) { return 0; }

// FT-DAG: define {{.*}} void @_ZN4Cls22f3E4Cls1({{.*}} !type [[F_TCLS2F3F4:![0-9]+]]
void f3(Cls1 a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f4E4Cls1({{.*}} !type [[F_TCLS2F3F4]]
void f4(const Cls1 a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f5EP4Cls1({{.*}} !type [[F_TCLS2F5:![0-9]+]]
void f5(Cls1 *a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f6EPK4Cls1({{.*}} !type [[F_TCLS2F6:![0-9]+]]
void f6(const Cls1 *a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f7ER4Cls1({{.*}} !type [[F_TCLS2F7:![0-9]+]]
void f7(Cls1 &a) {}

// FT-DAG: define {{.*}} void @_ZN4Cls22f8ERK4Cls1({{.*}} !type [[F_TCLS2F8:![0-9]+]]
void f8(const Cls1 &a) {}

// FT-DAG: define {{.*}} void @_ZNK4Cls22f9Ev({{.*}} !type [[F_TCLS2F9:![0-9]+]]
void f9() const {}
};

// FT-DAG: [[F_TCLS1RECEIVER]] = !{i64 0, !"_ZTSFPvS_S_E.generalized"}
// FT-DAG: [[F_TCLS2F2]] = !{i64 0, !"_ZTSFPvS_S_S_E.generalized"}
// FT-DAG: [[F_TCLS2F1]] = !{i64 0, !"_ZTSFicfdE.generalized"}
// FT-DAG: [[F_TCLS2F3F4]] = !{i64 0, !"_ZTSFv4Cls1E.generalized"}
// FT-DAG: [[F_TCLS2F5]] = !{i64 0, !"_ZTSFvPvE.generalized"}
// FT-DAG: [[F_TCLS2F6]] = !{i64 0, !"_ZTSFvPKvE.generalized"}
// FT-DAG: [[F_TCLS2F7]] = !{i64 0, !"_ZTSFvR4Cls1E.generalized"}
// FT-DAG: [[F_TCLS2F8]] = !{i64 0, !"_ZTSFvRK4Cls1E.generalized"}
// FT-DAG: [[F_TCLS2F9]] = !{i64 0, !"_ZTSKFvvE.generalized"}

////////////////////////////////////////////////////////////////////////////////
// Callsites (check for indirect callsite operand bundles)

// CST-LABEL: define {{.*}} @_Z3foov
void foo() {
Cls2 ObjCls2;
ObjCls2.fp = &Cls1::receiver;

// CST: call noundef ptr %{{.*}} [ "callee_type"(metadata !"_ZTSFPvS_S_E.generalized") ]
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"(metadata !"_ZTSFicfdE.generalized") ]
(ObjCls2Ptr->*fp_f1)(0, 0, 0);

// CST: call noundef ptr %{{.*}} [ "callee_type"(metadata !"_ZTSFPvS_S_S_E.generalized") ]
(ObjCls2Ptr->*fp_f2)(0, 0, 0);

// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFv4Cls1E.generalized") ]
(ObjCls2Ptr->*fp_f3)(Cls1Param);

// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFv4Cls1E.generalized") ]
(ObjCls2Ptr->*fp_f4)(Cls1Param);

// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFvPvE.generalized") ]
(ObjCls2Ptr->*fp_f5)(&Cls1Param);

// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFvPKvE.generalized") ]
(ObjCls2Ptr->*fp_f6)(&Cls1Param);

// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFvR4Cls1E.generalized") ]
(ObjCls2Ptr->*fp_f7)(Cls1Param);

// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFvRK4Cls1E.generalized") ]
(ObjCls2Ptr->*fp_f8)(Cls1Param);

// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSKFvvE.generalized") ]
(ObjCls2Ptr->*fp_f9)();
}

14 changes: 7 additions & 7 deletions clang/test/CodeGen/call-graph-section-2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void foo() {
Obj.fp = T_func<Cls1>;
Cls1 Cls1Obj;

// CST: call noundef ptr %{{.*}} [ "type"(metadata !"_ZTSFPv4Cls1S_PKvRS0_RKS0_E.generalized") ]
// CST: call noundef ptr %{{.*}} [ "callee_type"(metadata !"_ZTSFPv4Cls1S_PKvRS0_RKS0_E.generalized") ]
Obj.fp(Cls1Obj, &Cls1Obj, &Cls1Obj, Cls1Obj, Cls1Obj);

// Make indirect calls to Cls2's member methods
Expand All @@ -75,21 +75,21 @@ void foo() {

auto *Obj2Ptr = &Obj;

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvvE.generalized") ]
// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFvvE.generalized") ]
(Obj2Ptr->*fp_f1)();

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFv4Cls1E.generalized") ]
// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFv4Cls1E.generalized") ]
(Obj2Ptr->*fp_f2)(Cls1Obj);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPvE.generalized") ]
// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFvPvE.generalized") ]
(Obj2Ptr->*fp_f3)(&Cls1Obj);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvPKvE.generalized") ]
// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFvPKvE.generalized") ]
(Obj2Ptr->*fp_f4)(&Cls1Obj);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvR4Cls1E.generalized") ]
// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFvR4Cls1E.generalized") ]
(Obj2Ptr->*fp_f5)(Cls1Obj);

// CST: call void %{{.*}} [ "type"(metadata !"_ZTSFvRK4Cls1E.generalized") ]
// CST: call void %{{.*}} [ "callee_type"(metadata !"_ZTSFvRK4Cls1E.generalized") ]
(Obj2Ptr->*fp_f6)(Cls1Obj);
}
81 changes: 41 additions & 40 deletions clang/test/CodeGen/call-graph-section-3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,44 @@
// Class definitions (check for indirect target metadata)

class Base {
public:
// FT-DAG: define {{.*}} @_ZN4Base2vfEPc({{.*}} !type [[F_TVF:![0-9]+]]
virtual int vf(char *a) { return 0; };
};

class Derived : public Base {
public:
// FT-DAG: define {{.*}} @_ZN7Derived2vfEPc({{.*}} !type [[F_TVF]]
int vf(char *a) override { return 1; };
};

// FT-DAG: [[F_TVF]] = !{i64 0, !"_ZTSFiPvE.generalized"}

////////////////////////////////////////////////////////////////////////////////
// Callsites (check for indirect callsite operand bundles)

// CST-LABEL: define {{.*}} @_Z3foov
void foo() {
auto B = Base();
auto D = Derived();

Base *Bptr = &B;
Base *BptrToD = &D;
Derived *Dptr = &D;

auto FpBaseVf = &Base::vf;
auto FpDerivedVf = &Derived::vf;

// CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
(Bptr->*FpBaseVf)(0);

// CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
(BptrToD->*FpBaseVf)(0);

// CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
(Dptr->*FpBaseVf)(0);

// CST: call noundef i32 %{{.*}} [ "type"(metadata !"_ZTSFiPvE.generalized") ]
(Dptr->*FpDerivedVf)(0);
}
public:
// FT-DAG: define {{.*}} @_ZN4Base2vfEPc({{.*}} !type [[F_TVF:![0-9]+]]
virtual int vf(char *a) { return 0; };
};

class Derived : public Base {
public:
// FT-DAG: define {{.*}} @_ZN7Derived2vfEPc({{.*}} !type [[F_TVF]]
int vf(char *a) override { return 1; };
};

// FT-DAG: [[F_TVF]] = !{i64 0, !"_ZTSFiPvE.generalized"}

////////////////////////////////////////////////////////////////////////////////
// Callsites (check for indirect callsite operand bundles)

// CST-LABEL: define {{.*}} @_Z3foov
void foo() {
auto B = Base();
auto D = Derived();

Base *Bptr = &B;
Base *BptrToD = &D;
Derived *Dptr = &D;

auto FpBaseVf = &Base::vf;
auto FpDerivedVf = &Derived::vf;

// CST: call noundef i32 %{{.*}} [ "callee_type"(metadata !"_ZTSFiPvE.generalized") ]
(Bptr->*FpBaseVf)(0);

// CST: call noundef i32 %{{.*}} [ "callee_type"(metadata !"_ZTSFiPvE.generalized") ]
(BptrToD->*FpBaseVf)(0);

// CST: call noundef i32 %{{.*}} [ "callee_type"(metadata !"_ZTSFiPvE.generalized") ]
(Dptr->*FpBaseVf)(0);

// CST: call noundef i32 %{{.*}} [ "callee_type"(metadata !"_ZTSFiPvE.generalized") ]
(Dptr->*FpDerivedVf)(0);
}

Loading
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.