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:
parent
40806b8b8f
commit
a4ab7973cf
|
@ -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
|
||||
|
|
117
gcc/c-typeck.c
117
gcc/c-typeck.c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
|
@ -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 } */
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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" } */
|
||||
}
|
||||
|
|
|
@ -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" } */
|
||||
}
|
||||
|
|
|
@ -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" } */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue