This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: Fix decl_constant_value for COND_EXPRs


This patch implements Jason's suggestion that decl_constant_value
handle COND_EXPR specially; build_conditional_expr doesn't know
whether it's building an lvalue or an rvalue, sadly.  I've added a
test for the bug that I introduced, as well.

(One might also note that the back end could perform the
decl_constant_value operation when using a VAR_DECL in an rvalue
context...)

Tested on i686-pc-linux-gnu, applied on the mainline

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-08-28  Mark Mitchell  <mark@codesourcery.com>

	* init.c (decl_constant_value): Deal with COND_EXPR specially.
	* call.c (build_conditional_expr): Revert previous patch.

2003-08-28  Mark Mitchell  <mark@codesourcery.com>

	* g++.dg/expr/cond3.C: New test.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.426
diff -c -5 -p -r1.426 call.c
*** cp/call.c	28 Aug 2003 07:14:26 -0000	1.426
--- cp/call.c	29 Aug 2003 02:47:10 -0000
*************** build_conditional_expr (tree arg1, tree 
*** 3356,3367 ****
        error ("operands to ?: have different types");
        return error_mark_node;
      }
  
   valid_operands:
-   arg2 = decl_constant_value (arg2);
-   arg3 = decl_constant_value (arg3);
    result = fold (build (COND_EXPR, result_type, arg1, arg2, arg3));
    /* We can't use result_type below, as fold might have returned a
       throw_expr.  */
  
    /* Expand both sides into the same slot, hopefully the target of the
--- 3356,3365 ----
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.340
diff -c -5 -p -r1.340 init.c
*** cp/init.c	19 Aug 2003 12:54:59 -0000	1.340
--- cp/init.c	29 Aug 2003 02:47:10 -0000
*************** build_offset_ref (tree type, tree name, 
*** 1585,1594 ****
--- 1585,1612 ----
     constant, then return that value.  */
  
  tree
  decl_constant_value (tree decl)
  {
+   /* When we build a COND_EXPR, we don't know whether it will be used
+      as an lvalue or as an rvalue.  If it is an lvalue, it's not safe
+      to replace the second and third operands with their
+      initializers.  So, we do that here.  */
+   if (TREE_CODE (decl) == COND_EXPR)
+     {
+       tree d1;
+       tree d2;
+ 
+       d1 = decl_constant_value (TREE_OPERAND (decl, 1));
+       d2 = decl_constant_value (TREE_OPERAND (decl, 2));
+ 
+       if (d1 != TREE_OPERAND (decl, 1) || d2 != TREE_OPERAND (decl, 2))
+ 	return build (COND_EXPR,
+ 		      TREE_TYPE (decl),
+ 		      TREE_OPERAND (decl, 0), d1, d2);
+     }
+ 
    if (TREE_READONLY_DECL_P (decl)
        && ! TREE_THIS_VOLATILE (decl)
        && DECL_INITIAL (decl)
        && DECL_INITIAL (decl) != error_mark_node
        /* This is invalid if initial value is not constant.
Index: testsuite/g++.dg/expr/cond3.C
===================================================================
RCS file: testsuite/g++.dg/expr/cond3.C
diff -N testsuite/g++.dg/expr/cond3.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/expr/cond3.C	29 Aug 2003 02:47:11 -0000
***************
*** 0 ****
--- 1,6 ----
+ const int i = 7;
+ const int j = 3;
+ 
+ void f(bool b) {
+   &(b ? i : j);
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]