https://github.com/resistor created 
https://github.com/llvm/llvm-project/pull/148541

This fixes an issue reported in 
https://github.com/llvm/llvm-project/issues/148536 where
writes to flexible array members would sometimes be lost if the struct happened 
to hit
one of the cases where it would be passed in GPRs rather than on the stack.


>From 83495625bddb6e4e5fce6bb11d655c6e1628c5e0 Mon Sep 17 00:00:00 2001
From: Owen Anderson <resis...@mac.com>
Date: Mon, 14 Jul 2025 00:32:55 +0700
Subject: [PATCH] [clang][RISCV] Always pass & return flexible array member
 structs indirectly.

This fixes an issue reported in 
https://github.com/llvm/llvm-project/issues/148536 where
writes to flexible array members would sometimes be lost if the struct happened 
to hit
one of the cases where it would be passed in GPRs rather than on the stack.
---
 clang/lib/CodeGen/Targets/RISCV.cpp           |  4 ++
 .../RISCV/abi-flexible-array-members.cpp      | 46 +++++++++++++++++++
 2 files changed, 50 insertions(+)
 create mode 100644 clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp

diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp 
b/clang/lib/CodeGen/Targets/RISCV.cpp
index e3232b61a693c..5bf0f29903f56 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -609,6 +609,10 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, 
bool IsFixed,
   if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
     return ABIArgInfo::getIgnore();
 
+  // Structures with flexible arrays are always indirect.
+  if (Ty->isStructureTypeWithFlexibleArrayMember())
+    return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
+
   // Pass floating point values via FPRs if possible.
   if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
       FLen >= Size && ArgFPRsLeft) {
diff --git a/clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp 
b/clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp
new file mode 100644
index 0000000000000..b6f25982fd3f6
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp
@@ -0,0 +1,46 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --filter "^define |^entry:" --version 2
+// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-abi 
ilp32f -emit-llvm %s -o - \
+// RUN:   | FileCheck -check-prefixes=CHECK32 %s
+// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-feature 
+d -target-abi ilp32d -emit-llvm %s -o - \
+// RUN:   | FileCheck -check-prefixes=CHECK32 %s
+// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-abi lp64f 
-emit-llvm %s -o - \
+// RUN:   | FileCheck -check-prefixes=CHECK64 %s
+// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-feature 
+d -target-abi lp64d -emit-llvm %s -o - \
+// RUN:   | FileCheck -check-prefixes=CHECK64 %s
+
+#include <stdint.h>
+
+// Structs containing C99 flexible array members should always be passed and 
returned on the stack.
+
+struct s1 {
+    int a;
+    int b[];
+};
+
+// CHECK32-LABEL: define dso_local void @_Z7test_012s1
+// CHECK32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) 
align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_S1]]) align 4 [[A:%.*]]) 
#[[ATTR0:[0-9]+]] {
+// CHECK32:  entry:
+//
+// CHECK64-LABEL: define dso_local void @_Z7test_012s1
+// CHECK64-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) 
align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_S1]]) align 4 [[A:%.*]]) 
#[[ATTR0:[0-9]+]] {
+// CHECK64:  entry:
+//
+struct s1 test_01(struct s1 a) {
+  return a;
+}
+
+
+// CHECK32-LABEL: define dso_local void @_Z7test_02v
+// CHECK32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) 
align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] {
+// CHECK32:  entry:
+//
+// CHECK64-LABEL: define dso_local void @_Z7test_02v
+// CHECK64-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) 
align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] {
+// CHECK64:  entry:
+//
+struct s1 test_02() {
+    struct s1 r;
+    r.a = 0;
+    r.b[0] = 1;
+    return r;
+}

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

Reply via email to