Hi,

as spotted by Richard B., there is an oversight in the implementation of 
CONSTRUCTOR_NO_CLEARING in the gimplifier: it may be overruled depending on 
the outcome of the clearing heuristics.

Tested on x86-64/Linux, OK for the mainline?  Can I put this on the 8 and 7 
branches too (only the Ada compiler sets the flag at the moment)?


2018-06-19  Eric Botcazou  <ebotca...@adacore.com>

        * gimplify.c (gimplify_init_constructor): Really never clear for an
        incomplete constructor if CONSTRUCTOR_NO_CLEARING is set.


2018-06-19  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/aggr24.adb: New test.
        * gnat.dg/aggr24_pkg.ad[sb]: New helper.

-- 
Eric Botcazou
Index: gimplify.c
===================================================================
--- gimplify.c	(revision 261687)
+++ gimplify.c	(working copy)
@@ -4795,7 +4795,7 @@ gimplify_init_constructor (tree *expr_p,
 	     objects.  Initializers for such objects must explicitly set
 	     every field that needs to be set.  */
 	  cleared = false;
-	else if (!complete_p && !CONSTRUCTOR_NO_CLEARING (ctor))
+	else if (!complete_p)
 	  /* If the constructor isn't complete, clear the whole object
 	     beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
 
@@ -4804,7 +4804,7 @@ gimplify_init_constructor (tree *expr_p,
 	     we'd need to *find* the elements that are not present, and that
 	     requires trickery to avoid quadratic compile-time behavior in
 	     large cases or excessive memory use in small cases.  */
-	  cleared = true;
+	  cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
 	else if (num_ctor_elements - num_nonzero_elements
 		 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
 		 && num_nonzero_elements < num_ctor_elements / 4)
-- { dg-do run }

with Aggr24_Pkg; use Aggr24_Pkg;

procedure Aggr24 is
  V : Rec;
begin
  V.S := "Hello";
  Init (V);
  if V.S /= "Hello" then
    raise Program_Error;
  end if;
end;
package Aggr24_Pkg is

   type Rec is record
      I1 : Integer;
      I2 : Integer;
      I3 : Integer;
      I4 : Integer;
      I5 : Integer;
      I6 : Integer;
      I7 : Integer;
      S : String (1 .. 5);
   end record;

   procedure Init (R : out Rec);

end Aggr24_Pkg;
package body Aggr24_Pkg is

   procedure Init (R : out Rec) is
   begin
      R := (I1 => 0,
            I2 => 0,
            I3 => 0,
            I4 => 0,
            I5 => 0,
            I6 => 0,
            I7 => 0,
            S => <>);
   end;
   
end Aggr24_Pkg;

Reply via email to