[committed] d: Fix closure fields don't get same alignment as local variable [PR109144]

Message ID 20230316113935.325393-1-ibuclaw@gdcproject.org
State Committed
Commit 46c4be98d1e759a406069487e5dbaad0346e7e7d
Headers
Series [committed] d: Fix closure fields don't get same alignment as local variable [PR109144] |

Commit Message

Iain Buclaw March 16, 2023, 11:39 a.m. UTC
  Hi,

Local variables with both non-local references and explicit alignment
did not propagate their alignment to either the closure field or closure
frame type, resulting in the closure being misaligned. This is now
correctly set-up when building the frame type.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32,
committed to mainline and backported to releases/gcc-12.

I did have a look at backporting to gcc-11 too, however the D front-end
does not correctly set the alignment of local variables, so although the
code generation pass is doing the right thing, the alignment for the
local variable is never set in the first place.

Regards,
Iain.

---
	PR d/109144

gcc/d/ChangeLog:

	* d-codegen.cc (build_frame_type): Set frame field and type alignment.

gcc/testsuite/ChangeLog:

	* gdc.dg/torture/pr109144.d: New test.
---
 gcc/d/d-codegen.cc                      | 5 +++++
 gcc/testsuite/gdc.dg/torture/pr109144.d | 9 +++++++++
 2 files changed, 14 insertions(+)
 create mode 100644 gcc/testsuite/gdc.dg/torture/pr109144.d
  

Patch

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 5a041927ec9..5c6c300ecec 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -2706,6 +2706,11 @@  build_frame_type (tree ffi, FuncDeclaration *fd)
       TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym);
       DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym);
       TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym);
+      SET_DECL_ALIGN (field, DECL_ALIGN (vsym));
+
+      /* Update alignment for frame record type.  */
+      if (TYPE_ALIGN (frame_rec_type) < DECL_ALIGN (field))
+	SET_TYPE_ALIGN (frame_rec_type, DECL_ALIGN (field));
 
       if (DECL_LANG_NRVO (vsym))
 	{
diff --git a/gcc/testsuite/gdc.dg/torture/pr109144.d b/gcc/testsuite/gdc.dg/torture/pr109144.d
new file mode 100644
index 00000000000..32d3af7cd45
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr109144.d
@@ -0,0 +1,9 @@ 
+// { dg-do run }
+// { dg-skip-if "needs gcc/config.d" { ! d_runtime } }
+void main()
+{
+    align(128) byte var;
+    assert((cast(size_t) &var) % 128 == 0);
+    var = 73;
+    assert((() => var)() == 73);
+}