diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index aababd516d5..7e71422eba3 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -5978,27 +5978,30 @@ package body Exp_Attr is
       when Attribute_Reduce =>
          declare
             Loc : constant Source_Ptr := Sloc (N);
-            E1  : constant Node_Id := First (Expressions (N));
-            E2  : constant Node_Id := Next (E1);
-            Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
-            Typ : constant Entity_Id := Etype (N);
+            E1  : constant Node_Id    := First (Expressions (N));
+            E2  : constant Node_Id    := Next (E1);
+            Bnn : constant Entity_Id  := Make_Temporary (Loc, 'B', N);
 
-            New_Loop : Node_Id;
-            Stat     : Node_Id;
+            Accum_Typ : Entity_Id;
+            New_Loop  : Node_Id;
 
             function Build_Stat (Comp : Node_Id) return Node_Id;
             --  The reducer can be a function, a procedure whose first
             --  parameter is in-out, or an attribute that is a function,
             --  which (for now) can only be Min/Max. This subprogram
-            --  builds the corresponding computation for the generated loop.
+            --  builds the corresponding computation for the generated loop
+            --  and retrieves the accumulator type as per RM 4.5.10(19/5).
 
             ----------------
             -- Build_Stat --
             ----------------
 
             function Build_Stat (Comp : Node_Id) return Node_Id is
+               Stat : Node_Id;
+
             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,
@@ -6009,12 +6012,14 @@ 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,
@@ -6074,6 +6079,13 @@ package body Exp_Attr is
                       End_Label => Empty,
                       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.
+
+                  if Is_Universal_Numeric_Type (Accum_Typ) then
+                     Accum_Typ := Etype (N);
+                  end if;
                end;
 
             else
@@ -6082,9 +6094,10 @@ package body Exp_Attr is
                --  a container with the proper aspects.
 
                declare
-                  Iter : Node_Id;
                   Elem : constant Entity_Id := Make_Temporary (Loc, 'E', N);
 
+                  Iter : Node_Id;
+
                begin
                   Iter :=
                     Make_Iterator_Specification (Loc,
@@ -6101,6 +6114,44 @@ package body Exp_Attr is
                       End_Label => Empty,
                       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
+                  --  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)));
+
+                     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;
                end;
             end if;
 
@@ -6110,10 +6161,11 @@ package body Exp_Attr is
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Bnn,
                      Object_Definition   =>
-                       New_Occurrence_Of (Typ, Loc),
+                       New_Occurrence_Of (Accum_Typ, Loc),
                      Expression => Relocate_Node (E2)), New_Loop),
                  Expression => New_Occurrence_Of (Bnn, Loc)));
-            Analyze_And_Resolve (N, Typ);
+
+            Analyze_And_Resolve (N, Accum_Typ);
          end;
 
       ----------
