]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Spurious error analyzing 'old or 'result in class-wide conditions
authorJavier Miranda <miranda@adacore.com>
Thu, 26 Jan 2023 19:39:31 +0000 (19:39 +0000)
committerMarc Poulhiès <poulhies@adacore.com>
Tue, 16 May 2023 08:30:58 +0000 (10:30 +0200)
gcc/ada/

* sem_attr.adb
(Analyze_Attribute_Old_Result): When preanalyzing a class-wide
condition, search in the scopes stack for the subprogram that has
the condition. This is required because returning the current
scope causes reporting spurious errors when the occurrence of the
attribute is found, for example, in a quantified expression.

gcc/ada/sem_attr.adb

index 452aabdd4360c9e8408c713bd795d7d87e627f0e..a07e91b839d4adeaddbbc34bba933a2da6c23d93 100644 (file)
@@ -1366,8 +1366,27 @@ package body Sem_Attr is
          --  yet on its definite context.
 
          if Inside_Class_Condition_Preanalysis then
-            Legal   := True;
-            Spec_Id := Current_Scope;
+            Legal := True;
+
+            --  Search for the subprogram that has this class-wide condition;
+            --  required to avoid reporting spurious errors since the current
+            --  scope may not be appropriate because the attribute may be
+            --  referenced from the inner scope of, for example, quantified
+            --  expressions.
+
+            --  Although the expression is not installed on its definite
+            --  context, we know that the subprogram has been placed in the
+            --  scope stack by Preanalyze_Condition; we also know that it is
+            --  not a generic subprogram since class-wide pre/postconditions
+            --  can only be applied for primitive operations of tagged types.
+
+            if Is_Subprogram (Current_Scope) then
+               Spec_Id := Current_Scope;
+            else
+               Spec_Id := Enclosing_Subprogram (Current_Scope);
+            end if;
+
+            pragma Assert (Is_Dispatching_Operation (Spec_Id));
             return;
          end if;