Commit f1e2bf65 by Eric Botcazou Committed by Pierre-Marie de Rodat

[Ada] Fix small regression with others choice in array aggregate

This change is aimed at fixing a fallout of bumping the default value of
the Max_Others_Replicate parameter of the Convert_To_Positional routine.
This parameter is responsible for taming the duplication of the
expression of an others choice in an array aggregate so that it doesn't
result in a code size explosion.

Unfortunately a fine-grained control based on the analysis of the
expression is not really possible because this analysis has not been
done yet by the time the decision is made in most cases, so the usual
syntactic ambiguities of the language come into play and make the
process a bit cumbersome.  For example, it is not possible to
distinguish a simple reference to a static constant declared in another
unit from a call to a parameterless function.

Therefore the change errs on the side of caution and allows the
duplication only if the expression is unambiguously static and
sufficiently simple.

For the following three aggregates, the duplication must be blocked and
the elaboration of the aggregates must be done by means of a loop:

with Q; use Q;

procedure P is

  A : Arr := (others => Get_Value);

  B : Arr := (others => Get_Other_Value (0));

  C : Arr := (others => Q.Get_Other_Value (1));

begin
  null;
end;

package Q is

  type Arr is array (1 .. 32) of Integer;

  function Get_Value return Integer;

  function Get_Other_Value (I : integer) return Integer;

end Q;

2018-11-14  Eric Botcazou  <ebotcazou@adacore.com>

gcc/ada/

	* exp_aggr.adb (Is_Static_Element): New predicate extracted
	from...
	(Check_Static_Components): ...here.  Call Is_Static_Element on
	each element of the component association list, if any.
	(Flatten): Duplicate the expression of an others choice only if
	it is static or is an aggregate which can itself be flattened.

