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
