This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

fix overoptimistic assumption on lhs alignments


On a couple of STRICT_ALIGNMENT platforms (e.g. hppa-hpux), the Ada
testcase below gets a spurious SIGBUS at runtime.

    procedure Misaligned_Nest is

       type Int is record
	  Value : 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;
       for K in P'Range loop
	  P(K).I.Value := 1;
       end loop;

It features an array of 2 records, each with an Integer component wrapped
into an inner record and packed at bit position 1 past a Boolean. The SIGBUS
triggers on the second round through the loop, from a misaligned word access
generated out of an optimistic assumption by

    /* Similar, except that the alignment requirements of TARGET are
       taken into account.  Assume it is at least as aligned as its
       type, unless it is a COMPONENT_REF in which case the layout of
       the structure gives the alignment.  */

    static unsigned HOST_WIDE_INT
    highest_pow2_factor_for_target (const_tree target, const_tree exp)

in particular:

  if (TREE_CODE (target) == COMPONENT_REF)
    target_align = DECL_ALIGN_UNIT (TREE_OPERAND (target, 1));

For our "P(K).I.Value" lhs, this gets us the alignment of the "Value" field
decl in Int, 4bytes. Unfortunately, the access is nested within an outer
bitfield here so the real target alignment is actually not even byte
aligned. Below is what the "target" tree at hand looks like:

<component_ref 7ae6f2d0
    type <integer_type 7ae629a0 integer

    arg 0 <component_ref 7ae6f2a8
        type <record_type misaligned_nest__int
            user align 32

        arg 0 <array_ref type <record_type misaligned_nest__block>

            arg 0 <component_ref type <array_type misaligned_nest__pair>
                arg 0 <var_decl 7ae03c00 p> arg 1 <field_decl 7ae03ba0 F>

            arg 1 <ssa_name 7aee3968 type <integer_type 7adf4310 integer>
                var <var_decl 7ae03c60 k>

        arg 1 <field_decl i type <record_type misaligned_nest__int>
            external packed bit-field nonaddressable SI
            align 1 offset_align 64
            offset <integer_cst 7ade99a0 constant 0>
            bit offset <integer_cst 7ade9920 constant 1>

    arg 1 <field_decl value type <integer_type integer>
        nonaddressable SI
        size <integer_cst 7ade94e0 32> unit size <integer_cst 7ade9280 4>
        align 32 offset_align 64 offset <integer_cst 7ade99a0 0>
        bit offset <integer_cst 7ade99c0 constant 0>

The C testcase below exposes the same issue:

    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;

The attach patch is a suggestion to address this by recursing in the "target"
tree to detect such cases.

It bootstraps and passes tests on hppa1.1-hp-hpux11.00.

Thanks in advance,


2009-05-18  Olivier Hainque  <>
            Eric Botcazou  <>

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

	* gnat.dg (misaligned_nest.adb): New test.
	* gcc.c-torture/execute/align-nest.c: New test.

Attachment: lhs-align.dif
Description: Text document

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]