https://github.com/lucaslive974 created https://github.com/llvm/llvm-project/pull/213478
Fix CIR to LLVM lowering for no_proto C functions (Fixes #213024) Since LLVM IR does not support an explicit no_proto representation, this change uses a variadic function signature to preserve the intended semantics. >From d17815b4b7c23c8ef9d82cb9afa129327eae329b Mon Sep 17 00:00:00 2001 From: lucaslive974 <[email protected]> Date: Thu, 30 Jul 2026 21:30:20 -0300 Subject: [PATCH] [clang][ClangIR]: Fixes no_prototype C functions CIR lowering. --- .../lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 14 ++++++++++++-- clang/test/CIR/CodeGen/attr-alias-no-proto.c | 8 ++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index c7e8f97f3a68f..a9fd9e6e7e59a 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -2510,11 +2510,21 @@ mlir::LogicalResult CIRToLLVMFuncOpLowering::matchAndRewrite( mlir::Type resultType = getTypeConverter()->convertType(fnType.getReturnType()); + // To match OGCG, a 'no_proto' function must be lowered to a variadic LLVM + // function type '(...)' to safely handle unspecified arguments. However, this + // fallback only applies to pure declarations and aliases that lack explicit + // parameters. We skip this fallback and emit a strict non-variadic signature + // if the function has a body, or if an alias redefines the type with explicit + // arguments. + bool isDeclOrAlias = op.isDeclaration() || (op.getAliaseeAttr() != nullptr); + bool isNoProto = + (op.getNoProto() && isDeclOrAlias) && (fnType.getNumInputs() == 0); + bool isVarArg = fnType.isVarArg() || isNoProto; + // Create the LLVM function operation. mlir::Type llvmFnTy = mlir::LLVM::LLVMFunctionType::get( resultType ? resultType : mlir::LLVM::LLVMVoidType::get(getContext()), - signatureConversion.getConvertedTypes(), - /*isVarArg=*/fnType.isVarArg()); + signatureConversion.getConvertedTypes(), isVarArg); // If this is an alias, it needs to be lowered to llvm::AliasOp. if (std::optional<llvm::StringRef> aliasee = op.getAliasee()) diff --git a/clang/test/CIR/CodeGen/attr-alias-no-proto.c b/clang/test/CIR/CodeGen/attr-alias-no-proto.c index c6e61bdca668a..c6fd9476411cb 100644 --- a/clang/test/CIR/CodeGen/attr-alias-no-proto.c +++ b/clang/test/CIR/CodeGen/attr-alias-no-proto.c @@ -5,14 +5,10 @@ // RUN: %clang_cc1 -std=c11 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll // RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s -// LLVM: @noproto_used = alias i32 (), ptr @noproto_used_target -// LLVM: @noproto_args = alias i32 (), ptr @noproto_args_target +// LLVM: @noproto_used = alias i32 (...), ptr @noproto_used_target +// LLVM: @noproto_args = alias i32 (...), ptr @noproto_args_target // LLVM: @noproto_args2 = alias i32 (i32, i32, i32), ptr @noproto_args_target2 -// FIXME(cir): we list no-proto for the alias in CIR, but perhaps lowering is -// missing it? We should be able to combine LLVM/OGCG check lines in this file. -// Filed: https://github.com/llvm/llvm-project/issues/213024 -// // OGCG: @noproto_used = alias i32 (...), ptr @noproto_used_target // OGCG: @noproto_args = alias i32 (...), ptr @noproto_args_target // OGCG: @noproto_args2 = alias i32 (i32, i32, i32), ptr @noproto_args_target2 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
