Author: Erich Keane Date: 2026-05-20T06:24:05-07:00 New Revision: f9585141ff3bc78ae7830c9f39ce562d660c5065
URL: https://github.com/llvm/llvm-project/commit/f9585141ff3bc78ae7830c9f39ce562d660c5065 DIFF: https://github.com/llvm/llvm-project/commit/f9585141ff3bc78ae7830c9f39ce562d660c5065.diff LOG: [CIR] Lower calling through a variable (#198672) We managed to miss a condition when lowering emitCallee, where a DeclRefExpr referenced a function object. This patch adds that condition, which will result in these being lowered properly as an indirect call. Added: Modified: clang/lib/CIR/CodeGen/CIRGenExpr.cpp clang/test/CIR/CodeGen/call.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 43f68e0bc6172..6a01513b3e25f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -2360,8 +2360,8 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) { "unexpected implicit cast on function pointers"); } else if (const auto *declRef = dyn_cast<DeclRefExpr>(e)) { // Resolve direct calls. - const auto *funcDecl = cast<FunctionDecl>(declRef->getDecl()); - return emitDirectCallee(funcDecl); + if (const auto *funcDecl = dyn_cast<FunctionDecl>(declRef->getDecl())) + return emitDirectCallee(funcDecl); } else if (auto me = dyn_cast<MemberExpr>(e)) { if (const auto *fd = dyn_cast<FunctionDecl>(me->getMemberDecl())) { emitIgnoredExpr(me->getBase()); diff --git a/clang/test/CIR/CodeGen/call.cpp b/clang/test/CIR/CodeGen/call.cpp index 70d45b9099d87..28b0479321131 100644 --- a/clang/test/CIR/CodeGen/call.cpp +++ b/clang/test/CIR/CodeGen/call.cpp @@ -130,4 +130,25 @@ void f16() { // LLVM-NEXT: %{{.+}} = call{{.*}} i32 @_Z3f15v() // LLVM: } +template<typename Func> +inline decltype(auto) TakesFunc(const Func &f) { + return f(); +} + +int Passed(); + +void use_TakesFunc() { + TakesFunc(Passed); +} + +// CIR-LABEL: _Z9TakesFuncIFivEEDcRKT_ +// CIR-NEXT: %[[FUNC_ALLOCA:.*]] = cir.alloca !cir.ptr<!cir.func<() -> !s32i>>, !cir.ptr<!cir.ptr<!cir.func<() -> !s32i>>>, ["f", init, const] +// CIR: %[[FUNC_LOAD:.*]] = cir.load %[[FUNC_ALLOCA]] : !cir.ptr<!cir.ptr<!cir.func<() -> !s32i>>>, !cir.ptr<!cir.func<() -> !s32i>> +// CIR-NEXT: %[[CALL:.*]] = cir.call %[[FUNC_LOAD]]() : (!cir.ptr<!cir.func<() -> !s32i>>) -> (!s32i {llvm.noundef}) + +// LLVM-LABEL: _Z9TakesFuncIFivEEDcRKT_ +// LLVM-NEXT: %[[FUNC_ALLOCA:.*]] = alloca ptr +// LLVM: %[[FUNC_LOAD:.*]] = load ptr, ptr %[[FUNC_ALLOCA]] +// LLVM-NEXT: %[[CALL:.*]] = call noundef i32 %[[FUNC_LOAD]]() + // LLVM: attributes #[[LLVM_ATTR_0]] = { nounwind } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
