diff options
| author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-20 20:31:52 +0000 |
|---|---|---|
| committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-20 20:31:52 +0000 |
| commit | 20931c08f468f8239334ec3d938e7554a8819998 (patch) | |
| tree | 744160b47cb98a4ccacd021c089dc864bfb2cedd /gcc/c-typeck.c | |
| parent | bb30f677e665bca25e979d13b23a9fc83c83d883 (diff) | |
| download | ppe42-gcc-20931c08f468f8239334ec3d938e7554a8819998.tar.gz ppe42-gcc-20931c08f468f8239334ec3d938e7554a8819998.zip | |
* 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
Diffstat (limited to 'gcc/c-typeck.c')
| -rw-r--r-- | gcc/c-typeck.c | 115 |
1 files changed, 54 insertions, 61 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 90ca0defce4..c5401042b66 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 %<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) + 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 %<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 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 %<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 (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 |

