diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2011-09-26 08:26:37 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2011-09-26 08:26:37 +0000 |
commit | a1c7d7973c44afbee5e1251b200cc6e7a27409b1 (patch) | |
tree | 0bbfdf9e810f8a0d87f499a7747d27b4dadc2da4 | |
parent | 20633efc34fadc76b339620c2d37f3c12231c40a (diff) | |
download | gcc-a1c7d7973c44afbee5e1251b200cc6e7a27409b1.zip gcc-a1c7d7973c44afbee5e1251b200cc6e7a27409b1.tar.gz gcc-a1c7d7973c44afbee5e1251b200cc6e7a27409b1.tar.bz2 |
ada-tree.h (DECL_CAN_NEVER_BE_NULL_P): New macro.
* gcc-interface/ada-tree.h (DECL_CAN_NEVER_BE_NULL_P): New macro.
* gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Set the flag.
(gnat_to_gnu_param): Likewise.
* gcc-interface/utils.c (convert) <UNCONSTRAINED_ARRAY_REF>: Invoke
maybe_unconstrained_array instead of doing the work manually.
(maybe_unconstrained_array): Propagate the TREE_THIS_NOTRAP flag.
* gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: If operand
is a DECL with the flag, set TREE_THIS_NOTRAP on the reference.
(gnat_stabilize_reference_1): Propagate the TREE_THIS_NOTRAP flag.
(gnat_stabilize_reference): Likewise.
From-SVN: r179182
-rw-r--r-- | gcc/ada/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/ada-tree.h | 5 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 2 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 41 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils2.c | 92 |
5 files changed, 94 insertions, 59 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b114542..4784219 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,18 @@ 2011-09-26 Eric Botcazou <ebotcazou@adacore.com> + * gcc-interface/ada-tree.h (DECL_CAN_NEVER_BE_NULL_P): New macro. + * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Set the flag. + (gnat_to_gnu_param): Likewise. + * gcc-interface/utils.c (convert) <UNCONSTRAINED_ARRAY_REF>: Invoke + maybe_unconstrained_array instead of doing the work manually. + (maybe_unconstrained_array): Propagate the TREE_THIS_NOTRAP flag. + * gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: If operand + is a DECL with the flag, set TREE_THIS_NOTRAP on the reference. + (gnat_stabilize_reference_1): Propagate the TREE_THIS_NOTRAP flag. + (gnat_stabilize_reference): Likewise. + +2011-09-26 Eric Botcazou <ebotcazou@adacore.com> + * 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 diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h index 4a0981d..d10fcf0 100644 --- a/gcc/ada/gcc-interface/ada-tree.h +++ b/gcc/ada/gcc-interface/ada-tree.h @@ -352,6 +352,9 @@ do { \ is needed to access the object. */ #define DECL_BY_REF_P(NODE) DECL_LANG_FLAG_1 (NODE) +/* Nonzero in a DECL if it is made for a pointer that can never be null. */ +#define DECL_CAN_NEVER_BE_NULL_P(NODE) DECL_LANG_FLAG_2 (NODE) + /* Nonzero in a FIELD_DECL that is a dummy built for some internal reason. */ #define DECL_INTERNAL_P(NODE) DECL_LANG_FLAG_3 (FIELD_DECL_CHECK (NODE)) @@ -364,7 +367,7 @@ do { \ DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (NODE)) /* Nonzero in a DECL if it is made for a pointer that points to something which - is readonly. Used mostly for fat pointers. */ + is readonly. */ #define DECL_POINTS_TO_READONLY_P(NODE) DECL_LANG_FLAG_4 (NODE) /* Nonzero in a PARM_DECL if we are to pass by descriptor. */ diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index ea8eb91..98d68fe 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -1417,6 +1417,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) gnat_entity); DECL_BY_REF_P (gnu_decl) = used_by_ref; DECL_POINTS_TO_READONLY_P (gnu_decl) = used_by_ref && inner_const_flag; + DECL_CAN_NEVER_BE_NULL_P (gnu_decl) = Can_Never_Be_Null (gnat_entity); /* If we are defining an Out parameter and optimization isn't enabled, create a fake PARM_DECL for debugging purposes and make it point to @@ -5568,6 +5569,7 @@ gnat_to_gnu_param (Entity_Id gnat_param, Mechanism_Type mech, mech == By_Short_Descriptor); DECL_POINTS_TO_READONLY_P (gnu_param) = (ro_param && (by_ref || by_component_ptr)); + DECL_CAN_NEVER_BE_NULL_P (gnu_param) = Can_Never_Be_Null (gnat_param); /* Save the alternate descriptor type, if any. */ if (gnu_param_type_alt) diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 4d95845..baa4ca1 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -3819,8 +3819,7 @@ convert (tree type, tree expr) return gnat_build_constructor (type, v); } - /* There are some special cases of expressions that we process - specially. */ + /* There are some cases of expressions that we process specially. */ switch (TREE_CODE (expr)) { case ERROR_MARK: @@ -3976,21 +3975,11 @@ convert (tree type, tree expr) break; case UNCONSTRAINED_ARRAY_REF: - { - /* Convert this to the type of the inner array by getting the address - of the array from the template. */ - const bool no_trap = TREE_THIS_NOTRAP (expr); - expr = TREE_OPERAND (expr, 0); - expr = build_unary_op (INDIRECT_REF, NULL_TREE, - build_component_ref (expr, NULL_TREE, - TYPE_FIELDS - (TREE_TYPE (expr)), - false)); - TREE_THIS_NOTRAP (expr) = no_trap; - etype = TREE_TYPE (expr); - ecode = TREE_CODE (etype); - break; - } + /* First retrieve the underlying array. */ + expr = maybe_unconstrained_array (expr); + etype = TREE_TYPE (expr); + ecode = TREE_CODE (etype); + break; case VIEW_CONVERT_EXPR: { @@ -4282,6 +4271,8 @@ maybe_unconstrained_array (tree exp) if (code == UNCONSTRAINED_ARRAY_REF) { const bool read_only = TREE_READONLY (exp); + const bool no_trap = TREE_THIS_NOTRAP (exp); + exp = TREE_OPERAND (exp, 0); if (TREE_CODE (exp) == COND_EXPR) { @@ -4306,12 +4297,16 @@ maybe_unconstrained_array (tree exp) TREE_OPERAND (exp, 0), op1, op2); } else - exp = build_unary_op (INDIRECT_REF, NULL_TREE, - build_component_ref (exp, NULL_TREE, - TYPE_FIELDS - (TREE_TYPE (exp)), - false)); - TREE_READONLY (exp) = read_only; + { + exp = build_unary_op (INDIRECT_REF, NULL_TREE, + build_component_ref (exp, NULL_TREE, + TYPE_FIELDS + (TREE_TYPE (exp)), + false)); + TREE_READONLY (exp) = read_only; + TREE_THIS_NOTRAP (exp) = no_trap; + } + return exp; } diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index 0cc554d..12c517c 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -1276,44 +1276,60 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand) break; case INDIRECT_REF: - /* If we want to refer to an unconstrained array, use the appropriate - expression to do so. This will never survive down to the back-end. - But if TYPE is a thin pointer, first convert to a fat pointer. */ - if (TYPE_IS_THIN_POINTER_P (type) - && TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))) - { - operand - = convert (TREE_TYPE (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))), + { + bool can_never_be_null; + tree t = operand; + + while (CONVERT_EXPR_P (t) || TREE_CODE (t) == VIEW_CONVERT_EXPR) + t = TREE_OPERAND (t, 0); + + can_never_be_null = DECL_P (t) && DECL_CAN_NEVER_BE_NULL_P (t); + + /* If TYPE is a thin pointer, first convert to the fat pointer. */ + if (TYPE_IS_THIN_POINTER_P (type) + && TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))) + { + operand = convert + (TREE_TYPE (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))), operand); - type = TREE_TYPE (operand); - } + type = TREE_TYPE (operand); + } - if (TYPE_IS_FAT_POINTER_P (type)) - { - result = build1 (UNCONSTRAINED_ARRAY_REF, - TYPE_UNCONSTRAINED_ARRAY (type), operand); - TREE_READONLY (result) - = TYPE_READONLY (TYPE_UNCONSTRAINED_ARRAY (type)); - } + /* If we want to refer to an unconstrained array, use the appropriate + expression. But this will never survive down to the back-end. */ + if (TYPE_IS_FAT_POINTER_P (type)) + { + result = build1 (UNCONSTRAINED_ARRAY_REF, + TYPE_UNCONSTRAINED_ARRAY (type), operand); + TREE_READONLY (result) + = TYPE_READONLY (TYPE_UNCONSTRAINED_ARRAY (type)); + } - /* If we are dereferencing an ADDR_EXPR, return its operand. */ - else if (TREE_CODE (operand) == ADDR_EXPR) - result = TREE_OPERAND (operand, 0); + /* If we are dereferencing an ADDR_EXPR, return its operand. */ + else if (TREE_CODE (operand) == ADDR_EXPR) + result = TREE_OPERAND (operand, 0); - /* Otherwise, build and fold the indirect reference. */ - else - { - result = build_fold_indirect_ref (operand); - TREE_READONLY (result) = TYPE_READONLY (TREE_TYPE (type)); - } + /* Otherwise, build and fold the indirect reference. */ + else + { + result = build_fold_indirect_ref (operand); + TREE_READONLY (result) = TYPE_READONLY (TREE_TYPE (type)); + } - if (!TYPE_IS_FAT_POINTER_P (type) && TYPE_VOLATILE (TREE_TYPE (type))) - { - TREE_SIDE_EFFECTS (result) = 1; - if (TREE_CODE (result) == INDIRECT_REF) - TREE_THIS_VOLATILE (result) = TYPE_VOLATILE (TREE_TYPE (result)); - } - break; + if (!TYPE_IS_FAT_POINTER_P (type) && TYPE_VOLATILE (TREE_TYPE (type))) + { + TREE_SIDE_EFFECTS (result) = 1; + if (TREE_CODE (result) == INDIRECT_REF) + TREE_THIS_VOLATILE (result) = TYPE_VOLATILE (TREE_TYPE (result)); + } + + if ((TREE_CODE (result) == INDIRECT_REF + || TREE_CODE (result) == UNCONSTRAINED_ARRAY_REF) + && can_never_be_null) + TREE_THIS_NOTRAP (result) = 1; + + break; + } case NEGATE_EXPR: case BIT_NOT_EXPR: @@ -2442,7 +2458,10 @@ gnat_stabilize_reference_1 (tree e, bool force) TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (e); TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e); - if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF) + if (code == INDIRECT_REF + || code == UNCONSTRAINED_ARRAY_REF + || code == ARRAY_REF + || code == ARRAY_RANGE_REF) TREE_THIS_NOTRAP (result) = TREE_THIS_NOTRAP (e); return result; @@ -2578,7 +2597,10 @@ gnat_stabilize_reference (tree ref, bool force, bool *success) TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (ref); TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref); - if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF) + if (code == INDIRECT_REF + || code == UNCONSTRAINED_ARRAY_REF + || code == ARRAY_REF + || code == ARRAY_RANGE_REF) TREE_THIS_NOTRAP (result) = TREE_THIS_NOTRAP (ref); return result; |