diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ebd71a1f53d7..d78ba88fabd3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2005-08-16 James A. Morrison + + * c-typeck.c (build_function_call): Call fold_buildN_initializer or + fold_buildN instead of buildN then fold_initializer or fold. + (build_unary_op): Likewise. + (build_binary_op): Likewise. + * fold-const.c (fold_initializer): Remove. + (fold_build1_initializer): New function. + (fold_build2_initializer): New function. + (fold_build3_initializer): New function. + * tree.h (fold_initializer): Remove. + (fold_build1_initializer): New function. + (fold_build2_initializer): New function. + (fold_build3_initializer): New function. + 2005-08-16 James A. Morrison * fold-const.c (optimize_bit_field_compare): Remove extra fold call. diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 39f682229a53..9ddab77fc503 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -2105,13 +2105,10 @@ build_function_call (tree function, tree params) check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params, TYPE_ARG_TYPES (fntype)); - result = build3 (CALL_EXPR, TREE_TYPE (fntype), - function, coerced_params, NULL_TREE); - TREE_SIDE_EFFECTS (result) = 1; - if (require_constant_value) { - result = fold_initializer (result); + result = fold_build3_initializer (CALL_EXPR, TREE_TYPE (fntype), + function, coerced_params, NULL_TREE); if (TREE_CONSTANT (result) && (name == NULL_TREE @@ -2119,7 +2116,8 @@ build_function_call (tree function, tree params) pedwarn_init ("initializer element is not constant"); } else - result = fold (result); + result = fold_build3 (CALL_EXPR, TREE_TYPE (fntype), + function, coerced_params, NULL_TREE); if (VOID_TYPE_P (TREE_TYPE (result))) return result; @@ -2828,8 +2826,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag) if (argtype == 0) argtype = TREE_TYPE (arg); - val = build1 (code, argtype, arg); - return require_constant_value ? fold_initializer (val) : fold (val); + return require_constant_value ? fold_build1_initializer (code, argtype, arg) + : fold_build1 (code, argtype, arg); } /* Return nonzero if REF is an lvalue valid for this language. @@ -8187,11 +8185,12 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, build_type = result_type; { - tree result = build2 (resultcode, build_type, op0, op1); - /* Treat expressions in initializers specially as they can't trap. */ - result = require_constant_value ? fold_initializer (result) - : fold (result); + tree result = require_constant_value ? fold_build2_initializer (resultcode, + build_type, + op0, op1) + : fold_build2 (resultcode, build_type, + op0, op1); if (final_type != 0) result = convert (final_type, result); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6853b413f09c..52a9a425a8b4 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10571,33 +10571,65 @@ fold_build3_stat (enum tree_code code, tree type, tree op0, tree op1, tree op2 } /* Perform constant folding and related simplification of initializer - expression EXPR. This behaves identically to "fold" but ignores + expression EXPR. These behave identically to "fold_buildN" but ignore potential run-time traps and exceptions that fold must preserve. */ +#define START_FOLD_INIT \ + int saved_signaling_nans = flag_signaling_nans;\ + int saved_trapping_math = flag_trapping_math;\ + int saved_rounding_math = flag_rounding_math;\ + int saved_trapv = flag_trapv;\ + flag_signaling_nans = 0;\ + flag_trapping_math = 0;\ + flag_rounding_math = 0;\ + flag_trapv = 0 + +#define END_FOLD_INIT \ + flag_signaling_nans = saved_signaling_nans;\ + flag_trapping_math = saved_trapping_math;\ + flag_rounding_math = saved_rounding_math;\ + flag_trapv = saved_trapv + tree -fold_initializer (tree expr) +fold_build1_initializer (enum tree_code code, tree type, tree op) { - int saved_signaling_nans = flag_signaling_nans; - int saved_trapping_math = flag_trapping_math; - int saved_rounding_math = flag_rounding_math; - int saved_trapv = flag_trapv; tree result; + START_FOLD_INIT; - flag_signaling_nans = 0; - flag_trapping_math = 0; - flag_rounding_math = 0; - flag_trapv = 0; - - result = fold (expr); - - flag_signaling_nans = saved_signaling_nans; - flag_trapping_math = saved_trapping_math; - flag_rounding_math = saved_rounding_math; - flag_trapv = saved_trapv; + result = fold_build1 (code, type, op); + END_FOLD_INIT; return result; } +tree +fold_build2_initializer (enum tree_code code, tree type, tree op0, tree op1) +{ + tree result; + START_FOLD_INIT; + + result = fold_build2 (code, type, op0, op1); + + END_FOLD_INIT; + return result; +} + +tree +fold_build3_initializer (enum tree_code code, tree type, tree op0, tree op1, + tree op2) +{ + tree result; + START_FOLD_INIT; + + result = fold_build3 (code, type, op0, op1, op2); + + END_FOLD_INIT; + return result; +} + +#undef START_FOLD_INIT +#undef END_FOLD_INIT + /* Determine if first argument is a multiple of second argument. Return 0 if it is not, or we cannot easily determined it to be. diff --git a/gcc/tree.h b/gcc/tree.h index 7ddfa97dae41..91b38278a4b4 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3795,7 +3795,9 @@ extern tree fold_build2_stat (enum tree_code, tree, tree, tree MEM_STAT_DECL); #define fold_build2(c,t1,t2,t3) fold_build2_stat (c, t1, t2, t3 MEM_STAT_INFO) extern tree fold_build3_stat (enum tree_code, tree, tree, tree, tree MEM_STAT_DECL); #define fold_build3(c,t1,t2,t3,t4) fold_build3_stat (c, t1, t2, t3, t4 MEM_STAT_INFO) -extern tree fold_initializer (tree); +extern tree fold_build1_initializer (enum tree_code, tree, tree); +extern tree fold_build2_initializer (enum tree_code, tree, tree, tree); +extern tree fold_build3_initializer (enum tree_code, tree, tree, tree, tree); extern tree fold_convert (tree, tree); extern tree fold_single_bit_test (enum tree_code, tree, tree, tree); extern tree fold_ignored_result (tree);