From 00d1b1d67536c0dc5737c721030798cde876c38a Mon Sep 17 00:00:00 2001
From: "James A. Morrison" <phython@gcc.gnu.org>
Date: Wed, 17 Aug 2005 04:00:21 +0000
Subject: [PATCH] c-typeck.c (build_function_call): Call
 fold_buildN_initializer or fold_buildN instead of buildN then...

2005-08-16  James A. Morrison  <phython@gcc.gnu.org>

        * 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.

From-SVN: r103201
---
 gcc/ChangeLog    | 15 +++++++++++
 gcc/c-typeck.c   | 23 ++++++++---------
 gcc/fold-const.c | 66 +++++++++++++++++++++++++++++++++++-------------
 gcc/tree.h       |  4 ++-
 4 files changed, 78 insertions(+), 30 deletions(-)

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  <phython@gcc.gnu.org>
+
+	* 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  <phython@gcc.gnu.org>
 
 	* 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);