[PATCH] no lowering of &a.b (and &a->b) in the C front-end

Andrew Pinski pinskia@physics.uc.edu
Mon Aug 23 00:13:00 GMT 2004


I found that both the C and C++ front-ends do lower &a.b into a + 
offsetof(b,a)
which is really not good for some optimizations which can change the 
struct
a into scaler values.

This patch changes the C front-end so there is no lowering and fixes a
bug found in c_finish_return with the no lowering turned on.  Warning 
about
returning a temporary which is true for &a->b.

OK? Bootstrapped and tested on powerpc-apple-darwin with no regressions.

I will be testing and posting the equivalent for C++ soon which then we 
should
be able to close some serious wrong-code bugs.

Thanks,
Andrew Pinski

ChangeLog;

	* c-typeck.c (build_unary_op): Use &a.b if the foldded lowered
	expression is not constant.
	(c_finish_return): Do not go through INDIRECT_REF when looking
	for the inner expression of an ADDR_EXPR for warning about.


Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.359
diff -u -p -r1.359 c-typeck.c
--- c-typeck.c	19 Aug 2004 10:35:52 -0000	1.359
+++ c-typeck.c	22 Aug 2004 23:37:09 -0000
@@ -2520,7 +2520,7 @@ build_unary_op (enum tree_code code, tre
  	return error_mark_node;

        {
-	tree addr;
+	tree addr, addr2;

  	if (TREE_CODE (arg) == COMPONENT_REF)
  	  {
@@ -2538,9 +2538,14 @@ build_unary_op (enum tree_code code, tre
  	    addr = fold (build2 (PLUS_EXPR, argtype,
  				 convert (argtype, addr),
  				 convert (argtype, byte_position (field))));
+	
+	    addr2 = build1 (ADDR_EXPR, argtype, arg);
+	
+	    if (!TREE_CONSTANT (addr) || TREE_CONSTANT (addr2))
+	      addr = addr2;
  	  }
  	else
-	  addr = build1 (code, argtype, arg);
+	  addr = build1 (ADDR_EXPR, argtype, arg);

  	if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
  	  TREE_INVARIANT (addr) = TREE_CONSTANT (addr) = 1;
@@ -6310,7 +6315,8 @@ c_finish_return (tree retval)
  	    case ADDR_EXPR:
  	      inner = TREE_OPERAND (inner, 0);

-	      while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r')
+	      while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r'
+	             && TREE_CODE (inner) != INDIRECT_REF)
  		inner = TREE_OPERAND (inner, 0);

  	      if (DECL_P (inner)



More information about the Gcc-patches mailing list