if (TREE_CODE (gnu_decl) == CONST_DECL)
DECL_CONST_ADDRESS_P (gnu_decl) = constructor_address_p (gnu_expr);
- /* If this object is declared in a block that contains a block with an
- exception handler, and we aren't using the GCC exception mechanism,
- we must force this variable in memory in order to avoid an invalid
- optimization. */
- if (Exception_Mechanism != Back_End_Exceptions
- && Has_Nested_Block_With_Handler (Scope (gnat_entity)))
+ /* If this is declared in a block that contains a block with an
+ exception handler, we must force this variable in memory to
+ suppress an invalid optimization. */
+ if (Has_Nested_Block_With_Handler (Scope (gnat_entity))
+ && Exception_Mechanism != Back_End_Exceptions)
TREE_ADDRESSABLE (gnu_decl) = 1;
/* If we are defining an object with variable size or an object with
debug_info_p, false);
/* If it is passed by reference, force BLKmode to ensure that objects
- of this type will always be put in memory. */
++ of this type will always be put in memory. */
if (Is_By_Reference_Type (gnat_entity))
SET_TYPE_MODE (gnu_type, BLKmode);
return (TREE_CODE (gnu_expr) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (gnu_expr, 0)) == CONSTRUCTOR);
}
+
+/* Return true if GNU_EXPR is (essentially) the address of a CONSTRUCTOR. */
+
+static bool
+constructor_address_p (tree gnu_expr)
+{
+ while (TREE_CODE (gnu_expr) == NOP_EXPR
+ || TREE_CODE (gnu_expr) == CONVERT_EXPR
+ || TREE_CODE (gnu_expr) == NON_LVALUE_EXPR)
+ gnu_expr = TREE_OPERAND (gnu_expr, 0);
+
+ return (TREE_CODE (gnu_expr) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (gnu_expr, 0)) == CONSTRUCTOR);
+}
\f
/* Given GNAT_ENTITY, elaborate all expressions that are required to
be elaborated at the point of its definition, but do nothing else. */