re PR ada/48013 (generic instantiation breaks the No_Elaboration_Code restriction)
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 10 Dec 2015 14:20:50 +0000 (14:20 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 10 Dec 2015 14:20:50 +0000 (14:20 +0000)
PR ada/48013
* gcc-interface/trans.c (empty_stmt_list_p): New predicate.
(gigi): Invoke it to compute the No_Elaboration_Code property.
(insert_code_for): Do not insert the code if it's empty.

From-SVN: r231515

gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/specs/elab4.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/specs/elab4_proc.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/specs/elab4_proc.ads [new file with mode: 0644]

index 10758ff1cb5045c1a3e51069e13c7b4c4c11e083..6e2e7b14a99c20eee0cfc9735e01c594673ec8f7 100644 (file)
@@ -1,3 +1,10 @@
+2015-12-10  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR ada/48013
+       * gcc-interface/trans.c (empty_stmt_list_p): New predicate.
+       (gigi): Invoke it to compute the No_Elaboration_Code property.
+       (insert_code_for): Do not insert the code if it's empty.
+
 2015-12-10  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/trans.c (Call_to_gnu): Remove guard for NULL_EXPR.
index d8d5ce20c969d92cf2740d1ce5c85778db4a2c82..ae1d287d443b6bbc75ba0ea282b4bb59793d9db9 100644 (file)
@@ -218,6 +218,7 @@ static enum tree_code gnu_codes[Number_Node_Kinds];
 
 static void init_code_table (void);
 static void Compilation_Unit_to_gnu (Node_Id);
+static bool empty_stmt_list_p (tree);
 static void record_code_position (Node_Id);
 static void insert_code_for (Node_Id);
 static void add_cleanup (tree, Node_Id);
@@ -675,15 +676,15 @@ gigi (Node_Id gnat_root,
   /* Finally see if we have any elaboration procedures to deal with.  */
   for (info = elab_info_list; info; info = info->next)
     {
-      tree gnu_body = DECL_SAVED_TREE (info->elab_proc), gnu_stmts;
+      tree gnu_body = DECL_SAVED_TREE (info->elab_proc);
 
       /* We should have a BIND_EXPR but it may not have any statements in it.
         If it doesn't have any, we have nothing to do except for setting the
         flag on the GNAT node.  Otherwise, process the function as others.  */
-      gnu_stmts = gnu_body;
+      tree gnu_stmts = gnu_body;
       if (TREE_CODE (gnu_stmts) == BIND_EXPR)
        gnu_stmts = BIND_EXPR_BODY (gnu_stmts);
-      if (!gnu_stmts || !STATEMENT_LIST_HEAD (gnu_stmts))
+      if (!gnu_stmts || empty_stmt_list_p (gnu_stmts))
        Set_Has_No_Elaboration_Code (info->gnat_node, 1);
       else
        {
@@ -7881,6 +7882,25 @@ push_exception_label_stack (vec<tree, va_gc> **gnu_stack, Entity_Id gnat_label)
   vec_safe_push (*gnu_stack, gnu_label);
 }
 \f
+/* Return true if the statement list STMT_LIST is empty.  */
+
+static bool
+empty_stmt_list_p (tree stmt_list)
+{
+  tree_stmt_iterator tsi;
+
+  for (tsi = tsi_start (stmt_list); !tsi_end_p (tsi); tsi_next (&tsi))
+    {
+      tree stmt = tsi_stmt (tsi);
+
+      /* Anything else than an empty STMT_STMT counts as something.  */
+      if (TREE_CODE (stmt) != STMT_STMT || STMT_STMT_STMT (stmt))
+       return false;
+    }
+
+  return true;
+}
+
 /* Record the current code position in GNAT_NODE.  */
 
 static void
@@ -7897,7 +7917,12 @@ record_code_position (Node_Id gnat_node)
 static void
 insert_code_for (Node_Id gnat_node)
 {
-  STMT_STMT_STMT (get_gnu_tree (gnat_node)) = gnat_to_gnu (gnat_node);
+  tree code = gnat_to_gnu (gnat_node);
+
+  /* It's too late to remove the STMT_STMT itself at this point.  */
+  if (!empty_stmt_list_p (code))
+    STMT_STMT_STMT (get_gnu_tree (gnat_node)) = code;
+
   save_gnu_tree (gnat_node, NULL_TREE, true);
 }
 \f
index c4f66a851710664f13f4260f12bec7fb151e5966..98ecdb5f3c8c74431f7b4dd03b0d524e98b5f894 100644 (file)
@@ -1,3 +1,8 @@
+2015-12-10  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/specs/elab4.ads: New test.
+       * gnat.dg/specs/elab4_proc.ad[sb]: New helper.
+
 2015-12-10  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/array25.adb: New test.
diff --git a/gcc/testsuite/gnat.dg/specs/elab4.ads b/gcc/testsuite/gnat.dg/specs/elab4.ads
new file mode 100644 (file)
index 0000000..f402f01
--- /dev/null
@@ -0,0 +1,13 @@
+-- { dg-do compile }
+
+pragma Restrictions(No_Elaboration_Code);
+
+with Elab4_Proc;
+
+package Elab4 is
+
+  procedure My_G is new Elab4_Proc;
+
+end Elab4;
+
+-- { dg-final { scan-assembler-not "elabs" } }
diff --git a/gcc/testsuite/gnat.dg/specs/elab4_proc.adb b/gcc/testsuite/gnat.dg/specs/elab4_proc.adb
new file mode 100644 (file)
index 0000000..0663766
--- /dev/null
@@ -0,0 +1,4 @@
+procedure Elab4_Proc is
+begin
+   null;
+end;
diff --git a/gcc/testsuite/gnat.dg/specs/elab4_proc.ads b/gcc/testsuite/gnat.dg/specs/elab4_proc.ads
new file mode 100644 (file)
index 0000000..437ec6a
--- /dev/null
@@ -0,0 +1,4 @@
+-- { dg-excess-errors "no code generated" }
+
+generic
+procedure Elab4_Proc;