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]

[RFA] Do not emit &a for &a[0] in the C frontend


This patch finally enables the C frontend to no longer emit
&a with mismatched types from array-to-pointer decay.

Passed C bootstrap and regression tests on i686.  Of course
the gimplify.c hunk will break other languages and f.i. mudflap.

Comments?  I'll probably submit the fold-const.c part separately.

Richard.


2005-05-17  Richard Guenther  <rguenth@gcc.gnu.org>

	* c-typeck.c (default_function_array_conversion): Emit
	array-to-pointer decay as &a[0].
	(build_unary_op): Emit &a[i] in its original form rather
	than splitting it to a + i.
	* fold-const.c (fold_binary): Handle zero-size array elements
	in folding of comparisons of ARRAY_REFs.

	* gimplify.c (check_pointer_types_r): ADDR_EXPR no longer
	can be of type array element for array operands.

Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.442
diff -c -3 -p -r1.442 c-typeck.c
*** c-typeck.c	17 May 2005 06:45:46 -0000	1.442
--- c-typeck.c	17 May 2005 13:58:45 -0000
*************** default_function_array_conversion (tree
*** 1343,1364 ****

        ptrtype = build_pointer_type (restype);

!       if (TREE_CODE (exp) == VAR_DECL)
! 	{
! 	  /* We are making an ADDR_EXPR of ptrtype.  This is a valid
! 	     ADDR_EXPR because it's the best way of representing what
! 	     happens in C when we take the address of an array and place
! 	     it in a pointer to the element type.  */
! 	  adr = build1 (ADDR_EXPR, ptrtype, exp);
! 	  if (!c_mark_addressable (exp))
! 	    return error_mark_node;
! 	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
! 	  return adr;
! 	}
!       /* This way is better for a COMPONENT_REF since it can
! 	 simplify the offset for a component.  */
!       adr = build_unary_op (ADDR_EXPR, exp, 1);
!       return convert (ptrtype, adr);
      }
    return exp;
  }
--- 1343,1361 ----

        ptrtype = build_pointer_type (restype);

!       /* We are making an ADDR_EXPR of ptrtype.  So we need to
! 	 construct an ARRAY_REF to the first element of the
! 	 array for tree type correctness.  This is the best way of
! 	 representing what happens in C when we take the address of
! 	 an array and place it in a pointer to the element type.  */
!       adr = build_unary_op (ADDR_EXPR,
! 			    build4 (ARRAY_REF, restype,
! 				    exp, integer_zero_node,
! 				    NULL_TREE, NULL_TREE), 1);
!       if (!c_mark_addressable (exp))
! 	return error_mark_node;
!       TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
!       return adr;
      }
    return exp;
  }
*************** build_unary_op (enum tree_code code, tre
*** 2738,2751 ****
  	  return TREE_OPERAND (arg, 0);
  	}

!       /* For &x[y], return x+y */
!       if (TREE_CODE (arg) == ARRAY_REF)
! 	{
! 	  if (!c_mark_addressable (TREE_OPERAND (arg, 0)))
! 	    return error_mark_node;
! 	  return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
! 				  TREE_OPERAND (arg, 1), 1);
! 	}

        /* Anything not already handled and not a true memory reference
  	 or a non-lvalue array is an error.  */
--- 2735,2743 ----
  	  return TREE_OPERAND (arg, 0);
  	}

!       if (TREE_CODE (arg) == ARRAY_REF
! 	  && !c_mark_addressable (TREE_OPERAND (arg, 0)))
! 	return error_mark_node;

        /* Anything not already handled and not a true memory reference
  	 or a non-lvalue array is an error.  */
*************** build_unary_op (enum tree_code code, tre
*** 2783,2789 ****

        val = build1 (ADDR_EXPR, argtype, arg);

!       if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
  	TREE_INVARIANT (val) = TREE_CONSTANT (val) = 1;

        return val;
--- 2775,2783 ----

        val = build1 (ADDR_EXPR, argtype, arg);

!       if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR
! 	  || (TREE_CODE (arg) == ARRAY_REF
! 	      && TREE_CODE (TREE_OPERAND (arg, 0)) == COMPOUND_LITERAL_EXPR))
  	TREE_INVARIANT (val) = TREE_CONSTANT (val) = 1;

        return val;
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.580
diff -c -3 -p -r1.580 fold-const.c
*** fold-const.c	14 May 2005 15:42:01 -0000	1.580
--- fold-const.c	17 May 2005 14:22:02 -0000
*************** fold_binary (enum tree_code code, tree t
*** 8962,8967 ****
--- 8962,8973 ----
  	      && extract_array_ref (arg1, &base1, &offset1)
  	      && operand_equal_p (base0, base1, 0))
  	    {
+ 	      tree eltype0 = TREE_TYPE (TREE_TYPE (base0));
+ 	      tree eltype1 = TREE_TYPE (TREE_TYPE (base1));
+ 	      if (integer_zerop (TYPE_SIZE_UNIT (eltype0)))
+ 		offset0 = NULL_TREE;
+ 	      if (integer_zerop (TYPE_SIZE_UNIT (eltype1)))
+ 		offset1 = NULL_TREE;
  	      if (offset0 == NULL_TREE
  		  && offset1 == NULL_TREE)
  		{
Index: gcc/gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.125
diff -c -3 -p -r2.125 gimplify.c
*** gcc/gimplify.c	22 Apr 2005 16:14:54 -0000	2.125
--- gcc/gimplify.c	28 Apr 2005 13:24:28 -0000
*************** check_pointer_types_r (tree *tp, int *wa
*** 4500,4516 ****
        ptype = TREE_TYPE (t);
        otype = TREE_TYPE (TREE_OPERAND (t, 0));
        dtype = TREE_TYPE (ptype);
!       if (!cpt_same_type (otype, dtype))
! 	{
! 	  /* &array is allowed to produce a pointer to the element, rather than
! 	     a pointer to the array type.  We must allow this in order to
! 	     properly represent assigning the address of an array in C into
! 	     pointer to the element type.  */
! 	  gcc_assert (TREE_CODE (otype) == ARRAY_TYPE
! 		      && POINTER_TYPE_P (ptype)
! 		      && cpt_same_type (TREE_TYPE (otype), dtype));
! 	  break;
! 	}
        break;

      default:
--- 4500,4506 ----
        ptype = TREE_TYPE (t);
        otype = TREE_TYPE (TREE_OPERAND (t, 0));
        dtype = TREE_TYPE (ptype);
!       gcc_assert (cpt_same_type (otype, dtype));
        break;

      default:


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