aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/trans.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2015-09-17 15:51:40 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2015-09-17 15:51:40 +0000
commit4e9a8214b871baf45a47bc8b80e1e5ad897f7899 (patch)
treec1ab690e1ad1fde458f6073d05297f18fcd41fb7 /gcc/ada/gcc-interface/trans.c
parent310055e7b481eb86318dc75dcf67f4091e395757 (diff)
downloadgcc-4e9a8214b871baf45a47bc8b80e1e5ad897f7899.zip
gcc-4e9a8214b871baf45a47bc8b80e1e5ad897f7899.tar.gz
gcc-4e9a8214b871baf45a47bc8b80e1e5ad897f7899.tar.bz2
* gcc-interface/trans.c (emit_check): Do not touch TREE_SIDE_EFFECTS.
From-SVN: r227879
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
-rw-r--r--gcc/ada/gcc-interface/trans.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index fea8e15..96f0c55 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -8798,29 +8798,32 @@ emit_index_check (tree gnu_array_object, tree gnu_expr, tree gnu_low,
gnu_expr, CE_Index_Check_Failed, gnat_node);
}
-/* GNU_COND contains the condition corresponding to an access, discriminant or
- range check of value GNU_EXPR. Build a COND_EXPR that returns GNU_EXPR if
- GNU_COND is false and raises a CONSTRAINT_ERROR if GNU_COND is true.
- REASON is the code that says why the exception was raised. GNAT_NODE is
- the GNAT node conveying the source location for which the error should be
- signaled. */
+/* GNU_COND contains the condition corresponding to an index, overflow or
+ range check of value GNU_EXPR. Build a COND_EXPR that returns GNU_EXPR
+ if GNU_COND is false and raises a CONSTRAINT_ERROR if GNU_COND is true.
+ REASON is the code that says why the exception is raised. GNAT_NODE is
+ the node conveying the source location for which the error should be
+ signaled.
+
+ We used to propagate TREE_SIDE_EFFECTS from GNU_EXPR to the COND_EXPR,
+ overwriting the setting inherited from the call statement, on the ground
+ that the expression need not be evaluated just for the check. However
+ that's incorrect because, in the GCC type system, its value is presumed
+ to be valid so its comparison against the type bounds always yields true
+ and, therefore, could be done without evaluating it; given that it can
+ be a computation that overflows the bounds, the language may require the
+ check to fail and thus the expression to be evaluated in this case. */
static tree
emit_check (tree gnu_cond, tree gnu_expr, int reason, Node_Id gnat_node)
{
tree gnu_call
= build_call_raise (reason, gnat_node, N_Raise_Constraint_Error);
- tree gnu_result
- = fold_build3 (COND_EXPR, TREE_TYPE (gnu_expr), gnu_cond,
- build2 (COMPOUND_EXPR, TREE_TYPE (gnu_expr), gnu_call,
- convert (TREE_TYPE (gnu_expr), integer_zero_node)),
- gnu_expr);
-
- /* GNU_RESULT has side effects if and only if GNU_EXPR has:
- we don't need to evaluate it just for the check. */
- TREE_SIDE_EFFECTS (gnu_result) = TREE_SIDE_EFFECTS (gnu_expr);
-
- return gnu_result;
+ return
+ fold_build3 (COND_EXPR, TREE_TYPE (gnu_expr), gnu_cond,
+ build2 (COMPOUND_EXPR, TREE_TYPE (gnu_expr), gnu_call,
+ convert (TREE_TYPE (gnu_expr), integer_zero_node)),
+ gnu_expr);
}
/* Return an expression that converts GNU_EXPR to GNAT_TYPE, doing overflow