From-SVN: r266135
parent 934d4736
2018-11-14 Eric Botcazou <ebotcazou@adacore.com>
* exp_aggr.adb (Is_Static_Element): New predicate extracted
from...
(Check_Static_Components): ...here. Call Is_Static_Element on
each element of the component association list, if any.
(Flatten): Duplicate the expression of an others choice only if
it is static or is an aggregate which can itself be flattened.
2018-11-14 Olivier Hainque <hainque@adacore.com> 2018-11-14 Olivier Hainque <hainque@adacore.com>
* sigtramp-vxworks-target.inc: Fix stack checking test errors in * sigtramp-vxworks-target.inc: Fix stack checking test errors in
......
...@@ -4302,8 +4302,6 @@ package body Exp_Aggr is ...@@ -4302,8 +4302,6 @@ package body Exp_Aggr is
-- Check whether all components of the aggregate are compile-time known -- Check whether all components of the aggregate are compile-time known
-- values, and can be passed as is to the back-end without further -- values, and can be passed as is to the back-end without further
-- expansion. -- expansion.
-- An Iterated_Component_Association is treated as nonstatic, but there
-- are possibilities for optimization here.
function Flatten function Flatten
(N : Node_Id; (N : Node_Id;
...@@ -4317,6 +4315,14 @@ package body Exp_Aggr is ...@@ -4317,6 +4315,14 @@ package body Exp_Aggr is
-- Return True iff the array N is flat (which is not trivial in the case -- Return True iff the array N is flat (which is not trivial in the case
-- of multidimensional aggregates). -- of multidimensional aggregates).
function Is_Static_Element (N : Node_Id) return Boolean;
-- Return True if N, an element of a component association list, i.e.
-- N_Component_Association or N_Iterated_Component_Association, has a
-- compile-time known value and can be passed as is to the back-end
-- without further expansion.
-- An Iterated_Component_Association is treated as nonstatic in most
-- cases for now, so there are possibilities for optimization.
----------------------------- -----------------------------
-- Check_Static_Components -- -- Check_Static_Components --
----------------------------- -----------------------------
...@@ -4324,7 +4330,8 @@ package body Exp_Aggr is ...@@ -4324,7 +4330,8 @@ package body Exp_Aggr is
-- Could use some comments in this body ??? -- Could use some comments in this body ???
procedure Check_Static_Components is procedure Check_Static_Components is
Expr : Node_Id; Assoc : Node_Id;
Expr : Node_Id;
begin begin
Static_Components := True; Static_Components := True;
...@@ -4350,30 +4357,14 @@ package body Exp_Aggr is ...@@ -4350,30 +4357,14 @@ package body Exp_Aggr is
if Nkind (N) = N_Aggregate if Nkind (N) = N_Aggregate
and then Present (Component_Associations (N)) and then Present (Component_Associations (N))
then then
Expr := First (Component_Associations (N)); Assoc := First (Component_Associations (N));
while Present (Expr) loop while Present (Assoc) loop
if Nkind_In (Expression (Expr), N_Integer_Literal, if not Is_Static_Element (Assoc) then
N_Real_Literal)
then
null;
elsif Is_Entity_Name (Expression (Expr))
and then Present (Entity (Expression (Expr)))
and then Ekind (Entity (Expression (Expr))) =
E_Enumeration_Literal
then
null;
elsif Nkind (Expression (Expr)) /= N_Aggregate
or else not Compile_Time_Known_Aggregate (Expression (Expr))
or else Expansion_Delayed (Expression (Expr))
or else Nkind (Expr) = N_Iterated_Component_Association
then
Static_Components := False; Static_Components := False;
exit; exit;
end if; end if;
Next (Expr); Next (Assoc);
end loop; end loop;
end if; end if;
end Check_Static_Components; end Check_Static_Components;
...@@ -4553,8 +4544,8 @@ package body Exp_Aggr is ...@@ -4553,8 +4544,8 @@ package body Exp_Aggr is
Cunit_Entity (Current_Sem_Unit); Cunit_Entity (Current_Sem_Unit);
begin begin
-- Check if duplication OK and if so continue -- Check if duplication is always OK and, if so,
-- processing. -- continue processing.
if Restriction_Active (No_Elaboration_Code) if Restriction_Active (No_Elaboration_Code)
or else Restriction_Active (No_Implicit_Loops) or else Restriction_Active (No_Implicit_Loops)
...@@ -4571,17 +4562,23 @@ package body Exp_Aggr is ...@@ -4571,17 +4562,23 @@ package body Exp_Aggr is
then then
null; null;
-- If duplication not OK, then we return False -- If duplication is not always OK, continue
-- if the replication count is too high -- only if either the element is static or is
-- an aggregate which can itself be flattened,
-- and the replication count is not too high.
elsif Rep_Count > Max_Others_Replicate then elsif (Is_Static_Element (Elmt)
return False; or else
(Nkind (Expression (Elmt)) = N_Aggregate
and then Present (Next_Index (Ix))))
and then Rep_Count <= Max_Others_Replicate
then
null;
-- Continue on if duplication not OK, but the -- Return False in all the other cases
-- replication count is not excessive.
else else
null; return False;
end if; end if;
end; end;
end if; end if;
...@@ -4706,6 +4703,37 @@ package body Exp_Aggr is ...@@ -4706,6 +4703,37 @@ package body Exp_Aggr is
end if; end if;
end Is_Flat; end Is_Flat;
-------------------------
-- Is_Static_Element --
-------------------------
function Is_Static_Element (N : Node_Id) return Boolean is
Expr : constant Node_Id := Expression (N);
begin
if Nkind_In (Expr, N_Integer_Literal, N_Real_Literal) then
return True;
elsif Is_Entity_Name (Expr)
and then Present (Entity (Expr))
and then Ekind (Entity (Expr)) = E_Enumeration_Literal
then
return True;
elsif Nkind (N) = N_Iterated_Component_Association then
return False;
elsif Nkind (Expr) = N_Aggregate
and then Compile_Time_Known_Aggregate (Expr)
and then not Expansion_Delayed (Expr)
then
return True;
else
return False;
end if;
end Is_Static_Element;
-- Start of processing for Convert_To_Positional -- Start of processing for Convert_To_Positional
begin begin
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment