diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2009-04-24 07:20:19 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2009-04-24 07:20:19 +0000 |
commit | 1275de7d6eb0240c3dc56206aa68bac7a6c2318b (patch) | |
tree | 03a8d14167ccef6572ef939b3637bdd160c0c809 /gcc/ada/gcc-interface/utils2.c | |
parent | 6f61bd412437337e11b367edfb0b8f48ba70f94c (diff) | |
download | gcc-1275de7d6eb0240c3dc56206aa68bac7a6c2318b.zip gcc-1275de7d6eb0240c3dc56206aa68bac7a6c2318b.tar.gz gcc-1275de7d6eb0240c3dc56206aa68bac7a6c2318b.tar.bz2 |
utils2.c (build_cond_expr): Move SAVE_EXPR ahead of the conditional expression only if...
* gcc-interface/utils2.c (build_cond_expr): Move SAVE_EXPR ahead of
the conditional expression only if it is common to both arms.
From-SVN: r146673
Diffstat (limited to 'gcc/ada/gcc-interface/utils2.c')
-rw-r--r-- | gcc/ada/gcc-interface/utils2.c | 34 |
1 files changed, 15 insertions, 19 deletions
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index a4534b1..3b2d526 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -1410,44 +1410,40 @@ tree build_cond_expr (tree result_type, tree condition_operand, tree true_operand, tree false_operand) { - tree result; bool addr_p = false; + tree result; - /* The front-end verifies that result, true and false operands have same base - type. Convert everything to the result type. */ - - true_operand = convert (result_type, true_operand); + /* The front-end verified that result, true and false operands have + same base type. Convert everything to the result type. */ + true_operand = convert (result_type, true_operand); false_operand = convert (result_type, false_operand); - /* If the result type is unconstrained, take the address of - the operands and then dereference our result. */ + /* If the result type is unconstrained, take the address of the operands + and then dereference our result. */ if (TREE_CODE (result_type) == UNCONSTRAINED_ARRAY_TYPE || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (result_type))) { - addr_p = true; result_type = build_pointer_type (result_type); true_operand = build_unary_op (ADDR_EXPR, result_type, true_operand); false_operand = build_unary_op (ADDR_EXPR, result_type, false_operand); + addr_p = true; } result = fold_build3 (COND_EXPR, result_type, condition_operand, true_operand, false_operand); - /* If either operand is a SAVE_EXPR (possibly surrounded by - arithmetic, make sure it gets done. */ - true_operand = skip_simple_arithmetic (true_operand); + /* If we have a common SAVE_EXPR (possibly surrounded by arithmetics) + in both arms, make sure it gets evaluated by moving it ahead of the + conditional expression. This is necessary because it is evaluated + in only one place at run time and would otherwise be uninitialized + in one of the arms. */ + true_operand = skip_simple_arithmetic (true_operand); false_operand = skip_simple_arithmetic (false_operand); - if (TREE_CODE (true_operand) == SAVE_EXPR) + if (true_operand == false_operand && TREE_CODE (true_operand) == SAVE_EXPR) result = build2 (COMPOUND_EXPR, result_type, true_operand, result); - if (TREE_CODE (false_operand) == SAVE_EXPR) - result = build2 (COMPOUND_EXPR, result_type, false_operand, result); - - /* ??? Seems the code above is wrong, as it may move ahead of the COND - SAVE_EXPRs with side effects and not shared by both arms. */ - - if (addr_p) + if (addr_p) result = build_unary_op (INDIRECT_REF, NULL_TREE, result); return result; |