aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2025-03-29 23:16:25 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2025-03-31 19:15:33 +0200
commit9fadadbbbc2b5352e5e70e0e1a9be9b447176913 (patch)
tree546f373331a3244509cea1c232f2393d2ad72d27 /gcc/d
parentb9adf3a4c8112df1d74440157f578a8344ebe166 (diff)
downloadgcc-9fadadbbbc2b5352e5e70e0e1a9be9b447176913.zip
gcc-9fadadbbbc2b5352e5e70e0e1a9be9b447176913.tar.gz
gcc-9fadadbbbc2b5352e5e70e0e1a9be9b447176913.tar.bz2
d: Fix error with -Warray-bounds and -O2 [PR117002]
The record layout of class types in D don't get any tail padding, so it is possible for the `classInstanceSize' to not be a multiple of the `classInstanceAlignment'. Rather than setting the instance alignment on the underlying RECORD_TYPE, instead give the type an alignment of 1, which will mark it as TYPE_PACKED. The value of `classInstanceAlignment' is instead applied to the DECL_ALIGN of both the static `init' symbol, and the stack allocated variable used when generating `new' for a `scope' class. PR d/117002 gcc/d/ChangeLog: * decl.cc (aggregate_initializer_decl): Set explicit decl alignment of class instance. * expr.cc (ExprVisitor::visit (NewExp *)): Likewise. * types.cc (TypeVisitor::visit (TypeClass *)): Mark the record type of classes as packed. gcc/testsuite/ChangeLog: * gdc.dg/torture/pr117002.d: New test.
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/decl.cc6
-rw-r--r--gcc/d/expr.cc2
-rw-r--r--gcc/d/types.cc3
3 files changed, 10 insertions, 1 deletions
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 9fcfc56..250d148 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -2393,6 +2393,12 @@ aggregate_initializer_decl (AggregateDeclaration *decl)
SET_DECL_ALIGN (sinit, sd->alignment.get () * BITS_PER_UNIT);
DECL_USER_ALIGN (sinit) = true;
}
+ else if (sd == NULL)
+ {
+ /* Alignment of class is determined its biggest field alignment. */
+ SET_DECL_ALIGN (sinit, decl->alignsize * BITS_PER_UNIT);
+ DECL_USER_ALIGN (sinit) = true;
+ }
decl->sinit = sinit;
return sinit;
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 0415763..46e6514 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -2243,6 +2243,8 @@ public:
storage class, then the instance is allocated on the stack
rather than the heap or using the class specific allocator. */
tree var = build_local_temp (TREE_TYPE (type));
+ SET_DECL_ALIGN (var, cd->alignsize * BITS_PER_UNIT);
+ DECL_USER_ALIGN (var) = 1;
new_call = build_nop (type, build_address (var));
setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
}
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index 98074f1..ea62bc9 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -1278,7 +1278,8 @@ public:
build_type_decl (basetype, t->sym);
set_visibility_for_decl (basetype, t->sym);
apply_user_attributes (t->sym, basetype);
- finish_aggregate_type (t->sym->structsize, t->sym->alignsize, basetype);
+ /* The underlying record type of classes are packed. */
+ finish_aggregate_type (t->sym->structsize, 1, basetype);
/* Classes only live in memory, so always set the TREE_ADDRESSABLE bit. */
for (tree tv = basetype; tv != NULL_TREE; tv = TYPE_NEXT_VARIANT (tv))