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++] don't expand &a.b to pointer arithmetic


Final patch in this series for C++.

All the hard work is done by build_base_path.  If the path is nice
and friendly (no virtual bases and whatnot) then we build "&obj.<base>.f".
If there's a virtual base involved, then of course all the correct
pointer ugliness happens.

The build_base_path change is to avoid recursion, since build_unary_op
would call right back into build_base_path again.

The g++.dg/other/offsetof1.C change avoids a pedantic error about
a non-constant expression being used where one is required.  Which
is correct.  We should have been generating at least a warning here
beforehand.


r~


        * class.c (build_base_path): Use build_address directly.
        * typeck.c (build_unary_op): Don't lower &a.b to pointer
        arithmetic directly.
        * typeck2.c (store_init_value): Don't assume !TREE_CONSTANT
        means !initializer_constant_valid_p.

        * g++.dg/other/offsetof1.C: Use __builtin_offsetof.

Index: gcc/cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.663
diff -u -p -r1.663 class.c
--- gcc/cp/class.c	30 Aug 2004 15:28:37 -0000	1.663
+++ gcc/cp/class.c	30 Aug 2004 18:02:55 -0000
@@ -319,7 +319,7 @@ build_base_path (enum tree_code code,
       expr = build_indirect_ref (expr, NULL);
       expr = build_simple_base_path (expr, binfo);
       if (want_pointer)
-	expr = build_unary_op (ADDR_EXPR, expr, 0);
+	expr = build_address (expr);
       target_type = TREE_TYPE (expr);
       goto out;
     }
Index: gcc/cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.571
diff -u -p -r1.571 typeck.c
--- gcc/cp/typeck.c	30 Aug 2004 16:03:47 -0000	1.571
+++ gcc/cp/typeck.c	30 Aug 2004 18:02:56 -0000
@@ -3963,19 +3963,6 @@ build_unary_op (enum tree_code code, tre
 	  return arg;
 	}
 
-      /* For &x[y], return x+y.  But, in a template, ARG may be an
-	 ARRAY_REF representing a non-dependent expression.  In that
-	 case, there may be an overloaded "operator []" that will be
-	 chosen at instantiation time; we must not try to optimize
-	 here.  */
-      if (TREE_CODE (arg) == ARRAY_REF && !processing_template_decl)
-	{
-	  if (!cxx_mark_addressable (TREE_OPERAND (arg, 0)))
-	    return error_mark_node;
-	  return cp_build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
-				     TREE_OPERAND (arg, 1));
-	}
-
       /* Uninstantiated types are all functions.  Taking the
 	 address of a function is a no-op, so just return the
 	 argument.  */
@@ -4099,9 +4086,6 @@ build_unary_op (enum tree_code code, tre
 	  }
 	else
 	  {
-	    /* Unfortunately we cannot just build an address
-	       expression here, because we would not handle
-	       address-constant-expressions or offsetof correctly.  */
 	    tree field = TREE_OPERAND (arg, 1);
 	    tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
 	    tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (rval)),
@@ -4109,10 +4093,9 @@ build_unary_op (enum tree_code code, tre
 				      ba_check, NULL);
 	    
 	    rval = build_base_path (PLUS_EXPR, rval, binfo, 1);
-	    rval = build_nop (argtype, rval);
-	    addr = fold (build2 (PLUS_EXPR, argtype, rval,
-				 cp_convert (argtype,
-					     byte_position (field))));
+
+	    TREE_OPERAND (arg, 0) = build_indirect_ref (rval, NULL);
+	    addr = build_address (arg);
 	  }
 
 	if (TREE_CODE (argtype) == POINTER_TYPE
Index: gcc/cp/typeck2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck2.c,v
retrieving revision 1.171
diff -u -p -r1.171 typeck2.c
--- gcc/cp/typeck2.c	30 Aug 2004 16:03:48 -0000	1.171
+++ gcc/cp/typeck2.c	30 Aug 2004 18:02:56 -0000
@@ -609,7 +609,7 @@ store_init_value (tree decl, tree init)
   else if (TYPE_NEEDS_CONSTRUCTING (type))
     return build2 (INIT_EXPR, type, decl, value);
   else if (TREE_STATIC (decl)
-	   && (! TREE_CONSTANT (value)
+	   && (TREE_SIDE_EFFECTS (value)
 	       || ! initializer_constant_valid_p (value, TREE_TYPE (value))))
     return split_nonconstant_init (decl, value);
   
Index: gcc/testsuite/g++.dg/other/offsetof1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/other/offsetof1.C,v
retrieving revision 1.2
diff -u -p -r1.2 offsetof1.C
--- gcc/testsuite/g++.dg/other/offsetof1.C	27 Aug 2002 20:55:17 -0000	1.2
+++ gcc/testsuite/g++.dg/other/offsetof1.C	30 Aug 2004 18:02:56 -0000
@@ -11,4 +11,4 @@ struct F
   char j;
 };
 
-static int ary[((__SIZE_TYPE__)&((struct F *)0)->j)];
+static int ary[__builtin_offsetof(F, j)];


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