[Ada] Fix crash on dynamic predicate when generating SCOs

Message ID 20190711080342.GA95120@adacore.com
State New
Headers show
Series
  • [Ada] Fix crash on dynamic predicate when generating SCOs
Related show

Commit Message

Pierre-Marie de Rodat July 11, 2019, 8:03 a.m.
A pragma Check for Dynamic_Predicate does not correspond to any source
construct that has a provisionally-disabled SCO.

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

2019-07-11  Thomas Quinot  <quinot@adacore.com>

gcc/ada/

	* sem_prag.adb (Analyze_Pragma, case pragma Check): Do not call
	Set_SCO_Pragma_Enabled for the dynamic predicate case.

gcc/testsuite/

	* gnat.dg/scos1.adb: New testcase.

Patch

--- gcc/ada/sem_prag.adb
+++ gcc/ada/sem_prag.adb
@@ -14113,9 +14113,14 @@  package body Sem_Prag is
 
             Expr := Get_Pragma_Arg (Arg2);
 
-            --  Deal with SCO generation
+            --  Mark the pragma (or, if rewritten from an aspect, the original
+            --  aspect) as enabled. Nothing to do for an internally generated
+            --  check for a dynamic predicate.
 
-            if Is_Checked (N) and then not Split_PPC (N) then
+            if Is_Checked (N)
+              and then not Split_PPC (N)
+              and then Cname /= Name_Dynamic_Predicate
+            then
                Set_SCO_Pragma_Enabled (Loc);
             end if;
 

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/scos1.adb
@@ -0,0 +1,26 @@ 
+--  { dg-do compile }
+--  { dg-options "-gnata -gnateS" }
+
+procedure SCOs1 with SPARK_Mode => On is
+
+   LEN_IN_BITS : constant := 20;
+
+   M_SIZE_BYTES : constant := 2 ** LEN_IN_BITS;
+   ET_BYTES : constant := (M_SIZE_BYTES - 4);
+
+   type T_BYTES  is new Integer range 0 .. ET_BYTES  with Size => 32;
+   subtype TYPE5_SCALAR is T_BYTES
+     with Dynamic_Predicate => TYPE5_SCALAR mod 4 = 0;
+
+   type E_16_BYTES is new Integer;
+   subtype RD_BYTES is E_16_BYTES
+     with Dynamic_Predicate => RD_BYTES mod 4 = 0;
+
+   function "-" (left : TYPE5_SCALAR; right : RD_BYTES) return TYPE5_SCALAR
+   is ( left - TYPE5_SCALAR(right) )
+     with Pre => TYPE5_SCALAR(right) <= left and then
+     left - TYPE5_SCALAR(right) <= T_BYTES'Last, Inline_Always;
+
+begin
+   null;
+end SCOs1;