[Ada] Wrong code with -gnatVa on lock-free protected objects
authorEd Schonberg <schonberg@adacore.com>
Mon, 1 Jul 2019 13:36:56 +0000 (13:36 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Mon, 1 Jul 2019 13:36:56 +0000 (13:36 +0000)
This patch fixes the handling of validity checks on protected objects
that use the Lock-Free implementation when validity checks are enabled,
previous to this patch the compiler would report improperly that a
condition in a protected operation was always True (when comoipled with
-gnatwa) and would generate incorrect code fhat operation.

2019-07-01  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

* checks.adb (Insert_Valid_Check): Do not apply validity check
to variable declared within a protected object that uses the
Lock_Free implementation, to prevent unwarranted constant
folding, because entities within such an object msut be treated
as volatile.

gcc/testsuite/

* gnat.dg/prot7.adb, gnat.dg/prot7.ads: New testcase.

From-SVN: r272873

gcc/ada/ChangeLog
gcc/ada/checks.adb
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/prot7.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/prot7.ads [new file with mode: 0644]

index c60b957641bbc6870b61d4649120541874c2d0fb..bf6e1c386a0821a2309d3506bffdd509c4080fc3 100644 (file)
@@ -1,3 +1,11 @@
+2019-07-01  Ed Schonberg  <schonberg@adacore.com>
+
+       * checks.adb (Insert_Valid_Check): Do not apply validity check
+       to variable declared within a protected object that uses the
+       Lock_Free implementation, to prevent unwarranted constant
+       folding, because entities within such an object msut be treated
+       as volatile.
+
 2019-07-01  Eric Botcazou  <ebotcazou@adacore.com>
 
        * exp_ch9.adb (Check_Inlining): Deal with Has_Pragma_No_Inline.
index fcfaec7d4709e73bb1fe9813f1d887026f2ab3b6..e851c5f702f29340eb7d54b1c48020226635795e 100644 (file)
@@ -7429,6 +7429,19 @@ package body Checks is
          return;
       end if;
 
+      --  Entities declared in Lock_free protected types must be treated
+      --  as volatile, and we must inhibit validity checks to prevent
+      --  improper constant folding.
+
+      if Is_Entity_Name (Expr)
+        and then Is_Subprogram (Scope (Entity (Expr)))
+        and then Present (Protected_Subprogram (Scope (Entity (Expr))))
+        and then Uses_Lock_Free
+           (Scope (Protected_Subprogram (Scope (Entity (Expr)))))
+      then
+         return;
+      end if;
+
       --  If we have a checked conversion, then validity check applies to
       --  the expression inside the conversion, not the result, since if
       --  the expression inside is valid, then so is the conversion result.
index ef255f5a312750414ebdf553e31a3cbc971253fb..4d49ad3de830ef3937b771446e622be74df1a867 100644 (file)
@@ -1,3 +1,7 @@
+2019-07-01  Ed Schonberg  <schonberg@adacore.com>
+
+       * gnat.dg/prot7.adb, gnat.dg/prot7.ads: New testcase.
+
 2019-07-01  Richard Biener  <rguenther@suse.de>
 
        * gcc.dg/gimplefe-42.c: New testcase.
diff --git a/gcc/testsuite/gnat.dg/prot7.adb b/gcc/testsuite/gnat.dg/prot7.adb
new file mode 100644 (file)
index 0000000..6051ef0
--- /dev/null
@@ -0,0 +1,22 @@
+--  { dg-do compile }
+--  { dg-options "-gnatwa -gnatVa" }
+
+package body Prot7 is
+   protected body Default_Slice is
+      function Get return Instance_Pointer is
+      begin
+         return Default;
+      end Get;
+
+      procedure Set (
+        Discard : in out Boolean;
+        Slice   : in     Instance_Pointer
+      ) is
+      begin
+         Discard := Default /= null;
+         if not Discard then
+            Default := Slice;
+         end if;
+      end Set;
+   end Default_Slice;
+end Prot7;
diff --git a/gcc/testsuite/gnat.dg/prot7.ads b/gcc/testsuite/gnat.dg/prot7.ads
new file mode 100644 (file)
index 0000000..5e06e26
--- /dev/null
@@ -0,0 +1,16 @@
+package Prot7 is
+   type Instance_Pointer is access Integer;
+
+   protected Default_Slice
+        with Lock_Free
+   is
+      function Get return Instance_Pointer;
+
+      procedure Set (
+        Discard : in out Boolean;
+        Slice   : in     Instance_Pointer
+      );
+   private
+      Default : Instance_Pointer;
+   end Default_Slice;
+end Prot7;