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.
This commit is contained in:
parent
b9adf3a4c8
commit
9fadadbbbc
4 changed files with 38 additions and 1 deletions
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
28
gcc/testsuite/gdc.dg/torture/pr117002.d
Normal file
28
gcc/testsuite/gdc.dg/torture/pr117002.d
Normal file
|
@ -0,0 +1,28 @@
|
|||
// { dg-do compile }
|
||||
// { dg-additional-options "-Warray-bounds" }
|
||||
extern(C++) class C117002
|
||||
{
|
||||
ubyte[4] not_multiple_of_8;
|
||||
}
|
||||
|
||||
int pr117002a(void *p)
|
||||
{
|
||||
auto init = __traits(initSymbol, C117002);
|
||||
if (init.ptr + init.length <= p)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pr117002b(void *p)
|
||||
{
|
||||
auto init = __traits(initSymbol, C117002);
|
||||
p[0 .. init.length] = init[];
|
||||
}
|
||||
|
||||
void pr117002c()
|
||||
{
|
||||
scope var = new C117002;
|
||||
void *p = cast(void*)var;
|
||||
auto init = __traits(initSymbol, C117002);
|
||||
p[0 .. __traits(classInstanceSize, C117002)] = init[];
|
||||
}
|
Loading…
Add table
Reference in a new issue