Commit a4ab7973 by Joseph Myers Committed by Joseph Myers

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
parent 40806b8b
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> 2004-11-20 Jeff Law <law@redhat.com>
* regrename.c (copyprop_hardreg_forward): Only search for a * regrename.c (copyprop_hardreg_forward): Only search for a
......
...@@ -1594,39 +1594,58 @@ build_indirect_ref (tree ptr, const char *errorstring) ...@@ -1594,39 +1594,58 @@ build_indirect_ref (tree ptr, const char *errorstring)
tree tree
build_array_ref (tree array, tree index) build_array_ref (tree array, tree index)
{ {
if (index == 0) bool swapped = false;
{
error ("subscript missing in array reference");
return error_mark_node;
}
if (TREE_TYPE (array) == error_mark_node if (TREE_TYPE (array) == error_mark_node
|| TREE_TYPE (index) == error_mark_node) || TREE_TYPE (index) == error_mark_node)
return error_mark_node; return error_mark_node;
if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE) if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE)
{ {
tree rval, type; tree temp;
if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
/* Subscripting with type char is likely to lose && TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
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"); error ("subscripted value is neither array nor pointer");
return error_mark_node; 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;
/* An array that is indexed by a non-constant /* An array that is indexed by a non-constant
cannot be stored in a register; we must be able to do cannot be stored in a register; we must be able to do
...@@ -1681,45 +1700,19 @@ build_array_ref (tree array, tree index) ...@@ -1681,45 +1700,19 @@ build_array_ref (tree array, tree index)
| TREE_THIS_VOLATILE (array)); | TREE_THIS_VOLATILE (array));
return require_complete_type (fold (rval)); return require_complete_type (fold (rval));
} }
else
{
tree ar = default_conversion (array);
{ if (ar == error_mark_node)
tree ar = default_conversion (array); return ar;
tree ind = default_conversion (index);
/* 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%>");
/* 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 gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE);
|| TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) == FUNCTION_TYPE) gcc_assert (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), return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, index, 0),
"array indexing"); "array indexing");
} }
} }
/* Build an external reference to identifier ID. FUN indicates /* Build an external reference to identifier ID. FUN indicates
......
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> 2004-11-20 Eric Botcazou <ebotcazou@libertysurf.fr>
PR target/18580 PR target/18580
......
/* 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];
}
/* 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 } */
}
...@@ -32,8 +32,8 @@ g (void) ...@@ -32,8 +32,8 @@ g (void)
f -= 1; f -= 1;
p[0]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ p[0]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
0[p]; /* { 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" } */ f[0]; /* { dg-error "error: subscripted value is pointer to function" } */
0[f]; /* { dg-error "error: subscripted value is neither array nor pointer" } */ 0[f]; /* { dg-error "error: subscripted value is pointer to function" } */
p - p; p - p;
f - f; f - f;
} }
...@@ -34,8 +34,8 @@ g (void) ...@@ -34,8 +34,8 @@ g (void)
/* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */ /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */
0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ 0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
/* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 35 } */ /* { 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" } */ f[0]; /* { dg-error "error: subscripted value is pointer to function" } */
0[f]; /* { dg-error "error: subscripted value is neither array nor pointer" } */ 0[f]; /* { dg-error "error: subscripted value is pointer to function" } */
p - p; /* { dg-warning "warning: pointer of type 'void \\*' used in subtraction" } */ p - p; /* { dg-warning "warning: pointer of type 'void \\*' used in subtraction" } */
f - f; /* { dg-warning "warning: pointer to a function used in subtraction" } */ f - f; /* { dg-warning "warning: pointer to a function used in subtraction" } */
} }
...@@ -34,8 +34,8 @@ g (void) ...@@ -34,8 +34,8 @@ g (void)
/* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */ /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */
0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ 0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
/* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 35 } */ /* { 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" } */ f[0]; /* { dg-error "error: subscripted value is pointer to function" } */
0[f]; /* { dg-error "error: subscripted value is neither array nor pointer" } */ 0[f]; /* { dg-error "error: subscripted value is pointer to function" } */
p - p; /* { dg-warning "warning: pointer of type 'void \\*' used in subtraction" } */ p - p; /* { dg-warning "warning: pointer of type 'void \\*' used in subtraction" } */
f - f; /* { dg-warning "warning: pointer to a function used in subtraction" } */ f - f; /* { dg-warning "warning: pointer to a function used in subtraction" } */
} }
...@@ -34,8 +34,8 @@ g (void) ...@@ -34,8 +34,8 @@ g (void)
/* { dg-error "error: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */ /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */
0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ 0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */
/* { dg-error "error: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 35 } */ /* { 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" } */ f[0]; /* { dg-error "error: subscripted value is pointer to function" } */
0[f]; /* { dg-error "error: subscripted value is neither array nor pointer" } */ 0[f]; /* { dg-error "error: subscripted value is pointer to function" } */
p - p; /* { dg-error "error: pointer of type 'void \\*' used in subtraction" } */ p - p; /* { dg-error "error: pointer of type 'void \\*' used in subtraction" } */
f - f; /* { dg-error "error: pointer to a function used in subtraction" } */ f - f; /* { dg-error "error: pointer to a function used in subtraction" } */
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment