diff options
Diffstat (limited to 'gcc/ada/sem_util.adb')
-rw-r--r-- | gcc/ada/sem_util.adb | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 43bffc9..5f15107 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -5846,7 +5846,14 @@ package body Sem_Util is -- will happen when something is evaluated if it never will be -- evaluated. - if not Is_Statically_Unevaluated (N) then + -- Suppress error reporting when checking that the expression of a + -- static expression function is a potentially static expression, + -- because we don't want additional errors being reported during the + -- preanalysis of the expression (see Analyze_Expression_Function). + + if not Is_Statically_Unevaluated (N) + and then not Checking_Potentially_Static_Expression + then if Present (Ent) then Error_Msg_NEL (Msgc (1 .. Msgl), N, Ent, Eloc); else @@ -18442,6 +18449,73 @@ package body Sem_Util is or else Nkind (N) = N_Procedure_Call_Statement; end Is_Statement; + ------------------------------------ + -- Is_Static_Expression_Function -- + ------------------------------------ + + function Is_Static_Expression_Function (Subp : Entity_Id) return Boolean is + begin + return Is_Expression_Function (Subp) + and then Has_Aspect (Subp, Aspect_Static) + and then + (No (Find_Value_Of_Aspect (Subp, Aspect_Static)) + or else Is_True (Static_Boolean + (Find_Value_Of_Aspect (Subp, Aspect_Static)))); + end Is_Static_Expression_Function; + + ----------------------------------------- + -- Is_Static_Expression_Function_Call -- + ----------------------------------------- + + function Is_Static_Expression_Function_Call (Call : Node_Id) return Boolean + is + + function Has_All_Static_Actuals (Call : Node_Id) return Boolean; + -- Return whether all actual parameters of Call are static expressions + + function Has_All_Static_Actuals (Call : Node_Id) return Boolean is + Actual : Node_Id := First_Actual (Call); + String_Result : constant Boolean := + Is_String_Type (Etype (Entity (Name (Call)))); + + begin + while Present (Actual) loop + if not Is_Static_Expression (Actual) then + + -- ??? In the string-returning case we want to avoid a call + -- being made to Establish_Transient_Scope in Resolve_Call, + -- but at the point where that's tested for (which now includes + -- a call to test Is_Static_Expression_Function_Call), the + -- actuals of the call haven't been resolved, so expressions + -- of the actuals may not have been marked Is_Static_Expression + -- yet, so we force them to be resolved here, so we can tell if + -- they're static. Calling Resolve here is admittedly a kludge, + -- and we limit this call to string-returning cases. ??? + + if String_Result then + Resolve (Actual); + end if; + + -- Test flag again in case it's now True due to above Resolve + + if not Is_Static_Expression (Actual) then + return False; + end if; + end if; + + Next_Actual (Actual); + end loop; + + return True; + end Has_All_Static_Actuals; + + begin + return Nkind (Call) = N_Function_Call + and then Is_Entity_Name (Name (Call)) + and then Is_Static_Expression_Function (Entity (Name (Call))) + and then Has_All_Static_Actuals (Call); + end Is_Static_Expression_Function_Call; + ---------------------------------------- -- Is_Subcomponent_Of_Atomic_Object -- ---------------------------------------- |