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:
Olivier Hainque 2009-05-27 16:06:44 +00:00 committed by Olivier Hainque
parent c1df0e1ac5
commit ceadb728b0
5 changed files with 111 additions and 8 deletions

View File

@ -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

View File

@ -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. */

View File

@ -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.

View 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;
}

View 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;