c-typeck.c (build_array_ref): Don't check for index == 0.

* c-typeck.c (build_array_ref): Don't check for index == 0.  Make
	checks for neither argument being an array or pointer (swapping
	the arguments if necessary), the array argument being a pointer to
	or array of functions and for -Wchar-subscripts warnings upfront.

testsuite:
	* gcc.dg/Wchar-subscripts-1.c, gcc.dg/array-8.c: New tests.
	* gcc.dg/pointer-arith-1.c, gcc.dg/pointer-arith-2.c,
	gcc.dg/pointer-arith-3.c, gcc.dg/pointer-arith-4.c: Update
	expected diagnostics.

From-SVN: r90969
This commit is contained in:
Joseph Myers 2004-11-20 20:31:52 +00:00 committed by Joseph Myers
parent 40806b8b8f
commit a4ab7973cf
9 changed files with 155 additions and 70 deletions

View File

@ -1,3 +1,10 @@
2004-11-20 Joseph S. Myers <joseph@codesourcery.com>
* c-typeck.c (build_array_ref): Don't check for index == 0. Make
checks for neither argument being an array or pointer (swapping
the arguments if necessary), the array argument being a pointer to
or array of functions and for -Wchar-subscripts warnings upfront.
2004-11-20 Jeff Law <law@redhat.com>
* regrename.c (copyprop_hardreg_forward): Only search for a

View File

@ -1594,40 +1594,59 @@ build_indirect_ref (tree ptr, const char *errorstring)
tree
build_array_ref (tree array, tree index)
{
if (index == 0)
{
error ("subscript missing in array reference");
return error_mark_node;
}
bool swapped = false;
if (TREE_TYPE (array) == error_mark_node
|| TREE_TYPE (index) == error_mark_node)
return error_mark_node;
if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE)
{
tree temp;
if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
{
error ("subscripted value is neither array nor pointer");
return error_mark_node;
}
temp = array;
array = index;
index = temp;
swapped = true;
}
if (!INTEGRAL_TYPE_P (TREE_TYPE (index)))
{
error ("array subscript is not an integer");
return error_mark_node;
}
if (TREE_CODE (TREE_TYPE (TREE_TYPE (array))) == FUNCTION_TYPE)
{
error ("subscripted value is pointer to function");
return error_mark_node;
}
/* Subscripting with type char is likely to lose on a machine where
chars are signed. So warn on any machine, but optionally. Don't
warn for unsigned char since that type is safe. Don't warn for
signed char because anyone who uses that must have done so
deliberately. ??? Existing practice has also been to warn only
when the char index is syntactically the index, not for
char[array]. */
if (warn_char_subscripts && !swapped
&& TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
warning ("array subscript has type %<char%>");
/* Apply default promotions *after* noticing character types. */
index = default_conversion (index);
gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
{
tree rval, type;
/* Subscripting with type char is likely to lose
on a machine where chars are signed.
So warn on any machine, but optionally.
Don't warn for unsigned char since that type is safe.
Don't warn for signed char because anyone who uses that
must have done so deliberately. */
if (warn_char_subscripts
&& TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
warning ("array subscript has type %<char%>");
/* Apply default promotions *after* noticing character types. */
index = default_conversion (index);
/* Require integer *after* promotion, for sake of enums. */
if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE)
{
error ("array subscript is not an integer");
return error_mark_node;
}
/* An array that is indexed by a non-constant
cannot be stored in a register; we must be able to do
address arithmetic on its address.
@ -1681,45 +1700,19 @@ build_array_ref (tree array, tree index)
| TREE_THIS_VOLATILE (array));
return require_complete_type (fold (rval));
}
else
{
tree ar = default_conversion (array);
{
tree ar = default_conversion (array);
tree ind = default_conversion (index);
if (ar == error_mark_node)
return ar;
/* Do the same warning check as above, but only on the part that's
syntactically the index and only if it is also semantically
the index. */
if (warn_char_subscripts
&& TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE
&& TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
warning ("subscript has type %<char%>");
gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE);
gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
/* Put the integer in IND to simplify error checking. */
if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
{
tree temp = ar;
ar = ind;
ind = temp;
}
if (ar == error_mark_node)
return ar;
if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE
|| TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) == FUNCTION_TYPE)
{
error ("subscripted value is neither array nor pointer");
return error_mark_node;
}
if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
{
error ("array subscript is not an integer");
return error_mark_node;
}
return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0),
"array indexing");
}
return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, index, 0),
"array indexing");
}
}
/* Build an external reference to identifier ID. FUN indicates

View File

@ -1,3 +1,10 @@
2004-11-20 Joseph S. Myers <joseph@codesourcery.com>
* gcc.dg/Wchar-subscripts-1.c, gcc.dg/array-8.c: New tests.
* gcc.dg/pointer-arith-1.c, gcc.dg/pointer-arith-2.c,
gcc.dg/pointer-arith-3.c, gcc.dg/pointer-arith-4.c: Update
expected diagnostics.
2004-11-20 Eric Botcazou <ebotcazou@libertysurf.fr>
PR target/18580

View File

@ -0,0 +1,29 @@
/* Test -Wchar-subscripts. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "-Wchar-subscripts" } */
extern int a[];
int *p;
char c;
signed char sc;
unsigned char uc;
void
f (void)
{
a[sc];
a[uc];
sc[a];
uc[a];
p[sc];
p[uc];
sc[p];
uc[p];
a[c]; /* { dg-warning "warning: array subscript has type 'char'" } */
p[c]; /* { dg-warning "warning: array subscript has type 'char'" } */
/* -Wchar-subscripts does not warn if the char is not syntactically
the subscript. */
c[a];
c[p];
}

