https://github.com/sga-sc created 
https://github.com/llvm/llvm-project/pull/150022

Consider this declaration:

`int foo();`

This function is described in LLVM with `clang::FunctionNoProtoType` class. 
([See 
description](https://clang.llvm.org/doxygen/classclang_1_1FunctionNoProtoType.html))

Judging by [this 
comment](https://github.com/llvm/llvm-project/blob/a1bf0d1394e48894be05d274d3942ff77c35ce87/clang/lib/CodeGen/CGCall.cpp#L159C11-L159C12)
 all such functions are treated like functions with variadic number of 
parameters.

When we want to [emit debug 
info](https://github.com/llvm/llvm-project/blob/0a8ddd396546bec7eaa4c3b7ef2f495e52bca0b8/clang/lib/CodeGen/CGDebugInfo.cpp#L4808)
 we have to know function that we calling.

In method 
[getCalledFunction()](https://github.com/llvm/llvm-project/blob/0a8ddd396546bec7eaa4c3b7ef2f495e52bca0b8/llvm/include/llvm/IR/InstrTypes.h#L1348)
 we compare two types of function:

1. Function that we deduce from calling operand, and
2. Function that we store locally

If they differ we get `nullptr` and can't emit appropriate debug info.

The only thing they differ is: lhs function is variadic, but rhs function isn't

Reason of this difference is that under RISC-V there is no overridden function 
that tells us about treating functions with no parameters. [Default 
function](https://github.com/llvm/llvm-project/blob/0a8ddd396546bec7eaa4c3b7ef2f495e52bca0b8/clang/lib/CodeGen/TargetInfo.cpp#L87)
 always return `false`.

This patch overrides this function for RISC-V

>From 4822a7b7f2e7c10baab92001f0d8243383fa00c8 Mon Sep 17 00:00:00 2001
From: Georgiy Samoylov <g.samoy...@syntacore.com>
Date: Tue, 22 Jul 2025 16:10:48 +0300
Subject: [PATCH] [clang][RISCV] Fix clang dwarf info generation for
 unprtototyped function

---
 clang/lib/CodeGen/Targets/RISCV.cpp           |  5 ++++
 .../CodeGen/RISCV/debug-info-emit-func-decl.c | 27 +++++++++++++++++++
 .../RISCV/debug-info-emit-func-decl.cpp       | 27 +++++++++++++++++++
 3 files changed, 59 insertions(+)
 create mode 100644 clang/test/CodeGen/RISCV/debug-info-emit-func-decl.c
 create mode 100644 clang/test/CodeGen/RISCV/debug-info-emit-func-decl.cpp

diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp 
b/clang/lib/CodeGen/Targets/RISCV.cpp
index e3232b61a693c..6c2ce5c96ce4a 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -842,6 +842,11 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
 
     Fn->addFnAttr("interrupt", Kind);
   }
+
+  bool isNoProtoCallVariadic(const CallArgList &,
+                             const FunctionNoProtoType *) const override {
+    return true;
+  }
 };
 } // namespace
 
diff --git a/clang/test/CodeGen/RISCV/debug-info-emit-func-decl.c 
b/clang/test/CodeGen/RISCV/debug-info-emit-func-decl.c
new file mode 100644
index 0000000000000..e580cb2702047
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/debug-info-emit-func-decl.c
@@ -0,0 +1,27 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 -debug-info-kind=limited -dwarf-version=4 
-debugger-tuning=gdb -O2 -emit-llvm %s -o - | FileCheck %s 
--check-prefix=CHECK-RV64
+// RUN: %clang_cc1 -triple riscv64 -debug-info-kind=limited -dwarf-version=4 
-debugger-tuning=lldb -O2 -emit-llvm %s -o - | FileCheck %s 
--check-prefix=CHECK-RV64
+// RUN: %clang_cc1 -triple riscv64 -debug-info-kind=limited -dwarf-version=5 
-O2 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-RV64
+
+// RUN: %clang_cc1 -triple riscv32 -debug-info-kind=limited -dwarf-version=4 
-debugger-tuning=gdb -O2 -emit-llvm %s -o - | FileCheck %s 
--check-prefix=CHECK-RV32
+// RUN: %clang_cc1 -triple riscv32 -debug-info-kind=limited -dwarf-version=4 
-debugger-tuning=lldb -O2 -emit-llvm %s -o - | FileCheck %s 
--check-prefix=CHECK-RV32
+// RUN: %clang_cc1 -triple riscv32 -debug-info-kind=limited -dwarf-version=5 
-O2 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-RV32
+
+// CHECK-RV64: declare !dbg ![[FOO:[0-9]+]] void @foo(...) local_unnamed_addr 
#[[ATTR0:[0-9]+]]
+// CHECK-RV32: declare !dbg ![[FOO:[0-9]+]] void @foo(...) local_unnamed_addr 
#[[ATTR0:[0-9]+]]
+void foo();
+
+// CHECK-RV64: declare !dbg ![[BAR:[0-9]+]] void @bar() local_unnamed_addr 
#[[ATTR0:[0-9]+]]
+// CHECK-RV32: declare !dbg ![[BAR:[0-9]+]] void @bar() local_unnamed_addr 
#[[ATTR0:[0-9]+]]
+void bar(void);
+
+// CHECK-RV64: declare !dbg ![[BAZ:[0-9]+]] void @baz(i32 noundef signext, 
...) local_unnamed_addr #[[ATTR0:[0-9]+]]
+// CHECK-RV32: declare !dbg ![[BAZ:[0-9]+]] void @baz(i32 noundef, ...) 
local_unnamed_addr #[[ATTR0:[0-9]+]]
+void baz(int a, ...);
+
+int main() {
+  foo();
+  bar();
+  baz(1);
+  return 0;
+}
diff --git a/clang/test/CodeGen/RISCV/debug-info-emit-func-decl.cpp 
b/clang/test/CodeGen/RISCV/debug-info-emit-func-decl.cpp
new file mode 100644
index 0000000000000..48f5540b4be78
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/debug-info-emit-func-decl.cpp
@@ -0,0 +1,27 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 -debug-info-kind=limited -dwarf-version=4 
-debugger-tuning=gdb -O2 -emit-llvm %s -o - | FileCheck %s 
--check-prefix=CHECK-RV64
+// RUN: %clang_cc1 -triple riscv64 -debug-info-kind=limited -dwarf-version=4 
-debugger-tuning=lldb -O2 -emit-llvm %s -o - | FileCheck %s 
--check-prefix=CHECK-RV64
+// RUN: %clang_cc1 -triple riscv64 -debug-info-kind=limited -dwarf-version=5 
-O2 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-RV64
+
+// RUN: %clang_cc1 -triple riscv32 -debug-info-kind=limited -dwarf-version=4 
-debugger-tuning=gdb -O2 -emit-llvm %s -o - | FileCheck %s 
--check-prefix=CHECK-RV32
+// RUN: %clang_cc1 -triple riscv32 -debug-info-kind=limited -dwarf-version=4 
-debugger-tuning=lldb -O2 -emit-llvm %s -o - | FileCheck %s 
--check-prefix=CHECK-RV32
+// RUN: %clang_cc1 -triple riscv32 -debug-info-kind=limited -dwarf-version=5 
-O2 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-RV32
+
+// CHECK-RV64: declare !dbg ![[FOO:[0-9]+]] void @_Z3foov() local_unnamed_addr 
#[[ATTR0:[0-9]+]]
+// CHECK-RV32: declare !dbg ![[FOO:[0-9]+]] void @_Z3foov() local_unnamed_addr 
#[[ATTR0:[0-9]+]]
+void foo();
+
+// CHECK-RV64: declare !dbg ![[BAR:[0-9]+]] void @_Z3barv() local_unnamed_addr 
#[[ATTR0:[0-9]+]]
+// CHECK-RV32: declare !dbg ![[BAR:[0-9]+]] void @_Z3barv() local_unnamed_addr 
#[[ATTR0:[0-9]+]]
+void bar(void);
+
+// CHECK-RV64: declare !dbg ![[BAZ:[0-9]+]] void @_Z3baziz(i32 noundef 
signext, ...) local_unnamed_addr #[[ATTR0:[0-9]+]]
+// CHECK-RV32: declare !dbg ![[BAZ:[0-9]+]] void @_Z3baziz(i32 noundef, ...) 
local_unnamed_addr #[[ATTR0:[0-9]+]]
+void baz(int a, ...);
+
+int main() {
+  foo();
+  bar();
+  baz(1);
+  return 0;
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to