https://gcc.gnu.org/g:058982859005e5ea28d13a252b6510bdf80f15a6
commit r17-730-g058982859005e5ea28d13a252b6510bdf80f15a6 Author: Eric Botcazou <[email protected]> Date: Sun Jan 11 13:00:32 2026 +0100 ada: Small tweaks to semantic analysis of expression functions They are mostly about streamlining the implementation, but also eliminate unexpected or duplicate error messages in some specific cases. gcc/ada/ChangeLog: * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Introduce new local boolean constant From_Expression_Function, use it throughout, and replace an equivalent test by it. Do not deal with name conflicts here when it is true. Do not verify the consistency of overriding indicators for stand-alone expression functions. * sem_util.ads (Is_Expression_Function_Or_Completion): Fix improper wording in description. * sem_util.adb (Is_Expression_Function_Or_Completion): Streamline the implementation. Diff: --- gcc/ada/sem_ch6.adb | 39 ++++++++++++++++++++++++--------------- gcc/ada/sem_util.adb | 23 ++++++++++------------- gcc/ada/sem_util.ads | 2 +- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index d78d60b233a7..4183da5d8360 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -2374,6 +2374,13 @@ package body Sem_Ch6 is Loc : constant Source_Ptr := Sloc (N); Prev_Id : constant Entity_Id := Current_Entity_In_Scope (Body_Id); + From_Expression_Function : constant Boolean := + Nkind (N) = N_Subprogram_Body and then Was_Expression_Function (N); + -- True if the body was generated either from a stand-alone expression + -- function or from an expression function that is a completion, which + -- means that it is equivalent to Is_Expression_Function_Or_Completion + -- invoked on Spec_Id declared below and not to Is_Expression_Function. + Body_Nod : Node_Id := Empty; Minimum_Acc_Objs : List_Id := No_List; @@ -3666,11 +3673,16 @@ package body Sem_Ch6 is -- name, the instance appears as a package renaming, and will be hidden -- within the subprogram. Otherwise a previous non-overloadable entity -- conflicts with the subprogram. Entering the name will post an error. + -- Note that a subprogram body generated from an expression function is + -- always the completion of a declaration, either present in the source + -- code or synthesized by Analyze_Expression_Function, so the conflict + -- is reported on the declaration. elsif Present (Prev_Id) and then not Is_Overloadable (Prev_Id) and then (Nkind (Parent (Prev_Id)) /= N_Package_Renaming_Declaration or else Comes_From_Source (Prev_Id)) + and then not From_Expression_Function then Enter_Name (Body_Id); goto Leave; @@ -3856,7 +3868,12 @@ package body Sem_Ch6 is else Spec_Decl := Unit_Declaration_Node (Spec_Id); - Verify_Overriding_Indicator; + + -- No possible inconsistency for an expression function + + if not Is_Expression_Function (Spec_Id) then + Verify_Overriding_Indicator; + end if; -- For functions with separate spec, if their return type was visible -- through a limited-with context clause, their extra formals were @@ -3887,8 +3904,7 @@ package body Sem_Ch6 is -- They are necessary in any case to ensure proper elaboration order -- in gigi. - if Nkind (N) = N_Subprogram_Body - and then Was_Expression_Function (N) + if From_Expression_Function and then not Has_Completion (Spec_Id) and then Serious_Errors_Detected = 0 and then (Expander_Active @@ -3988,8 +4004,7 @@ package body Sem_Ch6 is -- If the body is the completion of a previous function -- declared elsewhere, the conformance check is required. - elsif Nkind (N) = N_Subprogram_Body - and then Was_Expression_Function (N) + elsif From_Expression_Function and then Sloc (Spec_Id) = Sloc (Body_Id) then Conformant := True; @@ -4146,8 +4161,7 @@ package body Sem_Ch6 is -- No warnings for expression functions - and then (Nkind (N) /= N_Subprogram_Body - or else not Was_Expression_Function (N)) + and then not From_Expression_Function then Style.Body_With_No_Spec (N); end if; @@ -4176,9 +4190,7 @@ package body Sem_Ch6 is -- An exception in Ada 2012 is that the body created for expression -- functions does not freeze. - if Nkind (N) /= N_Subprogram_Body - or else not Was_Expression_Function (N) - then + if not From_Expression_Function then -- First clear the Is_Public flag on thunks since they are only -- referenced locally by dispatch tables and thus never inlined. @@ -4612,8 +4624,7 @@ package body Sem_Ch6 is -- (SPARK RM 6.1.12(6)). if Present (Spec_Id) - and then (Is_Expression_Function (Spec_Id) - or else Is_Expression_Function (Body_Id)) + and then From_Expression_Function and then Is_Function_With_Side_Effects (Spec_Id) then if From_Aspect_Specification @@ -4957,9 +4968,7 @@ package body Sem_Ch6 is -- Check references of the subprogram spec when we are dealing with -- an expression function due to it having a generated body. - if Present (Spec_Id) - and then Is_Expression_Function (Spec_Id) - then + if Present (Spec_Id) and then Is_Expression_Function (Spec_Id) then Check_References (Spec_Id); -- Skip the check for subprograms generated for protected subprograms diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index dc086b1e52ef..2eb7b1484eb5 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -18152,21 +18152,18 @@ package body Sem_Util is Subp_Decl : Node_Id; begin - if Ekind (Subp) = E_Function then - Subp_Decl := Unit_Declaration_Node (Subp); + -- The function declaration is either an expression function or is + -- completed by an expression function. - -- The function declaration is either an expression function or is - -- completed by an expression function body. + if Is_Expression_Function (Subp) then + return True; - return - Is_Expression_Function (Subp) - or else (Nkind (Subp_Decl) = N_Subprogram_Declaration - and then Present (Corresponding_Body (Subp_Decl)) - and then Is_Expression_Function - (Corresponding_Body (Subp_Decl))); - - elsif Ekind (Subp) = E_Subprogram_Body then - return Is_Expression_Function (Subp); + elsif Ekind (Subp) = E_Function then + Subp_Decl := Unit_Declaration_Node (Subp); + + return Nkind (Subp_Decl) = N_Subprogram_Declaration + and then Present (Corresponding_Body (Subp_Decl)) + and then Is_Expression_Function (Corresponding_Body (Subp_Decl)); else return False; diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index 03b003db612d..abf2dad2f22b 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -2161,7 +2161,7 @@ package Sem_Util is function Is_Expression_Function_Or_Completion (Subp : Entity_Id) return Boolean; -- Determine whether subprogram [body] Subp denotes an expression function - -- or is completed by an expression function body. + -- or is completed by an expression function. function Is_Extended_Precision_Floating_Point_Type (E : Entity_Id) return Boolean;
