c-typeck.c (build_array_ref): Don't check for index == 0.
authorJoseph Myers <joseph@codesourcery.com>
Sat, 20 Nov 2004 20:31:52 +0000 (20:31 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Sat, 20 Nov 2004 20:31:52 +0000 (20:31 +0000)
* 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

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wchar-subscripts-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/array-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pointer-arith-1.c
gcc/testsuite/gcc.dg/pointer-arith-2.c
gcc/testsuite/gcc.dg/pointer-arith-3.c
gcc/testsuite/gcc.dg/pointer-arith-4.c

index ffbfc55..7601d20 100644 (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
index 90ca0de..c540104 100644 (file)
@@ -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");
+    }
 }
 \f
 /* Build an external reference to identifier ID.  FUN indicates
index 8fe6b3b..ef3ca31 100644 (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
diff --git a/gcc/testsuite/gcc.dg/Wchar-subscripts-1.c b/gcc/testsuite/gcc.dg/Wchar-subscripts-1.c
new file mode 100644 (file)
index 0000000..d1efd25
--- /dev/null
@@ -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];
+}
diff --git a/gcc/testsuite/gcc.dg/array-8.c b/gcc/testsuite/gcc.dg/array-8.c
new file mode 100644 (file)
index 0000000..6d0a211
--- /dev/null
@@ -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 } */
+}
index fec2054..3bf7887 100644 (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;
 }
index 8e95ab5..fde01e1 100644 (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" } */
 }
index 90f5241..f23f677 100644 (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" } */
 }
index 3e577fc..b17f9d7 100644 (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" } */
 }