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>
* sigtramp-vxworks-target.inc: Fix stack checking test errors in
......
......@@ -4302,8 +4302,6 @@ package body Exp_Aggr is
-- Check whether all components of the aggregate are compile-time known
-- values, and can be passed as is to the back-end without further
-- expansion.
-- An Iterated_Component_Association is treated as nonstatic, but there
-- are possibilities for optimization here.
function Flatten
(N : Node_Id;
......@@ -4317,6 +4315,14 @@ package body Exp_Aggr is
-- Return True iff the array N is flat (which is not trivial in the case
-- 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 --
-----------------------------
......@@ -4324,7 +4330,8 @@ package body Exp_Aggr is
-- Could use some comments in this body ???
procedure Check_Static_Components is
Expr : Node_Id;
Assoc : Node_Id;
Expr : Node_Id;
begin
Static_Components := True;
......@@ -4350,30 +4357,14 @@ package body Exp_Aggr is
if Nkind (N) = N_Aggregate
and then Present (Component_Associations (N))
then
Expr := First (Component_Associations (N));
while Present (Expr) loop
if Nkind_In (Expression (Expr), N_Integer_Literal,
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
Assoc := First (Component_Associations (N));
while Present (Assoc) loop
if not Is_Static_Element (Assoc) then
Static_Components := False;
exit;
end if;
Next (Expr);
Next (Assoc);
end loop;
end if;
end Check_Static_Components;
......@@ -4553,8 +4544,8 @@ package body Exp_Aggr is
Cunit_Entity (Current_Sem_Unit);
begin
-- Check if duplication OK and if so continue
-- processing.
-- Check if duplication is always OK and, if so,
-- continue processing.
if Restriction_Active (No_Elaboration_Code)
or else Restriction_Active (No_Implicit_Loops)
......@@ -4571,17 +4562,23 @@ package body Exp_Aggr is
then
null;
-- If duplication not OK, then we return False
-- if the replication count is too high
-- If duplication is not always OK, continue
-- 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
return False;
elsif (Is_Static_Element (Elmt)
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
-- replication count is not excessive.
-- Return False in all the other cases
else
null;
return False;
end if;
end;
end if;
......@@ -4706,6 +4703,37 @@ package body Exp_Aggr is
end if;
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
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