tree-nested.c (convert_tramp_reference): Do not build a trampoline if we don't want...
authorEric Botcazou <ebotcazou@adacore.com>
Sun, 25 May 2008 22:42:49 +0000 (22:42 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 25 May 2008 22:42:49 +0000 (22:42 +0000)
 * tree-nested.c (convert_tramp_reference) <ADDR_EXPR>: Do not
build a trampoline if we don't want one.
* varasm.c (initializer_constant_valid_p) <ADDR_EXPR>: Do not
return zero for nested functions if we don't want a trampoline.
ada/
* trans.c (Attribute_to_gnu) <Code_Address>: Set TREE_NO_TRAMPOLINE
instead of TREE_STATIC on the ADDR_EXPR.

From-SVN: r135884

gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/trans.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/trampoline1.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/trampoline2.adb [new file with mode: 0644]
gcc/tree-nested.c
gcc/varasm.c

index 6922a02d170664977820fea962471663b1eea5c1..b456a499a3214949e488b0871637ea2af612e3c4 100644 (file)
@@ -1,3 +1,10 @@
+2008-05-25  Eric Botcazou  <ebotcazou@adacore.com>
+
+        * tree-nested.c (convert_tramp_reference) <ADDR_EXPR>: Do not
+       build a trampoline if we don't want one.
+       * varasm.c (initializer_constant_valid_p) <ADDR_EXPR>: Do not
+       return zero for nested functions if we don't want a trampoline.
+
 2008-05-26  Daniel Franke  <franke.daniel@gmail.com>
 
        * doc/invoke.texi: Added f77, f77-cpp-input to list of file types.
index f7305e8ef4f7c2ec6923130b4c01ceec7a3d968f..c2ffb5eaa6308a3cdc3989d13092e18132e2f251 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-25  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * trans.c (Attribute_to_gnu) <Code_Address>: Set TREE_NO_TRAMPOLINE
+       instead of TREE_STATIC on the ADDR_EXPR.
+
 2008-05-24  Eric Botcazou  <ebotcazou@adacore.com>
 
        * trans.c (gnat_to_gnu): Do not set source location info on NOP_EXPRs.
index 5f579e71b45a1a61524b21e9ccba1d43d29303c3..717c14bbf6a2bc03f0cde6cbb3a53a1ba8c8830e 100644 (file)
@@ -920,7 +920,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
            TREE_CONSTANT (gnu_expr) = 1;
 
          if (TREE_CODE (gnu_expr) == ADDR_EXPR)
-           TREE_STATIC (gnu_expr) = TREE_CONSTANT (gnu_expr) = 1;
+           TREE_NO_TRAMPOLINE (gnu_expr) = TREE_CONSTANT (gnu_expr) = 1;
        }
 
       /* For other address attributes applied to a nested function,
index 2cc96bf4f26e9c4a5759ced328ce70cbadfc87d4..b81a420aaf0558d8d97bc14fbbe59a9a0188f425 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-25  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/trampoline1.adb: New test.
+       * gnat.dg/trampoline2.adb: Likewise.
+
 2008-05-25  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/32600
diff --git a/gcc/testsuite/gnat.dg/trampoline1.adb b/gcc/testsuite/gnat.dg/trampoline1.adb
new file mode 100644 (file)
index 0000000..065b373
--- /dev/null
@@ -0,0 +1,23 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws" }
+
+with System; use System;
+
+procedure Trampoline1 is
+
+  A : Integer;
+
+  function F (I : Integer) return Integer is
+  begin
+    return A + I;
+  end F;
+
+  CA : System.Address := F'Code_Address;
+
+begin
+  if CA = System.Null_Address then
+    raise Program_Error;
+  end if;
+end;
+
+-- { dg-final { scan-assembler-not "GNU-stack.*x" } }
diff --git a/gcc/testsuite/gnat.dg/trampoline2.adb b/gcc/testsuite/gnat.dg/trampoline2.adb
new file mode 100644 (file)
index 0000000..26b4272
--- /dev/null
@@ -0,0 +1,27 @@
+-- { dg-do run }
+-- { dg-options "-gnatws" }
+
+with System; use System;
+
+procedure Trampoline2 is
+
+  A : Integer;
+
+  type FuncPtr is access function (I : Integer) return Integer;
+
+  function F (I : Integer) return Integer is
+  begin
+    return A + I;
+  end F;
+
+  P : FuncPtr := F'Access;
+  CA : System.Address := F'Code_Address;
+  I : Integer;
+
+begin
+  if CA = System.Null_Address then
+    raise Program_Error;
+  end if;
+
+  I := P(0);
+end;
index e3330032c03eb7541187d509d0e2b74514b6cfcc..ded3c2bf49b5a4d48a1e5e027e9f88f2e942b586 100644 (file)
@@ -1645,6 +1645,10 @@ convert_tramp_reference (tree *tp, int *walk_subtrees, void *data)
       if (DECL_NO_STATIC_CHAIN (decl))
        break;
 
+      /* If we don't want a trampoline, then don't build one.  */
+      if (TREE_NO_TRAMPOLINE (t))
+       break;
+
       /* Lookup the immediate parent of the callee, as that's where
         we need to insert the trampoline.  */
       for (i = info; i->context != target_context; i = i->outer)
index d9468c4997dcd068ba90e04e475c1ac9d1260dc5..2202ce110980d18bc3f6c691641344556b91117a 100644 (file)
@@ -4099,25 +4099,29 @@ initializer_constant_valid_p (tree value, tree endtype)
 
     case ADDR_EXPR:
     case FDESC_EXPR:
-      value = staticp (TREE_OPERAND (value, 0));
-      if (value)
-       {
-         /* "&(*a).f" is like unto pointer arithmetic.  If "a" turns out to
-            be a constant, this is old-skool offsetof-like nonsense.  */
-         if (TREE_CODE (value) == INDIRECT_REF
-             && TREE_CONSTANT (TREE_OPERAND (value, 0)))
-           return null_pointer_node;
-         /* Taking the address of a nested function involves a trampoline.  */
-         if (TREE_CODE (value) == FUNCTION_DECL
-             && decl_function_context (value)
-             && !DECL_NO_STATIC_CHAIN (value))
-           return NULL_TREE;
-         /* "&{...}" requires a temporary to hold the constructed
-            object.  */
-         if (TREE_CODE (value) == CONSTRUCTOR)
-           return NULL_TREE;
-       }
-      return value;
+      {
+       tree op0 = staticp (TREE_OPERAND (value, 0));
+       if (op0)
+         {
+           /* "&(*a).f" is like unto pointer arithmetic.  If "a" turns out
+              to be a constant, this is old-skool offsetof-like nonsense.  */
+           if (TREE_CODE (op0) == INDIRECT_REF
+               && TREE_CONSTANT (TREE_OPERAND (op0, 0)))
+             return null_pointer_node;
+           /* Taking the address of a nested function involves a trampoline,
+              unless we don't need or want one.  */
+           if (TREE_CODE (op0) == FUNCTION_DECL
+               && decl_function_context (op0)
+               && !DECL_NO_STATIC_CHAIN (op0)
+               && !TREE_NO_TRAMPOLINE (value))
+             return NULL_TREE;
+           /* "&{...}" requires a temporary to hold the constructed
+              object.  */
+           if (TREE_CODE (op0) == CONSTRUCTOR)
+             return NULL_TREE;
+         }
+       return op0;
+      }
 
     case VIEW_CONVERT_EXPR:
     case NON_LVALUE_EXPR: