diff mbox series

[Ada] Crash on quantified expression in disabled assertion

Message ID 20190814095312.GA52138@adacore.com
State New
Headers show
Series [Ada] Crash on quantified expression in disabled assertion | expand

Commit Message

Pierre-Marie de Rodat Aug. 14, 2019, 9:53 a.m. UTC
The defining identifier of a quantified expression may be the freeze
point of its type.  If the quantified expression appears in an assertion
that is disavbled, the freeze node for that type may appear in a tree
that will be discarded when the enclosing pragma is elaborated. To
ensure that the freeze node is reachable for subsquent uses we must
generate its freeze node explicitly when the quantified expression is
analyzed.

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

2019-08-14  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

	* exp_ch4.adb (Expand_N_Quantified_Expression): Freeze
	explicitly the type of the loop parameter.

gcc/testsuite/

	* gnat.dg/assert2.adb, gnat.dg/assert2.ads: New testcase.
diff mbox series

Patch

--- gcc/ada/exp_ch4.adb
+++ gcc/ada/exp_ch4.adb
@@ -10337,8 +10337,30 @@  package body Exp_Ch4 is
       Flag      : Entity_Id;
       Scheme    : Node_Id;
       Stmts     : List_Id;
+      Var       : Entity_Id;
 
    begin
+      --  Ensure that the bound variable is properly frozen. We must do
+      --  this before expansion because the expression is about to be
+      --  converted into a loop, and resulting freeze nodes may end up
+      --  in the wrong place in the tree.
+
+      if Present (Iter_Spec) then
+         Var := Defining_Identifier (Iter_Spec);
+      else
+         Var := Defining_Identifier (Loop_Spec);
+      end if;
+
+      declare
+         P : Node_Id := Parent (N);
+      begin
+         while Nkind (P) in N_Subexpr loop
+            P := Parent (P);
+         end loop;
+
+         Freeze_Before (P, Etype (Var));
+      end;
+
       --  Create the declaration of the flag which tracks the status of the
       --  quantified expression. Generate:
 

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/assert2.adb
@@ -0,0 +1,5 @@ 
+--  { dg-do compile }
+
+package body Assert2 is
+   procedure Dummy is null;
+end Assert2;

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/assert2.ads
@@ -0,0 +1,15 @@ 
+package Assert2
+    with SPARK_Mode
+is
+   type Living is new Integer;
+   function Is_Martian (Unused : Living) return Boolean is (False);
+
+   function Is_Green (Unused : Living) return Boolean is (True);
+
+   pragma Assert
+     (for all M in Living => (if Is_Martian (M) then Is_Green (M)));
+   pragma Assert
+     (for all M in Living => (if Is_Martian (M) then not Is_Green (M)));
+
+   procedure Dummy;
+end Assert2;