Now that the implementation of freezing for expression functions is mostly
in line with its semantic model, quirks of the previous implementation are
obsolete and can be eliminated.

The cleanup performed in Analyze_Declarations exposed a couple of glitches
in the ad-hoc resolution implemented for aspect expressions: the prefixes
of components were resolved, but not those of subcomponents, and selector
names of expanded names were incorrectly resolved as direct names.

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


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

        * sinfo.ads (Selector_Name): Beef up description.
        * sem_ch3.adb (Contains_Lib_Incomplete_Type): Delete.
        (Analyze_Declarations): Remove obsolete code.
        * sem_ch13.adb (Resolve_Aspect_Expressions.Resolve_Name): Resolve
        only names that are not selector names.

-- 
Eric Botcazou
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index b95368fd3db..d648da2f55e 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -17357,34 +17357,21 @@ package body Sem_Ch13 is
          Dummy : Traverse_Result;
 
       begin
-         if Nkind (N) = N_Selected_Component then
-            if Nkind (Prefix (N)) = N_Identifier
-              and then Chars (Prefix (N)) /= Chars (E)
-            then
-               Find_Selected_Component (N);
-
-               --  Reset the Entity if N is overloaded since the entity might
-               --  not be the correct one; allow later resolution to set it
-               --  properly.
-
-               if Is_Overloaded (N) then
-                  Set_Entity (N, Empty);
-               end if;
-            end if;
+         --  Resolve identifiers that are not selector names, because the
+         --  latter are not resolved by visibility.
 
-            return Skip;
-
-         --  Resolve identifiers, but not selectors in parameter associations;
-         --  such selectors are never resolved by visibility.
-
-         elsif Nkind (N) = N_Identifier
+         if Nkind (N) = N_Identifier
            and then Chars (N) /= Chars (E)
-           and then (Nkind (Parent (N)) /= N_Parameter_Association
-                      or else N /= Selector_Name (Parent (N)))
+           and then not (Nkind (Parent (N)) in N_Expanded_Name
+                                             | N_Generic_Association
+                                             | N_Parameter_Association
+                                             | N_Selected_Component
+                          and then N = Selector_Name (Parent (N)))
          then
             Find_Direct_Name (N);
 
-            --  Reset the Entity as above for selected_components
+            --  Reset Entity if N is overloaded, since the entity might not
+            --  be the correct one, to allow resolution to set it properly.
 
             if Is_Overloaded (N) then
                Set_Entity (N, Empty);
@@ -17396,6 +17383,8 @@ package body Sem_Ch13 is
             Dummy := Resolve_Name (Expression (N));
             return Skip;
 
+         --  See above for the rationale
+
          elsif Nkind (N) = N_Quantified_Expression then
             return Skip;
          end if;
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 4893671b929..8f44ac7c6df 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -2320,12 +2320,6 @@ package body Sem_Ch3 is
       --  contract expression. Full analysis of the expression is done when
       --  the contract is processed.
 
-      function Contains_Lib_Incomplete_Type (Pkg : Entity_Id) return Boolean;
-      --  Check if a nested package has entities within it that rely on library
-      --  level private types where the full view has not been completed for
-      --  the purposes of checking if it is acceptable to freeze an expression
-      --  function at the point of declaration.
-
       procedure Handle_Late_Controlled_Primitive (Body_Decl : Node_Id);
       --  Determine whether Body_Decl denotes the body of a late controlled
       --  primitive (either Initialize, Adjust or Finalize). If this is the
@@ -2529,40 +2523,6 @@ package body Sem_Ch3 is
          end loop;
       end Check_Entry_Contracts;
 
