This happens when it is present in an expression function, because it is
effectively analyzed twice and the analysis is not idempotent.

Tested on x86-64/Linux, applied on the mainline.


2026-09-23  Eric Botcazou  <[email protected]>

        * sem_aggr.adb (Discriminant_Present): Do not return early if the
        component list already contains an inherited discriminant.
        (Resolve_Record_Aggregate): For an extension, remove the inherited
        discriminants from the component list of the rewritten aggregate.

-- 
Eric Botcazou
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 1d39bd7d845..ba65c193845 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -5507,10 +5507,10 @@ package body Sem_Aggr is
       --  ancestor part.
       --
       --  If the aggregate is in a context with expansion delayed, it will be
-      --  reanalyzed. The inherited discriminant values must not be reinserted
-      --  in the component list to prevent spurious errors, but they must be
-      --  present on first analysis to build the proper subtype indications.
-      --  The flag Inherited_Discriminant is used to prevent the re-insertion.
+      --  reanalyzed. The inherited discriminant values must not be present in
+      --  the component list the second time to prevent spurious errors and,
+      --  therefore, need to be removed at the end of the first processing.
+      --  The flag Inherited_Discriminant is used to implement this scheme.
 
       function Find_Private_Ancestor (Typ : Entity_Id) return Entity_Id;
       --  AI05-0115: Find earlier ancestor in the derivation chain that is
@@ -5599,40 +5599,20 @@ package body Sem_Aggr is
       --------------------------
 
       function Discriminant_Present (Input_Discr : Entity_Id) return Boolean is
-         Regular_Aggr : constant Boolean := Nkind (N) /= N_Extension_Aggregate;
-
+         Ancestor           : Node_Id;
          Ancestor_Is_Subtyp : Boolean;
-
-         Loc : Source_Ptr;
-
-         Ancestor     : Node_Id;
-         Ancestor_Typ : Entity_Id;
-         Comp_Assoc   : Node_Id;
-         Discr        : Entity_Id;
-         Discr_Expr   : Node_Id;
-         Discr_Val    : Elmt_Id := No_Elmt;
-         Orig_Discr   : Entity_Id;
+         Ancestor_Typ       : Entity_Id;
+         Discr              : Entity_Id;
+         Discr_Expr         : Node_Id;
+         Discr_Val          : Elmt_Id;
+         Loc                : Source_Ptr;
+         Orig_Discr         : Entity_Id;
 
       begin
-         if Regular_Aggr then
+         if Nkind (N) /= N_Extension_Aggregate then
             return True;
          end if;
 
-         --  Check whether inherited discriminant values have already been
-         --  inserted in the aggregate. This will be the case if we are
-         --  re-analyzing an aggregate whose expansion was delayed.
-
-         if Present (Component_Associations (N)) then
-            Comp_Assoc := First (Component_Associations (N));
-            while Present (Comp_Assoc) loop
-               if Inherited_Discriminant (Comp_Assoc) then
-                  return True;
-               end if;
-
-               Next (Comp_Assoc);
-            end loop;
-         end if;
-
          Ancestor     := Ancestor_Part (N);
          Ancestor_Typ := Etype (Ancestor);
          Loc          := Sloc (Ancestor);
@@ -6982,7 +6962,24 @@ package body Sem_Aggr is
       Step_8 : declare
          New_Aggregate : constant Node_Id := New_Copy (N);
 
+         Assoc      : Node_Id;
+         Next_Assoc : Node_Id;
+
       begin
+         --  If this is an extension aggregate, remove the inherited
+         --  discriminants from the list in case it is reanalyzed.
+
+         if Nkind (N) = N_Extension_Aggregate then
+            Assoc := First (New_Assoc_List);
+            while Present (Assoc) loop
+               Next_Assoc := Next (Assoc);
+               if Inherited_Discriminant (Assoc) then
+                  Remove (Assoc);
+               end if;
+               Assoc := Next_Assoc;
+            end loop;
+         end if;
+
          Set_Expressions            (New_Aggregate, No_List);
          Set_Etype                  (New_Aggregate, Etype (N));
          Set_Component_Associations (New_Aggregate, New_Assoc_List);

Reply via email to