From 20931c08f468f8239334ec3d938e7554a8819998 Mon Sep 17 00:00:00 2001 From: jsm28 Date: Sat, 20 Nov 2004 20:31:52 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@90969 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++ gcc/c-typeck.c | 115 ++++++++++++++---------------- gcc/testsuite/ChangeLog | 7 ++ gcc/testsuite/gcc.dg/Wchar-subscripts-1.c | 29 ++++++++ gcc/testsuite/gcc.dg/array-8.c | 49 +++++++++++++ gcc/testsuite/gcc.dg/pointer-arith-1.c | 4 +- gcc/testsuite/gcc.dg/pointer-arith-2.c | 4 +- gcc/testsuite/gcc.dg/pointer-arith-3.c | 4 +- gcc/testsuite/gcc.dg/pointer-arith-4.c | 4 +- 9 files changed, 154 insertions(+), 69 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wchar-subscripts-1.c create mode 100644 gcc/testsuite/gcc.dg/array-8.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ffbfc55..7601d20 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-11-20 Joseph S. Myers + + * 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 * regrename.c (copyprop_hardreg_forward): Only search for a diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 90ca0de..c540104 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1594,39 +1594,58 @@ 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) + if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE + && TREE_CODE (TREE_TYPE (array)) != POINTER_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 %"); - - /* 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) + tree temp; + if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE + && TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE) { - error ("array subscript is not an integer"); + 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 %"); + + /* 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 cannot be stored in a register; we must be able to do @@ -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); - - /* 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 %"); - - /* 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 (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; - } + gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE); + gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE); - 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8fe6b3b..ef3ca31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2004-11-20 Joseph S. Myers + + * 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 PR target/18580 diff --git a/gcc/testsuite/gcc.dg/Wchar-subscripts-1.c b/gcc/testsuite/gcc.dg/Wchar-subscripts-1.c new file mode 100644 index 0000000..d1efd25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wchar-subscripts-1.c @@ -0,0 +1,29 @@ +/* Test -Wchar-subscripts. */ +/* Origin: Joseph Myers */ +/* { 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]; +} diff --git a/gcc/testsuite/gcc.dg/array-8.c b/gcc/testsuite/gcc.dg/array-8.c new file mode 100644 index 0000000..6d0a211 --- /dev/null +++ b/gcc/testsuite/gcc.dg/array-8.c @@ -0,0 +1,49 @@ +/* Test diagnostics for array references. */ +/* Origin: Joseph Myers */ +/* { 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 } */ +} diff --git a/gcc/testsuite/gcc.dg/pointer-arith-1.c b/gcc/testsuite/gcc.dg/pointer-arith-1.c index fec2054..3bf7887 100644 --- a/gcc/testsuite/gcc.dg/pointer-arith-1.c +++ b/gcc/testsuite/gcc.dg/pointer-arith-1.c @@ -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; } diff --git a/gcc/testsuite/gcc.dg/pointer-arith-2.c b/gcc/testsuite/gcc.dg/pointer-arith-2.c index 8e95ab5..fde01e1 100644 --- a/gcc/testsuite/gcc.dg/pointer-arith-2.c +++ b/gcc/testsuite/gcc.dg/pointer-arith-2.c @@ -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" } */ } diff --git a/gcc/testsuite/gcc.dg/pointer-arith-3.c b/gcc/testsuite/gcc.dg/pointer-arith-3.c index 90f5241..f23f677 100644 --- a/gcc/testsuite/gcc.dg/pointer-arith-3.c +++ b/gcc/testsuite/gcc.dg/pointer-arith-3.c @@ -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" } */ } diff --git a/gcc/testsuite/gcc.dg/pointer-arith-4.c b/gcc/testsuite/gcc.dg/pointer-arith-4.c index 3e577fc..b17f9d7 100644 --- a/gcc/testsuite/gcc.dg/pointer-arith-4.c +++ b/gcc/testsuite/gcc.dg/pointer-arith-4.c @@ -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" } */ } -- 2.7.4