[clang] [CIR] Fix verifier error for no-proto calls with multiple arguments (PR #182626)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 20 16:07:07 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: None (valium007)
<details>
<summary>Changes</summary>
Fixes #<!-- -->182175
---
Full diff: https://github.com/llvm/llvm-project/pull/182626.diff
2 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+10-3)
- (modified) clang/test/CIR/CodeGen/no-prototype.c (+12)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 83d51bac01d1e..1989ead7e748a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2039,9 +2039,16 @@ RValue CIRGenFunction::emitCall(clang::QualType calleeTy,
assert(!cir::MissingFeatures::opCallChain());
assert(!cir::MissingFeatures::addressSpace());
cir::FuncType calleeTy = getTypes().getFunctionType(funcInfo);
- // get non-variadic function type
- calleeTy = cir::FuncType::get(calleeTy.getInputs(),
- calleeTy.getReturnType(), false);
+
+ // For unprototyped functions, funcInfo was built with RequiredArgs(0) so
+ // calleeTy.getInputs() is empty. So we build the non-variadic callee type from
+ // the actual promoted argument types instead.
+ SmallVector<mlir::Type, 8> promotedArgTypes;
+ for (const CallArg &arg : args)
+ promotedArgTypes.push_back(convertType(arg.ty));
+ calleeTy = cir::FuncType::get(promotedArgTypes,
+ calleeTy.getReturnType(), /*isVarArg=*/false);
+
auto calleePtrTy = cir::PointerType::get(calleeTy);
mlir::Operation *fn = callee.getFunctionPointer();
diff --git a/clang/test/CIR/CodeGen/no-prototype.c b/clang/test/CIR/CodeGen/no-prototype.c
index d266ccb86448a..e5d4f601aec9f 100644
--- a/clang/test/CIR/CodeGen/no-prototype.c
+++ b/clang/test/CIR/CodeGen/no-prototype.c
@@ -82,3 +82,15 @@ int test5(int x) {
}
int noProto5(int x) { return x; }
// CHECK: cir.func {{.*}} no_proto {{.*}} @noProto5(%arg0: !s32i {{.+}}) -> !s32i
+
+// No-proto declaration without definition, called with multiple args of
+// different types. This is the "printf without a header" case and exercises
+// the promoted-arg-type path in emitCall.
+int noProto6();
+int test6(int x) {
+// CHECK: cir.func {{.*}} @test6
+ return noProto6("hello", x);
+ // CHECK: [[GGO:%.*]] = cir.get_global @noProto6 : !cir.ptr<!cir.func<(...) -> !s32i>>
+ // CHECK: [[CAST:%.*]] = cir.cast bitcast [[GGO]] : !cir.ptr<!cir.func<(...) -> !s32i>> -> !cir.ptr<!cir.func<(!cir.ptr<!s8i>, !s32i) -> !s32i>>
+ // CHECK: {{%.*}} = cir.call [[CAST]](%{{.*}}, %{{.*}}) : (!cir.ptr<!cir.func<(!cir.ptr<!s8i>, !s32i) -> !s32i>>, !cir.ptr<!s8i>, !s32i) -> !s32i
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/182626
More information about the cfe-commits
mailing list