Skip to content

Commit 853ebb4

Browse files
committed
Fix handling of call via indirect reference
1 parent 27fdb6b commit 853ebb4

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,9 +1821,11 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {
18211821
const auto *funcDecl = cast<FunctionDecl>(declRef->getDecl());
18221822
return emitDirectCallee(funcDecl);
18231823
} else if (auto me = dyn_cast<MemberExpr>(e)) {
1824-
const auto *fd = cast<FunctionDecl>(me->getMemberDecl());
1825-
emitIgnoredExpr(me->getBase());
1826-
return emitDirectCallee(fd);
1824+
if (const auto *fd = dyn_cast<FunctionDecl>(me->getMemberDecl())) {
1825+
emitIgnoredExpr(me->getBase());
1826+
return emitDirectCallee(fd);
1827+
}
1828+
// Else fall through to the indirect reference handling below.
18271829
} else if (auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
18281830
return CIRGenCallee::forPseudoDestructor(pde);
18291831
}

clang/test/CIR/CodeGen/call-via-class-member-funcptr.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,53 @@ void fn1() { F f1; }
3434
// OGCG: define {{.*}} ptr @_ZN1F1bEv
3535
// OGCG: %[[VAR_H:.*]] = load i32, ptr @h
3636
// OGCG: %[[RET:.*]] = call noundef ptr @_ZN1A1bEi(i32 noundef %[[VAR_H]])
37+
38+
class B {
39+
public:
40+
B();
41+
int (&indirect_callee_int_ref)(int);
42+
};
43+
44+
class C {
45+
public:
46+
int call_indirect(int v) { return inner.indirect_callee_int_ref(v); };
47+
B inner;
48+
};
49+
50+
void fn2() { C c1; c1.call_indirect(2); }
51+
52+
// CIR: cir.func {{.*}} @_ZN1C13call_indirectEi(%[[THIS_ARG:.*]]: !cir.ptr<!rec_C> {{.*}}, %[[V_ARG:.*]]: !s32i {{.*}}) -> !s32i
53+
// CIR: %[[THIS_ADDR:.*]] = cir.alloca !cir.ptr<!rec_C>, !cir.ptr<!cir.ptr<!rec_C>>, ["this", init]
54+
// CIR: %[[V_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["v", init]
55+
// CIR: cir.store %[[THIS_ARG]], %[[THIS_ADDR]]
56+
// CIR: cir.store %[[V_ARG]], %[[V_ADDR]]
57+
// CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
58+
// CIR: %[[INNER:.*]] = cir.get_member %[[THIS]][0] {name = "inner"} : !cir.ptr<!rec_C> -> !cir.ptr<!rec_B>
59+
// CIR: %[[INDIRECT_CALLEE_PTR:.*]] = cir.get_member %[[INNER]][0] {name = "indirect_callee_int_ref"}
60+
// CIR: %[[INDIRECT_CALLEE:.*]] = cir.load %[[INDIRECT_CALLEE_PTR]]
61+
// CIR: %[[V:.*]] = cir.load{{.*}} %[[V_ADDR]] : !cir.ptr<!s32i>, !s32i
62+
// CIR: %[[RET:.*]] = cir.call %[[INDIRECT_CALLEE]](%[[V]])
63+
64+
// LLVM: define {{.*}} i32 @_ZN1C13call_indirectEi(ptr %[[THIS_ARG:.*]], i32 %[[V_ARG:.*]])
65+
// LLVM: %[[THIS_ADDR:.*]] = alloca ptr
66+
// LLVM: %[[V_ADDR:.*]] = alloca i32
67+
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
68+
// LLVM: store i32 %[[V_ARG]], ptr %[[V_ADDR]]
69+
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
70+
// LLVM: %[[INNER:.*]] = getelementptr %class.C, ptr %[[THIS]], i32 0, i32 0
71+
// LLVM: %[[INDIRECT_CALLEE_PTR:.*]] = getelementptr %class.B, ptr %[[INNER]], i32 0, i32 0
72+
// LLVM: %[[INDIRECT_CALLEE:.*]] = load ptr, ptr %[[INDIRECT_CALLEE_PTR]]
73+
// LLVM: %[[V:.*]] = load i32, ptr %[[V_ADDR]]
74+
// LLVM: %[[RET:.*]] = call i32 %[[INDIRECT_CALLEE]](i32 %[[V]])
75+
76+
// OGCG: define {{.*}} i32 @_ZN1C13call_indirectEi(ptr {{.*}} %[[THIS_ARG:.*]], i32 {{.*}} %[[V_ARG:.*]])
77+
// OGCG: %[[THIS_ADDR:.*]] = alloca ptr
78+
// OGCG: %[[V_ADDR:.*]] = alloca i32
79+
// OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
80+
// OGCG: store i32 %[[V_ARG]], ptr %[[V_ADDR]]
81+
// OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
82+
// OGCG: %[[INNER:.*]] = getelementptr inbounds nuw %class.C, ptr %[[THIS]], i32 0, i32 0
83+
// OGCG: %[[INDIRECT_CALLEE_PTR:.*]] = getelementptr inbounds nuw %class.B, ptr %[[INNER]], i32 0, i32 0
84+
// OGCG: %[[INDIRECT_CALLEE:.*]] = load ptr, ptr %[[INDIRECT_CALLEE_PTR]]
85+
// OGCG: %[[V:.*]] = load i32, ptr %[[V_ADDR]]
86+
// OGCG: %[[RET:.*]] = call noundef i32 %[[INDIRECT_CALLEE]](i32 noundef %[[V]])

0 commit comments

Comments
 (0)