Commit 2a1838cd by Eric Botcazou Committed by Pierre-Marie de Rodat

[Ada] Fix recent regression on array aggregate with dynamic subtype

This prevents either a crash or an assertion failure in gigi on an array
with dynamic subtype that is wrongly flagged as static by the front-end
because of a recent improvement made in the handling of nested
aggregates.

The patch reuses the existing Static_Array_Aggregate predicate instead
of fixing the problematic test, pluging a few loopholes in the process.
The predicate is conservatively correct but should be good enough in
practice.

2018-12-03  Eric Botcazou  <ebotcazou@adacore.com>

gcc/ada/

	* exp_aggr.adb (Convert_To_Positional): Use
	Static_Array_Aggregate to decide whether to set
	Compile_Time_Known_Aggregate on an already flat aggregate.
	(Expand_Array_Aggregate): Remove test on
	Compile_Time_Known_Aggregate that turns out to be dead and
	simplify.
	(Is_Static_Component): New predicate extracted from...
	(Static_Array_Aggregate): ...here.  Test neither Is_Tagged_Type
	nor Is_Controlled for the type, but test whether the component
	type has discriminants.  Use the Is_Static_Component predicate
	consistently for the positional and named cases.

gcc/testsuite/

	* gnat.dg/array32.adb, gnat.dg/array32.ads: New testcase.

