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

Reply via email to