This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFA] Do not emit &a for &a[0] in the C frontend
- From: Richard Guenther <rguenth at tat dot physik dot uni-tuebingen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 17 May 2005 16:35:21 +0200 (CEST)
- Subject: [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: