expr.c (target_align): New function.
* expr.c (target_align): New function. Alignment the TARGET of an assignment may be assume to have. (highest_pow2_factor_for_target): Use it instead of relying on immediate tree attributes of TARGET, not necessarily honored when intermediate bitfields are involved. testsuite/ * gcc.c-torture/execute/align-nest.c: New testcase. * gnat.dg/misaligned_nest.adb: New testcase. Co-Authored-By: Eric Botcazou <ebotcazou@adacore.com> From-SVN: r147916
This commit is contained in:
parent
c1df0e1ac5
commit
ceadb728b0
@ -1,3 +1,11 @@
|
||||
2009-05-28 Olivier Hainque <hainque@adacore.com>
|
||||
|
||||
* expr.c (target_align): New function. Alignment the TARGET of an
|
||||
assignment may be assume to have.
|
||||
(highest_pow2_factor_for_target): Use it instead of relying on
|
||||
immediate tree attributes of TARGET, not necessarily honored when
|
||||
intermediate bitfields are involved.
|
||||
|
||||
2009-05-27 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/40266
|
||||
|
49
gcc/expr.c
49
gcc/expr.c
@ -6224,6 +6224,45 @@ component_ref_field_offset (tree exp)
|
||||
else
|
||||
return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
|
||||
}
|
||||
|
||||
/* Alignment in bits the TARGET of an assignment may be assumed to have. */
|
||||
|
||||
static unsigned HOST_WIDE_INT
|
||||
target_align (const_tree target)
|
||||
{
|
||||
/* We might have a chain of nested references with intermediate misaligning
|
||||
bitfields components, so need to recurse to find out. */
|
||||
|
||||
unsigned HOST_WIDE_INT this_align, outer_align;
|
||||
|
||||
switch (TREE_CODE (target))
|
||||
{
|
||||
case BIT_FIELD_REF:
|
||||
return 1;
|
||||
|
||||
case COMPONENT_REF:
|
||||
this_align = DECL_ALIGN (TREE_OPERAND (target, 1));
|
||||
outer_align = target_align (TREE_OPERAND (target, 0));
|
||||
return MIN (this_align, outer_align);
|
||||
|
||||
case ARRAY_REF:
|
||||
case ARRAY_RANGE_REF:
|
||||
this_align = TYPE_ALIGN (TREE_TYPE (target));
|
||||
outer_align = target_align (TREE_OPERAND (target, 0));
|
||||
return MIN (this_align, outer_align);
|
||||
|
||||
CASE_CONVERT:
|
||||
case NON_LVALUE_EXPR:
|
||||
case VIEW_CONVERT_EXPR:
|
||||
this_align = TYPE_ALIGN (TREE_TYPE (target));
|
||||
outer_align = target_align (TREE_OPERAND (target, 0));
|
||||
return MAX (this_align, outer_align);
|
||||
|
||||
default:
|
||||
return TYPE_ALIGN (TREE_TYPE (target));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Given an rtx VALUE that may contain additions and multiplications, return
|
||||
an equivalent value that just refers to a register, memory, or constant.
|
||||
@ -6670,14 +6709,10 @@ highest_pow2_factor (const_tree exp)
|
||||
static unsigned HOST_WIDE_INT
|
||||
highest_pow2_factor_for_target (const_tree target, const_tree exp)
|
||||
{
|
||||
unsigned HOST_WIDE_INT target_align, factor;
|
||||
unsigned HOST_WIDE_INT talign = target_align (target) / BITS_PER_UNIT;
|
||||
unsigned HOST_WIDE_INT factor = highest_pow2_factor (exp);
|
||||
|
||||
factor = highest_pow2_factor (exp);
|
||||
if (TREE_CODE (target) == COMPONENT_REF)
|
||||
target_align = DECL_ALIGN_UNIT (TREE_OPERAND (target, 1));
|
||||
else
|
||||
target_align = TYPE_ALIGN_UNIT (TREE_TYPE (target));
|
||||
return MAX (factor, target_align);
|
||||
return MAX (factor, talign);
|
||||
}
|
||||
|
||||
/* Return &VAR expression for emulated thread local VAR. */
|
||||
|
@ -1,3 +1,9 @@
|
||||
2009-05-28 Olivier Hainque <hainque@adacore.com>
|
||||
Eric Botcazou <botcazou@adacore.com>
|
||||
|
||||
* gcc.c-torture/execute/align-nest.c: New testcase.
|
||||
* gnat.dg/misaligned_nest.adb: New testcase.
|
||||
|
||||
2009-05-27 Rafael Avila de Espindola <espindola@google.com>
|
||||
|
||||
* g++.dg/plugin/attribute_plugin.c: Include gcc-plugin.h first.
|
||||
|
28
gcc/testsuite/gcc.c-torture/execute/align-nest.c
Normal file
28
gcc/testsuite/gcc.c-torture/execute/align-nest.c
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
void foo(int n)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
int value;
|
||||
} myint;
|
||||
|
||||
struct S
|
||||
{
|
||||
int i[n];
|
||||
unsigned int b:1;
|
||||
myint mi;
|
||||
} __attribute__ ((packed)) __attribute__ ((aligned (4)));
|
||||
|
||||
struct S s[2];
|
||||
int k;
|
||||
|
||||
for (k = 0; k < 2; k ++)
|
||||
s[k].mi.value = 0;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
foo (2);
|
||||
return 0;
|
||||
}
|
||||
|
26
gcc/testsuite/gnat.dg/misaligned_nest.adb
Normal file
26
gcc/testsuite/gnat.dg/misaligned_nest.adb
Normal file
@ -0,0 +1,26 @@
|
||||
-- { dg-do run }
|
||||
-- { dg-options "-gnatp" }
|
||||
|
||||
procedure Misaligned_Nest is
|
||||
|
||||
type Int is record
|
||||
V : Integer;
|
||||
end record;
|
||||
|
||||
type Block is record
|
||||
B : Boolean;
|
||||
I : Int;
|
||||
end record;
|
||||
pragma Pack (Block);
|
||||
for Block'Alignment use 1;
|
||||
|
||||
type Pair is array (1 .. 2) of Block;
|
||||
|
||||
P : Pair;
|
||||
begin
|
||||
for K in P'Range loop
|
||||
P(K).I.V := 1;
|
||||
end loop;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user