https://github.com/valium007 created 
https://github.com/llvm/llvm-project/pull/182626

Fixes #182175 

>From 81b33c1d328e23ba5cd32e8b9cc1c0315b43949f Mon Sep 17 00:00:00 2001
From: valium007 <[email protected]>
Date: Sat, 21 Feb 2026 05:28:26 +0530
Subject: [PATCH] [CIR] Fix verifier error for no-proto calls with multiple
 arguments

When emitting a call through a FunctionNoProtoType, the callee type was
built from FnInfo's inputs which are empty (RequiredArgs(0) produces no
required params). This gave a zero-param non-variadic FuncType, causing
the CIR verifier to fire with "incorrect number of operands for callee"
whenever such a function was called with arguments (e.g. printf without
a header under -fno-builtin or -std=c89).

Fix by building the non-variadic callee type from the actual promoted
argument types (convertType(arg.ty)) instead, matching what classic
CodeGen does in CGCall.cpp.
---
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp  | 13 ++++++++++---
 clang/test/CIR/CodeGen/no-prototype.c | 12 ++++++++++++
 2 files changed, 22 insertions(+), 3 deletions(-)

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
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to