[Ada] Crash on named actual in postcondition for generic subprogram
authorEd Schonberg <schonberg@adacore.com>
Mon, 8 Jul 2019 08:13:04 +0000 (08:13 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Mon, 8 Jul 2019 08:13:04 +0000 (08:13 +0000)
This patch fixes a crash on compiling the postcondtion for a generic
subprogram, when the postcondition is a call with both positional and
named parameter associations.

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

gcc/ada/

* sem_ch13.adb (Analyze_Aspect_Specifications): For a
pre/postcondition of a generic subprogram declaration, do not
use Relocate_Node on the aspect expression to construct the
corresponding attribute specification, to prevent tree anomalies
when the expression is a call with named actual parameters.

gcc/testsuite/

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

From-SVN: r273201

gcc/ada/ChangeLog
gcc/ada/sem_ch13.adb
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/predicate9.adb [new file with mode: 0644]

index 9a86909fe68b11026104e8c723a14e2813cfc302..d651ff09eafd1b8d2513f5af69f0248a150cdb0d 100644 (file)
@@ -1,3 +1,11 @@
+2019-07-08  Ed Schonberg  <schonberg@adacore.com>
+
+       * sem_ch13.adb (Analyze_Aspect_Specifications): For a
+       pre/postcondition of a generic subprogram declaration, do not
+       use Relocate_Node on the aspect expression to construct the
+       corresponding attribute specification, to prevent tree anomalies
+       when the expression is a call with named actual parameters.
+
 2019-07-08  Javier Miranda  <miranda@adacore.com>
 
        * sem_attr.adb (Analyze_Attribute [Attribute_Size]): For pragmas
index b62e2971defc1127d5fea32fe75aa9b70cf5776c..8467f75357646aa99e6e25bd19c1e454551131f7 100644 (file)
@@ -3495,12 +3495,28 @@ package body Sem_Ch13 is
                   --  because subsequent visibility analysis of the aspect
                   --  depends on this sharing. This should be cleaned up???
 
-                  Make_Aitem_Pragma
-                    (Pragma_Argument_Associations => New_List (
-                       Make_Pragma_Argument_Association (Eloc,
-                         Chars      => Name_Check,
-                         Expression => Relocate_Node (Expr))),
-                       Pragma_Name                => Pname);
+                  --  If the context is generic or involves ASIS, we want
+                  --  to preserve the original tree, and simply share it
+                  --  between aspect and generated attribute. This parallels
+                  --  what is done in sem_prag.adb (see Get_Argument).
+
+                  declare
+                     New_Expr : Node_Id;
+
+                  begin
+                     if ASIS_Mode or else Inside_A_Generic then
+                        New_Expr := Expr;
+                     else
+                        New_Expr := Relocate_Node (Expr);
+                     end if;
+
+                     Make_Aitem_Pragma
+                       (Pragma_Argument_Associations => New_List (
+                          Make_Pragma_Argument_Association (Eloc,
+                            Chars      => Name_Check,
+                            Expression => New_Expr)),
+                          Pragma_Name                => Pname);
+                  end;
 
                   --  Add message unless exception messages are suppressed
 
index 744f782435523c30958d3754d515b90194e68081..94ad86f98957521b546b0f078cf96d6230c499fa 100644 (file)
@@ -1,3 +1,7 @@
+2019-07-08  Ed Schonberg  <schonberg@adacore.com>
+
+       * gnat.dg/predicate9.adb: New testcase.
+
 2019-07-08  Justin Squirek  <squirek@adacore.com>
 
        * gnat.dg/sso16.adb: New testcase.
diff --git a/gcc/testsuite/gnat.dg/predicate9.adb b/gcc/testsuite/gnat.dg/predicate9.adb
new file mode 100644 (file)
index 0000000..ebcfca7
--- /dev/null
@@ -0,0 +1,21 @@
+--  { dg-do compile }
+procedure Predicate9 is
+  function Num (x : Integer) return Integer is (X + 1);
+  function name (X : String) return Integer is (X'Size);
+  function Post (One : Integer; Two : Integer) return Boolean;
+
+  generic
+     type T is private;
+  procedure Pro (Z : Integer) with Post =>
+    Post (Num (5), Two => Name ("yeah"));
+
+  function Post (One : Integer; Two : Integer) return Boolean
+  is (True);
+
+  procedure Pro (Z : Integer) is
+  begin
+     null;
+  end Pro;
+begin
+   null;
+end Predicate9;