diff mbox

[Ada] Legality checks on 'Result in the presence of quantified expression

Message ID 20110801090024.GA24935@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Aug. 1, 2011, 9 a.m. UTC
The expansion of quantified expressions into loops introduces new scopes that
must be taken into account when validating the use of the attribute 'Result.

The following must compile quietly:
   gcc -c -gnat12 -gnata test_astrium_2.adb

--
with Ada.Containers.Ordered_Sets;
package Test_Astrium_2 is
   package OS is new Ada.Containers.Ordered_Sets
     (Element_Type => Integer);

   use OS;

   function Test_Recovery_Highest (S : Set) return Integer
   with Post => (for all Cu in S =>
                 not (Test_Recovery_Highest'Result < Element (Cu)));

end Test_Astrium_2;
---
package body Test_Astrium_2 is
   function Test_Recovery_Highest (S : Set) return Integer is
      Res : Integer;
   begin
      Res := Integer'First;
      for Int of S loop
         if Int > Res then
            Res := Int;
         end if;
      end loop;
      return Res;
   end;
end Test_Astrium_2;

Tested on x86_64-pc-linux-gnu, committed on trunk

2011-08-01  Ed Schonberg  <schonberg@adacore.com>

	* sem_attr.adb (Analyze_Attribute, case 'Result): Handle properly a
	quantified expression that appears within a postcondition and uses the
	Ada2012 'Result attribute.
diff mbox

Patch

Index: sem_attr.adb
===================================================================
--- sem_attr.adb	(revision 176998)
+++ sem_attr.adb	(working copy)
@@ -3947,14 +3947,29 @@  package body Sem_Attr is
       ------------
 
       when Attribute_Result => Result : declare
-         CS : Entity_Id := Current_Scope;
-         PS : Entity_Id := Scope (CS);
+         CS : Entity_Id;
+         --  The enclosing scope, excluding loops for quantified expressions
+
+         PS : Entity_Id;
+         --  During analysis, CS is the postcondition subprogram and PS the
+         --  source subprogram to which the postcondition applies. During
+         --  pre-analysis, CS is the scope of the subprogram declaration.
 
       begin
+         --  Find enclosing scopes, excluding loops
+
+         CS := Current_Scope;
+         while Ekind (CS) = E_Loop loop
+            CS := Scope (CS);
+         end loop;
+
+         PS := Scope (CS);
+
          --  If the enclosing subprogram is always inlined, the enclosing
          --  postcondition will not be propagated to the expanded call.
 
-         if Has_Pragma_Inline_Always (PS)
+         if not In_Spec_Expression
+           and then Has_Pragma_Inline_Always (PS)
            and then Warn_On_Redundant_Constructs
          then
             Error_Msg_N
@@ -3994,9 +4009,7 @@  package body Sem_Attr is
          --  current one.
 
          else
-            while Present (CS)
-              and then CS /= Standard_Standard
-            loop
+            while Present (CS) and then CS /= Standard_Standard loop
                if Chars (CS) = Name_uPostconditions then
                   exit;
                else
@@ -4038,7 +4051,7 @@  package body Sem_Attr is
             else
                Error_Attr
                  ("% attribute can only appear" &
-                   "  in function Postcondition pragma", P);
+                   " in function Postcondition pragma", P);
             end if;
          end if;
       end Result;