This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, C] Emit &a[0] for array-to-pointer decay
- From: Richard Guenther <rguenth at tat dot physik dot uni-tuebingen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Henderson <rth at redhat dot com>
- Date: Tue, 26 Apr 2005 14:11:44 +0200 (CEST)
- Subject: [PATCH, C] Emit &a[0] for array-to-pointer decay
This patch changes the C frontend to emit &a[0] for array-to-pointer
decay as opposed to an ADDR_EXPR with kind-of non-matching types.
This patch is responsible for some extra failures (by triggering
problems elsewhere):
FAIL: gcc.dg/tree-ssa/pr15791-1.c (test for excess errors)
if (&b[0] == &b[2])
link_error();
is not optimized because of mismatching types (was &b == &b[2] before).
FAIL: gcc.c-torture/execute/builtins/strlen-3.c execution, -O2
ccp_fold_builtin is messing with
if (strlen (&bar[0] + (x++ & 7)) != 7)
abort ();
probably a bug within that function - it's working is magic to
me, though.
FAIL: gcc.dg/format/array-1.c unterminated array (test for warnings, line
26)
it's like
/net/alwazn/home/rguenth/src/gcc/cvs/gcc-4.1/gcc/testsuite/gcc.dg/format/array-1.c:23:
warning: format not a string literal and no format arguments
for printf (a1); I guess the check for the warning needs adjustment.
But I didn't see anything obvious in c-format.c:check_format_arg.
Note that the same (bogous?) warning occours for printf (&a1[0])
without the patch.
Otherwise the patch survived bootstrap and testing for on i686-linux
for c; the gimplify.c change is not applicable until all other frontends
are fixed.
Richard.
2005-04-26 Richard Guenther <rguenth@gcc.gnu.org>
* c-typeck.c (default_function_array_conversion): Emit
&a[0] for array-to-pointer decay.
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.436
diff -c -3 -p -r1.436 c-typeck.c
*** c-typeck.c 23 Apr 2005 21:27:34 -0000 1.436
--- c-typeck.c 26 Apr 2005 11:33:14 -0000
*************** default_function_array_conversion (tree
*** 1337,1347 ****
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. */
--- 1337,1351 ----
if (TREE_CODE (exp) == VAR_DECL)
{
! /* 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 = build1 (ADDR_EXPR, ptrtype,
! build4 (ARRAY_REF, restype,
! exp, integer_zero_node,
! NULL_TREE, NULL_TREE));
if (!c_mark_addressable (exp))
return error_mark_node;
TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.125
diff -c -3 -p -r2.125 gimplify.c
*** gimplify.c 22 Apr 2005 16:14:54 -0000 2.125
--- gimplify.c 26 Apr 2005 11:33:14 -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: