This is the mail archive of the gcc-patches@gcc.gnu.org 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]

[patch] fix overlapping constructors block cleared too early


Hello,

For records/unions/arrays, gimplify_init_constructor chooses to block clear
the whole assignment target in some circumstances, for instance

   /* If there are "lots" of zeros, then block clear the object first.  */

It also has a general provision to deal with constructor elements
possibly referencing the target, by way of a so called "preevaluation"
helper to capture the overlapping elements into temporaries.

Unfortunately, block clearing currently happens before preevaluation,
so when an assignment involves both, the overlapping values are lost
(zeroed) by the time they are captured.

This is very visible on the simple Ada testcase below, which fails
on virtually any target with Pressure.Value being zero instead of 256
after the aggregate assignment.

   procedure self_aggregate_with_zeros is

      type Sensor is record
	 Value  : Natural;
	 A, B, C, D, E, F, G, H, I, J, K, L, M : Natural;
      end record;

      Pressure : Sensor;
   begin
      Pressure.Value := 256;
      Pressure := (Pressure.Value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

      if Pressure.Value /= 256 then
	 raise Program_Error;
      end if;
   end;

The resulting sequence on x86-linux is clear:

  pressure.value = 256;

  pressure = {};              <== block clear

  D.600 = pressure.value;     <== capture overlapping component, too late
                                  (zeroed out by the block clearing)

  pressure.value = D.600;     <== reassign

  D.601 = pressure.value;
  if (D.601 != 256)
    {
       ... raise ...
    }

The user visible failure is a regression compared to the GCC 3.4 series.

The attached patch is a suggestion to address this issue, by simply
moving the preevaluation up before the block clearing statements.

It has been bootstrapped and successfully regression tested with all+ada
languages on i686-pc-linux-gnu.

Thanks in advance,

Olivier


2006-07-27  Olivier Hainque  <hainque@adacore.com>

        * gimplify.c (gimplify_init_constructor) <RECORD,UNION,ARRAY types>:
        Arrange for the temporary captures of components overlapping the lhs
        to happen before the lhs is possibly cleared.

        * gnat.dg/self_aggregate_with_zeros.adb: New test.
        * gnat.dg/self_aggregate_with_array.adb: New test.






Attachment: early-preeval.dif
Description: Text document


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