+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.
+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.
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,
+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
--- /dev/null
+-- { 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" } }
--- /dev/null
+-- { 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;
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)
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: