diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2025-03-29 23:16:25 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2025-03-31 19:15:33 +0200 |
commit | 9fadadbbbc2b5352e5e70e0e1a9be9b447176913 (patch) | |
tree | 546f373331a3244509cea1c232f2393d2ad72d27 /gcc/d | |
parent | b9adf3a4c8112df1d74440157f578a8344ebe166 (diff) | |
download | gcc-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.cc | 6 | ||||
-rw-r--r-- | gcc/d/expr.cc | 2 | ||||
-rw-r--r-- | gcc/d/types.cc | 3 |
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)) |