View File

@ -0,0 +1,49 @@
/* Test diagnostics for array references. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "-std=gnu89" } */
struct s { char c[1]; };
struct s f (void);
_Bool b;
char c;
enum e { E } e;
extern int a[];
int *p;
void *pv;
void (*fp)(void);
struct si *sip;
void
g (void)
{
a[b];
a[c];
a[e];
p[b];
p[c];
p[e];
b[a];
c[a];
e[a];
b[p];
c[p];
e[p];
/* These two should be treated the same. In particular, a "neither
array nor pointer" bogus warning used to be given for the
second. */
f().c[0];
0[f().c];
/* Various invalid cases. */
c[c]; /* { dg-error "error: subscripted value is neither array nor pointer" } */
p[1.0]; /* { dg-error "error: array subscript is not an integer" } */
1.0[a]; /* { dg-error "error: array subscript is not an integer" } */
fp[0]; /* { dg-error "error: subscripted value is pointer to function" } */
0[fp]; /* { dg-error "error: subscripted value is pointer to function" } */
pv[0]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
0[pv]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
sip[0]; /* { dg-error "error: invalid use of undefined type 'struct si'" } */
/* { dg-error "error: dereferencing pointer to incomplete type" "" { target *-*-* } 45 } */
0[sip]; /* { dg-error "error: invalid use of undefined type 'struct si'" } */
/* { dg-error "error: dereferencing pointer to incomplete type" "" { target *-*-* } 47 } */
}

View File

@ -32,8 +32,8 @@ g (void)
f -= 1;
p[0]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
f[0]; /* { dg-error "error: subscripted value is neither array nor pointer" } */
0[f]; /* { dg-error "error: subscripted value is neither array nor pointer" } */
f[0]; /* { dg-error "error: subscripted value is pointer to function" } */
0[f]; /* { dg-error "error: subscripted value is pointer to function" } */
p - p;
f - f;
}

View File

@ -34,8 +34,8 @@ g (void)
/* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */
0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
/* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 35 } */
f[0]; /* { dg-error "error: subscripted value is neither array nor pointer" } */
0[f]; /* { dg-error "error: subscripted value is neither array nor pointer" } */
f[0]; /* { dg-error "error: subscripted value is pointer to function" } */
0[f]; /* { dg-error "error: subscripted value is pointer to function" } */
p - p; /* { dg-warning "warning: pointer of type 'void \\*' used in subtraction" } */
f - f; /* { dg-warning "warning: pointer to a function used in subtraction" } */
}

View File

@ -34,8 +34,8 @@ g (void)
/* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */
0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
/* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 35 } */
f[0]; /* { dg-error "error: subscripted value is neither array nor pointer" } */
0[f]; /* { dg-error "error: subscripted value is neither array nor pointer" } */
f[0]; /* { dg-error "error: subscripted value is pointer to function" } */
0[f]; /* { dg-error "error: subscripted value is pointer to function" } */
p - p; /* { dg-warning "warning: pointer of type 'void \\*' used in subtraction" } */
f - f; /* { dg-warning "warning: pointer to a function used in subtraction" } */
}

View File

@ -34,8 +34,8 @@ g (void)
/* { dg-error "error: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */
0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
/* { dg-error "error: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 35 } */
f[0]; /* { dg-error "error: subscripted value is neither array nor pointer" } */
0[f]; /* { dg-error "error: subscripted value is neither array nor pointer" } */
f[0]; /* { dg-error "error: subscripted value is pointer to function" } */
0[f]; /* { dg-error "error: subscripted value is pointer to function" } */
p - p; /* { dg-error "error: pointer of type 'void \\*' used in subtraction" } */
f - f; /* { dg-error "error: pointer to a function used in subtraction" } */
}