diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2011-09-26 07:52:58 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2011-09-26 07:52:58 +0000 |
commit | 50179d5882b4abaed3c5deaa6a3068e01956fe29 (patch) | |
tree | 8d0ae965ac4142c79fa9762852ce25e5e0cdf3bf /gcc/ada/gcc-interface/utils.c | |
parent | 382346e535ff0d18de34888258c948e908646fb6 (diff) | |
download | gcc-50179d5882b4abaed3c5deaa6a3068e01956fe29.zip gcc-50179d5882b4abaed3c5deaa6a3068e01956fe29.tar.gz gcc-50179d5882b4abaed3c5deaa6a3068e01956fe29.tar.bz2 |
ada-tree.h (TYPE_NULL_BOUNDS): New macro.
* gcc-interface/ada-tree.h (TYPE_NULL_BOUNDS): New macro.
(SET_TYPE_NULL_BOUNDS): Likewise.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Set again
TREE_THIS_NOTRAP on the INDIRECT_REF node built for the template.
* gcc-interface/trans.c (Identifier_to_gnu): Return initializers of fat
pointer types.
* gcc-interface/utils.c (create_var_decl_1): If the object is external,
check that the initializer is a valid constant expression for use in
initializing a static variable. Add missing guard.
(update_pointer_to): Adjust TYPE_NULL_BOUNDS if set.
(convert_to_fat_pointer): In the null fat pointer case, build a valid
pointer for the bounds.
* gcc-interface/utils2.c (compare_fat_pointers): New function.
(build_binary_op) <EQ_EXPR>: Call it to compare fat pointers.
From-SVN: r179180
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index de9256a..4d95845 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -1391,10 +1391,14 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init, bool static_flag, bool const_decl_allowed_p, struct attrib *attr_list, Node_Id gnat_node) { + /* Whether the initializer is a constant initializer. At the global level + or for an external object or an object to be allocated in static memory, + we check that it is a valid constant expression for use in initializing + a static variable; otherwise, we only check that it is constant. */ bool init_const = (var_init != 0 && gnat_types_compatible_p (type, TREE_TYPE (var_init)) - && (global_bindings_p () || static_flag + && (global_bindings_p () || extern_flag || static_flag ? initializer_constant_valid_p (var_init, TREE_TYPE (var_init)) != 0 : TREE_CONSTANT (var_init))); @@ -1460,6 +1464,7 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init, section which runs afoul of the PE-COFF run-time relocation mechanism. */ if (extern_flag && constant_p + && var_init && initializer_constant_valid_p (var_init, TREE_TYPE (var_init)) != null_pointer_node) DECL_IGNORED_P (var_decl) = 1; @@ -3489,7 +3494,11 @@ update_pointer_to (tree old_type, tree new_type) /* Now adjust them. */ for (; ptr; ptr = TYPE_NEXT_PTR_TO (ptr)) for (t = TYPE_MAIN_VARIANT (ptr); t; t = TYPE_NEXT_VARIANT (t)) - TREE_TYPE (t) = new_type; + { + TREE_TYPE (t) = new_type; + if (TYPE_NULL_BOUNDS (t)) + TREE_TYPE (TREE_OPERAND (TYPE_NULL_BOUNDS (t), 0)) = new_type; + } /* If we have adjusted named types, finalize them. This is necessary since we had forced a DWARF typedef for them in gnat_pushdecl. */ @@ -3560,16 +3569,36 @@ convert_to_fat_pointer (tree type, tree expr) tree template_tree; VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 2); - /* If EXPR is null, make a fat pointer that contains null pointers to the - template and array. */ + /* If EXPR is null, make a fat pointer that contains a null pointer to the + array (compare_fat_pointers ensures that this is the full discriminant) + and a valid pointer to the bounds. This latter property is necessary + since the compiler can hoist the load of the bounds done through it. */ if (integer_zerop (expr)) { + tree ptr_template_type = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type))); + tree null_bounds, t; + + if (TYPE_NULL_BOUNDS (ptr_template_type)) + null_bounds = TYPE_NULL_BOUNDS (ptr_template_type); + else + { + /* The template type can still be dummy at this point so we build an + empty constructor. The middle-end will fill it in with zeros. */ + t = build_constructor (template_type, NULL); + TREE_CONSTANT (t) = TREE_STATIC (t) = 1; + null_bounds = build_unary_op (ADDR_EXPR, NULL_TREE, t); + SET_TYPE_NULL_BOUNDS (ptr_template_type, null_bounds); + } + CONSTRUCTOR_APPEND_ELT (v, TYPE_FIELDS (type), - convert (p_array_type, expr)); - CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (type)), - convert (build_pointer_type (template_type), - expr)); - return gnat_build_constructor (type, v); + fold_convert (p_array_type, null_pointer_node)); + CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (type)), null_bounds); + t = build_constructor (type, v); + /* Do not set TREE_CONSTANT so as to force T to static memory. */ + TREE_CONSTANT (t) = 0; + TREE_STATIC (t) = 1; + + return t; } /* If EXPR is a thin pointer, make template and data from the record.. */ |