[clang] [clang][ClangIR]: Fixes no_prototype C functions CIR lowering. (PR #213478)
Lucas Ribeiro via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 1 11:44:47 PDT 2026
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 <lucasribeirolima974 at gmail.com>
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
More information about the cfe-commits
mailing list