From-SVN: r266755
parent d71753da
2018-12-03 Eric Botcazou <ebotcazou@adacore.com> 2018-12-03 Eric Botcazou <ebotcazou@adacore.com>
* exp_aggr.adb (Convert_To_Positional): Use
Static_Array_Aggregate to decide whether to set
Compile_Time_Known_Aggregate on an already flat aggregate.
(Expand_Array_Aggregate): Remove test on
Compile_Time_Known_Aggregate that turns out to be dead and
simplify.
(Is_Static_Component): New predicate extracted from...
(Static_Array_Aggregate): ...here. Test neither Is_Tagged_Type
nor Is_Controlled for the type, but test whether the component
type has discriminants. Use the Is_Static_Component predicate
consistently for the positional and named cases.
2018-12-03 Eric Botcazou <ebotcazou@adacore.com>
* freeze.adb (Freeze_Entity): Do not freeze the partial view of * freeze.adb (Freeze_Entity): Do not freeze the partial view of
a private subtype if its base type is also private with delayed a private subtype if its base type is also private with delayed
freeze before the full type declaration of the base type has freeze before the full type declaration of the base type has
......
...@@ -4759,17 +4759,8 @@ package body Exp_Aggr is ...@@ -4759,17 +4759,8 @@ package body Exp_Aggr is
-- initial value of a thread-local variable. -- initial value of a thread-local variable.
if Is_Flat (N, Number_Dimensions (Typ)) then if Is_Flat (N, Number_Dimensions (Typ)) then
Check_Static_Components; if Static_Array_Aggregate (N) then
if Static_Components then Set_Compile_Time_Known_Aggregate (N);
if Is_Packed (Etype (N))
or else
(Is_Record_Type (Component_Type (Etype (N)))
and then Has_Discriminants (Component_Type (Etype (N))))
then
null;
else
Set_Compile_Time_Known_Aggregate (N);
end if;
end if; end if;
return; return;
...@@ -6205,15 +6196,8 @@ package body Exp_Aggr is ...@@ -6205,15 +6196,8 @@ package body Exp_Aggr is
or else (Parent_Kind = N_Assignment_Statement or else (Parent_Kind = N_Assignment_Statement
and then Inside_Init_Proc) and then Inside_Init_Proc)
then then
if Static_Array_Aggregate (N) Set_Expansion_Delayed (N, not Static_Array_Aggregate (N));
or else Compile_Time_Known_Aggregate (N) return;
then
Set_Expansion_Delayed (N, False);
return;
else
Set_Expansion_Delayed (N);
return;
end if;
end if; end if;
-- STEP 4 -- STEP 4
...@@ -8506,20 +8490,48 @@ package body Exp_Aggr is ...@@ -8506,20 +8490,48 @@ package body Exp_Aggr is
---------------------------- ----------------------------
function Static_Array_Aggregate (N : Node_Id) return Boolean is function Static_Array_Aggregate (N : Node_Id) return Boolean is
function Is_Static_Component (N : Node_Id) return Boolean;
-- Return True if N has a compile-time known value and can be passed as
-- is to the back-end without further expansion.
---------------------------
-- Is_Static_Component --
---------------------------
function Is_Static_Component (N : Node_Id) return Boolean is
begin
if Nkind_In (N, N_Integer_Literal, N_Real_Literal) then
return True;
elsif Is_Entity_Name (N)
and then Present (Entity (N))
and then Ekind (Entity (N)) = E_Enumeration_Literal
then
return True;
elsif Nkind (N) = N_Aggregate
and then Compile_Time_Known_Aggregate (N)
then
return True;
else
return False;
end if;
end Is_Static_Component;
Bounds : constant Node_Id := Aggregate_Bounds (N); Bounds : constant Node_Id := Aggregate_Bounds (N);
Typ : constant Entity_Id := Etype (N); Typ : constant Entity_Id := Etype (N);
Comp_Type : constant Entity_Id := Component_Type (Typ);
Agg : Node_Id; Agg : Node_Id;
Expr : Node_Id; Expr : Node_Id;
Lo : Node_Id; Lo : Node_Id;
Hi : Node_Id; Hi : Node_Id;
-- Start of processing for Static_Array_Aggregate
begin begin
if Is_Tagged_Type (Typ) if Is_Packed (Typ) or else Has_Discriminants (Component_Type (Typ)) then
or else Is_Controlled (Typ)
or else Is_Packed (Typ)
then
return False; return False;
end if; end if;
...@@ -8533,11 +8545,11 @@ package body Exp_Aggr is ...@@ -8533,11 +8545,11 @@ package body Exp_Aggr is
if No (Component_Associations (N)) then if No (Component_Associations (N)) then
-- Verify that all components are static integers -- Verify that all components are static
Expr := First (Expressions (N)); Expr := First (Expressions (N));
while Present (Expr) loop while Present (Expr) loop
if Nkind (Expr) /= N_Integer_Literal then if not Is_Static_Component (Expr) then
return False; return False;
end if; end if;
...@@ -8567,17 +8579,7 @@ package body Exp_Aggr is ...@@ -8567,17 +8579,7 @@ package body Exp_Aggr is
-- component type. We also limit the size of a static aggregate -- component type. We also limit the size of a static aggregate
-- to prevent runaway static expressions. -- to prevent runaway static expressions.
if Is_Array_Type (Comp_Type) if not Is_Static_Component (Expression (Expr)) then
or else Is_Record_Type (Comp_Type)
then
if Nkind (Expression (Expr)) /= N_Aggregate
or else
not Compile_Time_Known_Aggregate (Expression (Expr))
then
return False;
end if;
elsif Nkind (Expression (Expr)) /= N_Integer_Literal then
return False; return False;
end if; end if;
......
2018-12-03 Eric Botcazou <ebotcazou@adacore.com> 2018-12-03 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/array32.adb, gnat.dg/array32.ads: New testcase.
2018-12-03 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/generic_inst2.adb, gnat.dg/generic_inst2.ads, * gnat.dg/generic_inst2.adb, gnat.dg/generic_inst2.ads,
gnat.dg/generic_inst2_c.ads: New testcase. gnat.dg/generic_inst2_c.ads: New testcase.
......
-- { dg-do compile }
package body Array32 is
procedure Init (A : out Arr) is
begin
A := ((I => 1), (I => 2));
end;
end Array32;
package Array32 is
type Rec is record
I : Integer;
end record;
type Arr is array (Positive range <>) of Rec;
procedure Init (A : out Arr);
end Array32;
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