-      ----------------------------------
-      -- Contains_Lib_Incomplete_Type --
-      ----------------------------------
-
-      function Contains_Lib_Incomplete_Type (Pkg : Entity_Id) return Boolean is
-         Curr : Entity_Id;
-
-      begin
-         --  Avoid looking through scopes that do not meet the precondition of
-         --  Pkg not being within a library unit spec.
-
-         if not Is_Compilation_Unit (Pkg)
-           and then not Is_Generic_Instance (Pkg)
-           and then not In_Package_Body (Enclosing_Lib_Unit_Entity (Pkg))
-         then
-            --  Loop through all entities in the current scope to identify
-            --  an entity that depends on a private type.
-
-            Curr := First_Entity (Pkg);
-            loop
-               if Nkind (Curr) in N_Entity
-                 and then Depends_On_Private (Curr)
-               then
-                  return True;
-               end if;
-
-               exit when Last_Entity (Current_Scope) = Curr;
-               Next_Entity (Curr);
-            end loop;
-         end if;
-
-         return False;
-      end Contains_Lib_Incomplete_Type;
-
       --------------------------------------
       -- Handle_Late_Controlled_Primitive --
       --------------------------------------
@@ -2806,10 +2766,6 @@ package body Sem_Ch3 is
                Check_Entry_Contracts;
 
             elsif Nkind (Parent (L)) /= N_Package_Specification then
-               if Nkind (Parent (L)) = N_Package_Body then
-                  Freeze_From := First_Entity (Current_Scope);
-               end if;
-
                --  There may have been several freezing points previously,
                --  for example object declarations or subprogram bodies, but
                --  at the end of a declarative part we check freezing from
@@ -2881,7 +2837,7 @@ package body Sem_Ch3 is
                Resolve_Aspects;
             end if;
 
-         --  If next node is a body then freeze all types before the body.
+         --  If next node is a body, then freeze all entities before the body.
          --  An exception occurs for some expander-generated bodies. If these
          --  are generated at places where in general language rules would not
          --  allow a freeze point, then we assume that the expander has
@@ -2892,25 +2848,11 @@ package body Sem_Ch3 is
 
          --  In all other cases (bodies that come from source, and expander
          --  generated bodies that have not been analyzed yet), freeze all
-         --  types now. Note that in the latter case, the expander must take
-         --  care to attach the bodies at a proper place in the tree so as to
-         --  not cause unwanted freezing at that point. The exception is the
-         --  generated body of an expression function, which does not freeze.
-
-         --  It is also necessary to check for a case where both an expression
-         --  function is used and the current scope depends on an incomplete
-         --  private type from a library unit, otherwise premature freezing of
-         --  the private type will occur.
-
-         elsif not Analyzed (Next_Decl)
-           and then Is_Body (Next_Decl)
-           and then ((Nkind (Next_Decl) /= N_Subprogram_Body
-                      or else not Was_Expression_Function (Next_Decl))
-                     or else (not Is_Ignored_Ghost_Entity_In_Codegen
-                                    (Current_Scope)
-                              and then not Contains_Lib_Incomplete_Type
-                                             (Current_Scope)))
-         then
+         --  entities now. Note that in the latter case, the expander must
+         --  take care to attach the bodies at a proper place in the tree,
+         --  so as not to cause unwanted freezing at that point.
+
+         elsif Is_Body (Next_Decl) and then not Analyzed (Next_Decl) then
             --  When a controlled type is frozen, the expander generates stream
             --  and controlled-type support routines. If the freeze is caused
             --  by the stand-alone body of Initialize, Adjust, or Finalize, the
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index a78fd31a1f2..9e8beec6049 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -2255,8 +2255,11 @@ package Sinfo is
    --    to the expander.
 
    --  Selector_Name
-   --    Present in N_Expanded_Name N_Selected_Component,
-   --    N_Generic_Association, and N_Parameter_Association nodes.
+   --    Present in N_Expanded_Name and N_Selected_Component nodes, where it
+   --    references a name that denotes an entity declared in the prefix, as
+   --    well as in N_Generic_Association and N_Parameter_Association nodes,
+   --    where it references a name that denotes a formal parameter of the
+   --    generic unit or callable entity.
 
    --  Shift_Count_OK
    --    A flag present in shift nodes to indicate that the shift count is

Reply via email to