Since a backend may ignore user type alignment for arguments passed on
stack, check backend for argument alignment on stack when evaluating
__alignof.

gcc/c-family/

PR c/89544
* c-common.cc (c_alignof_expr): Check backend for argument
alignment on stack.

gcc/testsuite/

PR c/89544
* gcc.target/i386/pr89544.c: New test.


-- 
H.J.
From 1f395b8268ba87121546a082e9111fe4b9ad0ab5 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.to...@gmail.com>
Date: Sat, 28 Jun 2025 08:07:51 +0800
Subject: [PATCH] c-family: Check backend for argument alignment on stack

Since a backend may ignore user type alignment for arguments passed on
stack, check backend for argument alignment on stack when evaluating
__alignof.

gcc/c-family/

	PR c/89544
	* c-common.cc (c_alignof_expr): Check backend for argument
	alignment on stack.

gcc/testsuite/

	PR c/89544
	* gcc.target/i386/pr89544.c: New test.

Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
---
 gcc/c-family/c-common.cc                | 11 ++++++++
 gcc/testsuite/gcc.target/i386/pr89544.c | 36 +++++++++++++++++++++++++
 2 files changed, 47 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr89544.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index f71cb2652d5..768cf994ffa 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -4076,6 +4076,17 @@ c_alignof_expr (location_t loc, tree expr)
 	}
       return c_alignof (loc, TREE_TYPE (TREE_TYPE (best)));
     }
+  else if (TREE_CODE (expr) == PARM_DECL)
+    {
+      /* User alignment on type may be ignored for parameter passed on
+	 stack.  */
+      tree type = TREE_TYPE (expr);
+      unsigned int alignment
+	= targetm.calls.function_arg_boundary (TYPE_MODE (type),
+					       type);
+      tree value = size_int (alignment / BITS_PER_UNIT);
+      return value;
+    }
   else
     return c_alignof (loc, TREE_TYPE (expr));
 
diff --git a/gcc/testsuite/gcc.target/i386/pr89544.c b/gcc/testsuite/gcc.target/i386/pr89544.c
new file mode 100644
index 00000000000..59ebf429526
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr89544.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef struct {
+  long double a;
+  long double b;
+} c1 __attribute__((aligned(32)));
+extern c1 x1;
+void
+foo1 (c1 f)
+{
+  c1 x = f;
+  x1 = x;
+  _Static_assert (__alignof (x) == 32, "__alignof (x) == 32");
+  _Static_assert (__alignof (f) == __alignof (long double),
+		  "__alignof (f) == __alignof (long double)");
+  _Static_assert (__alignof (f.a) == __alignof (long double),
+		  "__alignof (f.a) == __alignof (long double)");
+}
+
+typedef struct {
+  long double a;
+  long double b;
+} c2 __attribute__((aligned(1)));
+extern c2 x2;
+void
+foo2 (c2 f)
+{
+  c2 x = f;
+  x2 = x;
+  _Static_assert (__alignof (x) == 1, "__alignof (x) == 1");
+  _Static_assert (__alignof (f) == __alignof (long double),
+		  "__alignof (f) == __alignof (long double)");
+  _Static_assert (__alignof (f.a) == __alignof (long double),
+		  "__alignof (f.a) == __alignof (long double)");
+}
-- 
2.50.0

Reply via email to