[COMMITTED] ada: Error compiling reduction expression with overloaded reducer subprogram
Checks
Commit Message
From: Steve Baird <baird@adacore.com>
In some cases involving a reduction expression with an overloaded reducer
subprogram, the accumulator type is not determined correctly. This can lead
to spurious compile-time errors.
gcc/ada/
* exp_attr.adb (Expand_N_Attribute_Reference): In the case of a
Reduce attribute reference, fix bugs in initializing Accum_Typ.
The previous version was incorrect in the case where E1 refers to
the first of multiple possible overload resolution candidates and
that candidate does not turn out to be the right one. The previous
version also had code to compute Accum_Typ via a different method
if the initial computation turned out to yield a universal numeric
type. Delete that initial computation and use the second method in
all cases.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_attr.adb | 77 +++++++++++++++++++-------------------------
1 file changed, 34 insertions(+), 43 deletions(-)
@@ -6039,7 +6039,7 @@ package body Exp_Attr is
E2 : constant Node_Id := Next (E1);
Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
- Accum_Typ : Entity_Id;
+ Accum_Typ : Entity_Id := Empty;
New_Loop : Node_Id;
function Build_Stat (Comp : Node_Id) return Node_Id;
@@ -6058,7 +6058,6 @@ package body Exp_Attr is
begin
if Nkind (E1) = N_Attribute_Reference then
- Accum_Typ := Entity (Prefix (E1));
Stat := Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Bnn, Loc),
Expression => Make_Attribute_Reference (Loc,
@@ -6069,14 +6068,12 @@ package body Exp_Attr is
Comp)));
elsif Ekind (Entity (E1)) = E_Procedure then
- Accum_Typ := Etype (First_Formal (Entity (E1)));
Stat := Make_Procedure_Call_Statement (Loc,
Name => New_Occurrence_Of (Entity (E1), Loc),
Parameter_Associations => New_List (
New_Occurrence_Of (Bnn, Loc),
Comp));
else
- Accum_Typ := Etype (Entity (E1));
Stat := Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Bnn, Loc),
Expression => Make_Function_Call (Loc,
@@ -6137,12 +6134,9 @@ package body Exp_Attr is
Statements =>
New_List (Build_Stat (Relocate_Node (Expr))));
- -- If the reducer subprogram is a universal operator, then
- -- we still look at the context to find the type for now.
+ -- Look at the context to find the type.
- if Is_Universal_Numeric_Type (Accum_Typ) then
- Accum_Typ := Etype (N);
- end if;
+ Accum_Typ := Etype (N);
end;
else
@@ -6172,43 +6166,40 @@ package body Exp_Attr is
Statements => New_List (
Build_Stat (New_Occurrence_Of (Elem, Loc))));
- -- If the reducer subprogram is a universal operator, then
- -- we need to look at the prefix to find the type. This is
+ -- Look at the prefix to find the type. This is
-- modeled on Analyze_Iterator_Specification in Sem_Ch5.
- if Is_Universal_Numeric_Type (Accum_Typ) then
- declare
- Ptyp : constant Entity_Id :=
- Base_Type (Etype (Prefix (N)));
+ declare
+ Ptyp : constant Entity_Id :=
+ Base_Type (Etype (Prefix (N)));
- begin
- if Is_Array_Type (Ptyp) then
- Accum_Typ := Component_Type (Ptyp);
-
- elsif Has_Aspect (Ptyp, Aspect_Iterable) then
- declare
- Element : constant Entity_Id :=
- Get_Iterable_Type_Primitive
- (Ptyp, Name_Element);
- begin
- if Present (Element) then
- Accum_Typ := Etype (Element);
- end if;
- end;
-
- else
- declare
- Element : constant Node_Id :=
- Find_Value_Of_Aspect
- (Ptyp, Aspect_Iterator_Element);
- begin
- if Present (Element) then
- Accum_Typ := Entity (Element);
- end if;
- end;
- end if;
- end;
- end if;
+ begin
+ if Is_Array_Type (Ptyp) then
+ Accum_Typ := Component_Type (Ptyp);
+
+ elsif Has_Aspect (Ptyp, Aspect_Iterable) then
+ declare
+ Element : constant Entity_Id :=
+ Get_Iterable_Type_Primitive
+ (Ptyp, Name_Element);
+ begin
+ if Present (Element) then
+ Accum_Typ := Etype (Element);
+ end if;
+ end;
+
+ else
+ declare
+ Element : constant Node_Id :=
+ Find_Value_Of_Aspect
+ (Ptyp, Aspect_Iterator_Element);
+ begin
+ if Present (Element) then
+ Accum_Typ := Entity (Element);
+ end if;
+ end;
+ end if;
+ end;
end;
end if;