[clang] b76219b - [clang][Sema] Use correct array size for diagnostic

Bill Wendling via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 20 11:57:03 PDT 2022


Author: Bill Wendling
Date: 2022-10-20T11:56:49-07:00
New Revision: b76219b590208c1b539e614247f91481900bd7a1

URL: https://github.com/llvm/llvm-project/commit/b76219b590208c1b539e614247f91481900bd7a1
DIFF: https://github.com/llvm/llvm-project/commit/b76219b590208c1b539e614247f91481900bd7a1.diff

LOG: [clang][Sema] Use correct array size for diagnostic

The diagnostic was confusing and reporting that an array contains far
more elements than it is defined to have, due to casting.

For example, this code:

  double foo[4096];
  ((char*)foo)[sizeof(foo)];

warns that the "index 32768 is past the end of the array (which contains
32768 elements)."

Reviewed By: serge-sans-paille, aaron.ballman

Differential Revision: https://reviews.llvm.org/D135920

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaChecking.cpp
    clang/test/Sema/array-bounds-ptr-arith.c
    clang/test/Sema/integer-overflow.c
    clang/test/SemaCXX/array-bounds-ptr-arith.cpp
    clang/test/SemaCXX/array-bounds-strict-flex-arrays.cpp
    clang/test/SemaCXX/array-bounds.cpp
    clang/test/SemaCXX/integer-overflow.cpp
    clang/test/SemaObjC/flexible-array-bounds.m

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1a4db1fa689cc..8198d62bc8d5f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -321,6 +321,10 @@ Improvements to Clang's diagnostics
   on the previous undocumented behavior. As a side effect of this change,
   constructor calls outside of initializer expressions are no longer ignored,
   which can result in new warnings (or make existing warnings disappear).
+- The wording of diagnostics regarding arithmetic on fixed-sized arrays and
+  pointers is improved to include the type of the array and whether it's cast
+  to another type. This should improve comprehension for why an index is
+  out-of-bounds.
 
 Non-comprehensive list of changes in this release
 -------------------------------------------------

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0396d6fae26ac..b1d475772502b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9401,15 +9401,14 @@ def warn_ptr_arith_precedes_bounds : Warning<
   "the pointer decremented by %0 refers before the beginning of the array">,
   InGroup<ArrayBoundsPointerArithmetic>, DefaultIgnore;
 def warn_ptr_arith_exceeds_bounds : Warning<
-  "the pointer incremented by %0 refers past the end of the array (that "
-  "contains %1 element%s2)">,
+  "the pointer incremented by %0 refers past the end of the array (that has type %1)">,
   InGroup<ArrayBoundsPointerArithmetic>, DefaultIgnore;
 def warn_array_index_precedes_bounds : Warning<
   "array index %0 is before the beginning of the array">,
   InGroup<ArrayBounds>;
 def warn_array_index_exceeds_bounds : Warning<
-  "array index %0 is past the end of the array (which contains %1 "
-  "element%s2)">, InGroup<ArrayBounds>;
+  "array index %0 is past the end of the array (that has type %1%select{|, cast to %3}2)">,
+  InGroup<ArrayBounds>;
 def warn_ptr_arith_exceeds_max_addressable_bounds : Warning<
   "the pointer incremented by %0 refers past the last possible element for an array in %1-bit "
   "address space containing %2-bit (%3-byte) elements (max possible %4 element%s5)">,

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 9d8640a6a057a..73710e87ea675 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16069,12 +16069,13 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
 
     unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
                           : diag::warn_ptr_arith_exceeds_bounds;
+    unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
+    QualType CastMsgTy = ASE ? ASE->getLHS()->getType() : QualType();
 
-    DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
-                        PDiag(DiagID) << toString(index, 10, true)
-                                      << toString(size, 10, true)
-                                      << (unsigned)size.getLimitedValue(~0U)
-                                      << IndexExpr->getSourceRange());
+    DiagRuntimeBehavior(
+        BaseExpr->getBeginLoc(), BaseExpr,
+        PDiag(DiagID) << toString(index, 10, true) << ArrayTy->desugar()
+                      << CastMsg << CastMsgTy << IndexExpr->getSourceRange());
   } else {
     unsigned DiagID = diag::warn_array_index_precedes_bounds;
     if (!ASE) {

diff  --git a/clang/test/Sema/array-bounds-ptr-arith.c b/clang/test/Sema/array-bounds-ptr-arith.c
index 57baf9241cf0e..a76a8884120bc 100644
--- a/clang/test/Sema/array-bounds-ptr-arith.c
+++ b/clang/test/Sema/array-bounds-ptr-arith.c
@@ -11,7 +11,7 @@ void* ext2_statfs (struct ext2_super_block *es,int a) {
   return (void *)es->s_uuid + sizeof(int); // no-warning
 }
 void* broken (struct ext2_super_block *es,int a) {
-  return (void *)es->s_uuid + 9; // expected-warning {{the pointer incremented by 9 refers past the end of the array}}
+  return (void *)es->s_uuid + 9; // expected-warning {{the pointer incremented by 9 refers past the end of the array (that has type 'unsigned char[8]')}}
 }
 
 // Test case reduced from PR11594
@@ -40,7 +40,7 @@ typedef struct RDar11387038_B RDar11387038_B;
 
 void radar11387038(void) {
   RDar11387038_B *pRDar11387038_B;
-  struct RDar11387038 *y = &(*pRDar11387038_B->x)->z[4]; // strict-warning {{array index 4 is past the end of the array (which contains 1 element)}}
+  struct RDar11387038 *y = &(*pRDar11387038_B->x)->z[4]; // strict-warning {{array index 4 is past the end of the array (that has type 'struct RDar11387038[1]')}}
 }
 
 void pr51682(void) {

diff  --git a/clang/test/Sema/integer-overflow.c b/clang/test/Sema/integer-overflow.c
index 36c84b2d0537a..cf822f346e8b2 100644
--- a/clang/test/Sema/integer-overflow.c
+++ b/clang/test/Sema/integer-overflow.c
@@ -142,7 +142,7 @@ uint64_t check_integer_overflows(int i) {
   (__imag__ x) = 4608 * 1024 * 1024;
 
 // expected-warning at +4 {{overflow in expression; result is 536870912 with type 'int'}}
-// expected-warning at +3 {{array index 536870912 is past the end of the array (which contains 10 elements)}}
+// expected-warning at +3 {{array index 536870912 is past the end of the array (that has type 'uint64_t[10]' (aka 'unsigned long long[10]'))}}
 // expected-note at +1 {{array 'a' declared here}}
   uint64_t a[10];
   a[4608 * 1024 * 1024] = 1i;

diff  --git a/clang/test/SemaCXX/array-bounds-ptr-arith.cpp b/clang/test/SemaCXX/array-bounds-ptr-arith.cpp
index 16e2567c53e99..39467fd13a09c 100644
--- a/clang/test/SemaCXX/array-bounds-ptr-arith.cpp
+++ b/clang/test/SemaCXX/array-bounds-ptr-arith.cpp
@@ -6,13 +6,13 @@ void test_pointer_arithmetic(int n) {
   const char *helloptr = hello;
 
   swallow("Hello world!" + 6); // no-warning
-  swallow("Hello world!" - 6); // expected-warning {{refers before the beginning of the array}}
-  swallow("Hello world!" + 14); // expected-warning {{refers past the end of the array}}
+  swallow("Hello world!" - 6); // expected-warning {{the pointer decremented by 6 refers before the beginning of the array}}
+  swallow("Hello world!" + 14); // expected-warning {{the pointer incremented by 14 refers past the end of the array (that has type 'const char[13]')}}
   swallow("Hello world!" + 13); // no-warning
 
   swallow(hello + 6); // no-warning
-  swallow(hello - 6); // expected-warning {{refers before the beginning of the array}}
-  swallow(hello + 14); // expected-warning {{refers past the end of the array}}
+  swallow(hello - 6); // expected-warning {{the pointer decremented by 6 refers before the beginning of the array}}
+  swallow(hello + 14); // expected-warning {{the pointer incremented by 14 refers past the end of the array (that has type 'const char[13]')}}
   swallow(hello + 13); // no-warning
 
   swallow(helloptr + 6); // no-warning
@@ -22,12 +22,12 @@ void test_pointer_arithmetic(int n) {
 
   double numbers[2]; // expected-note {{declared here}}
   swallow((char*)numbers + sizeof(double)); // no-warning
-  swallow((char*)numbers + 60); // expected-warning {{refers past the end of the array}}
+  swallow((char*)numbers + 60); // expected-warning {{the pointer incremented by 60 refers past the end of the array (that has type 'double[2]')}}
 
   char buffer[5]; // expected-note 2 {{declared here}}
   // TODO: Add FixIt notes for adding parens around non-ptr part of arith expr
-  swallow(buffer + sizeof("Hello")-1); // expected-warning {{refers past the end of the array}}
+  swallow(buffer + sizeof("Hello")-1); // expected-warning {{the pointer incremented by 6 refers past the end of the array (that has type 'char[5]')}}
   swallow(buffer + (sizeof("Hello")-1)); // no-warning
-  if (n > 0 && n <= 6) swallow(buffer + 6 - n); // expected-warning {{refers past the end of the array}}
+  if (n > 0 && n <= 6) swallow(buffer + 6 - n); // expected-warning {{the pointer incremented by 6 refers past the end of the array (that has type 'char[5]')}}
   if (n > 0 && n <= 6) swallow(buffer + (6 - n)); // no-warning
 }

diff  --git a/clang/test/SemaCXX/array-bounds-strict-flex-arrays.cpp b/clang/test/SemaCXX/array-bounds-strict-flex-arrays.cpp
index 7136973a8ab8e..639c072a849b2 100644
--- a/clang/test/SemaCXX/array-bounds-strict-flex-arrays.cpp
+++ b/clang/test/SemaCXX/array-bounds-strict-flex-arrays.cpp
@@ -16,7 +16,7 @@ struct t0 {
   int a[10]; // relaxed-note {{array 'a' declared here}}
 };
 void test0(t0 *s2) {
-  s2->a[12] = 0; // relaxed-warning {{array index 12 is past the end of the array (which contains 10 elements)}}
+  s2->a[12] = 0; // relaxed-warning {{array index 12 is past the end of the array (that has type 'int[10]')}}
 }
 
 
@@ -26,7 +26,7 @@ struct t1 {
   int a[1]; // strict-note {{array 'a' declared here}}
 };
 void test1(t1 *s2) {
-  s2->a[2] = 0; // strict-warning {{array index 2 is past the end of the array (which contains 1 element)}}
+  s2->a[2] = 0; // strict-warning {{array index 2 is past the end of the array (that has type 'int[1]')}}
 }
 
 // Under -fstrict-flex-arrays={1,2} `a` is a flexible array.

diff  --git a/clang/test/SemaCXX/array-bounds.cpp b/clang/test/SemaCXX/array-bounds.cpp
index 4e3da45b8f60b..b584e1e7cd453 100644
--- a/clang/test/SemaCXX/array-bounds.cpp
+++ b/clang/test/SemaCXX/array-bounds.cpp
@@ -8,16 +8,16 @@ int foo() {
   int v[1][1][1]; // expected-note {{array 'v' declared here}}
   int *p = &y[2]; // no-warning
   (void) sizeof(x[2]); // no-warning
-  y[2] = 2; // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
-  z[1] = 'x'; // expected-warning {{array index 1 is past the end of the array (which contains 1 element)}}
-  w[0][2] = 0; // expected-warning {{array index 2 is past the end of the array (which contains 1 element)}}
-  v[0][0][2] = 0; // expected-warning {{array index 2 is past the end of the array (which contains 1 element)}}
-  return x[2] +  // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+  y[2] = 2; // expected-warning {{array index 2 is past the end of the array (that has type 'int[2]')}}
+  z[1] = 'x'; // expected-warning {{array index 1 is past the end of the array (that has type 'int[1]')}}
+  w[0][2] = 0; // expected-warning {{array index 2 is past the end of the array (that has type 'int[1]')}}
+  v[0][0][2] = 0; // expected-warning {{array index 2 is past the end of the array (that has type 'int[1]')}}
+  return x[2] +  // expected-warning {{array index 2 is past the end of the array (that has type 'int[2]')}}
          y[-1] + // expected-warning {{array index -1 is before the beginning of the array}}
-         x[sizeof(x)] +  // expected-warning {{array index 8 is past the end of the array (which contains 2 elements)}}
-         x[sizeof(x) / sizeof(x[0])] +  // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+         x[sizeof(x)] +  // expected-warning {{array index 8 is past the end of the array (that has type 'int[2]')}}
+         x[sizeof(x) / sizeof(x[0])] +  // expected-warning {{array index 2 is past the end of the array (that has type 'int[2]')}}
          x[sizeof(x) / sizeof(x[0]) - 1] + // no-warning
-         x[sizeof(x[2])]; // expected-warning {{array index 4 is past the end of the array (which contains 2 elements)}}
+         x[sizeof(x[2])]; // expected-warning {{array index 4 is past the end of the array (that has type 'int[2]')}}
 }
 
 // This code example tests that -Warray-bounds works with arrays that
@@ -31,7 +31,7 @@ void f1(int a[1]) {
 }
 
 void f2(const int (&a)[2]) { // expected-note {{declared here}}
-  int val = a[3];  // expected-warning {{array index 3 is past the end of the array (which contains 2 elements)}}
+  int val = a[3];  // expected-warning {{array index 3 is past the end of the array (that has type 'const int[2]')}}
 }
 
 void test() {
@@ -44,33 +44,33 @@ void test() {
     short a[2]; // expected-note 4 {{declared here}}
     char c[4];
   } u;
-  u.a[3] = 1; // expected-warning {{array index 3 is past the end of the array (which contains 2 elements)}}
+  u.a[3] = 1; // expected-warning {{array index 3 is past the end of the array (that has type 'short[2]')}}
   u.c[3] = 1; // no warning
   short *p = &u.a[2]; // no warning
-  p = &u.a[3]; // expected-warning {{array index 3 is past the end of the array (which contains 2 elements)}}
-  *(&u.a[2]) = 1; // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
-  *(&u.a[3]) = 1; // expected-warning {{array index 3 is past the end of the array (which contains 2 elements)}}
+  p = &u.a[3]; // expected-warning {{array index 3 is past the end of the array (that has type 'short[2]')}}
+  *(&u.a[2]) = 1; // expected-warning {{array index 2 is past the end of the array (that has type 'short[2]')}}
+  *(&u.a[3]) = 1; // expected-warning {{array index 3 is past the end of the array (that has type 'short[2]')}}
   *(&u.c[3]) = 1; // no warning
 
   const int const_subscript = 3;
   int array[2]; // expected-note {{declared here}}
-  array[const_subscript] = 0;  // expected-warning {{array index 3 is past the end of the array (which contains 2 elements)}}
+  array[const_subscript] = 0;  // expected-warning {{array index 3 is past the end of the array (that has type 'int[2]')}}
 
   int *ptr;
   ptr[3] = 0; // no warning for pointer references
   int array2[] = { 0, 1, 2 }; // expected-note 2 {{declared here}}
 
-  array2[3] = 0; // expected-warning {{array index 3 is past the end of the array (which contains 3 elements)}}
-  array2[2+2] = 0; // expected-warning {{array index 4 is past the end of the array (which contains 3 elements)}}
+  array2[3] = 0; // expected-warning {{array index 3 is past the end of the array (that has type 'int[3]')}}
+  array2[2+2] = 0; // expected-warning {{array index 4 is past the end of the array (that has type 'int[3]')}}
 
   const char *str1 = "foo";
   char c1 = str1[5]; // no warning for pointers
 
   const char str2[] = "foo"; // expected-note {{declared here}}
-  char c2 = str2[5]; // expected-warning {{array index 5 is past the end of the array (which contains 4 elements)}}
+  char c2 = str2[5]; // expected-warning {{array index 5 is past the end of the array (that has type 'const char[4]')}}
 
   int (*array_ptr)[2];
-  (*array_ptr)[3] = 1; // expected-warning {{array index 3 is past the end of the array (which contains 2 elements)}}
+  (*array_ptr)[3] = 1; // expected-warning {{array index 3 is past the end of the array (that has type 'int[2]')}}
 }
 
 template <int I> struct S {
@@ -78,8 +78,8 @@ template <int I> struct S {
 };
 template <int I> void f() {
   S<3> s;
-  s.arr[4] = 0; // expected-warning 2 {{array index 4 is past the end of the array (which contains 3 elements)}}
-  s.arr[I] = 0; // expected-warning {{array index 5 is past the end of the array (which contains 3 elements)}}
+  s.arr[4] = 0; // expected-warning 2 {{array index 4 is past the end of the array (that has type 'char[3]')}}
+  s.arr[I] = 0; // expected-warning {{array index 5 is past the end of the array (that has type 'char[3]')}}
 }
 
 void test_templates() {
@@ -92,13 +92,13 @@ void test_templates() {
 int test_no_warn_macro_unreachable() {
   int arr[SIZE]; // expected-note {{array 'arr' declared here}}
   return ARR_IN_MACRO(0, arr, SIZE) + // no-warning
-         ARR_IN_MACRO(1, arr, SIZE); // expected-warning{{array index 10 is past the end of the array (which contains 10 elements)}}
+         ARR_IN_MACRO(1, arr, SIZE); // expected-warning{{array index 10 is past the end of the array (that has type 'int[10]')}}
 }
 
 // This exhibited an assertion failure for a 32-bit build of Clang.
 int test_pr9240() {
   short array[100]; // expected-note {{array 'array' declared here}}
-  return array[(unsigned long long) 100]; // expected-warning {{array index 100 is past the end of the array (which contains 100 elements)}}
+  return array[(unsigned long long) 100]; // expected-warning {{array index 100 is past the end of the array (that has type 'short[100]')}}
 }
 
 // PR 9284 - a template parameter can cause an array bounds access to be
@@ -116,7 +116,7 @@ void pr9284b() {
     int arr[3 + (extendArray ? 1 : 0)]; // expected-note {{array 'arr' declared here}}
 
     if (!extendArray)
-        arr[3] = 42; // expected-warning{{array index 3 is past the end of the array (which contains 3 elements)}}
+        arr[3] = 42; // expected-warning{{array index 3 is past the end of the array (that has type 'int[3]')}}
 }
 
 void test_pr9284() {
@@ -135,7 +135,7 @@ int test_sizeof_as_condition(int flag) {
   int arr[2] = { 0, 0 }; // expected-note {{array 'arr' declared here}}
   if (flag) 
     return sizeof(char) != sizeof(char) ? arr[2] : arr[1];
-  return sizeof(char) == sizeof(char) ? arr[2] : arr[1]; // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+  return sizeof(char) == sizeof(char) ? arr[2] : arr[1]; // expected-warning {{array index 2 is past the end of the array (that has type 'int[2]')}}
 }
 
 void test_switch() {
@@ -147,7 +147,7 @@ void test_switch() {
     }
     case 4: {
       int arr[2]; // expected-note {{array 'arr' declared here}}
-      arr[2] = 1; // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+      arr[2] = 1; // expected-warning {{array index 2 is past the end of the array (that has type 'int[2]')}}
       break;
     }
     default: {
@@ -199,9 +199,9 @@ namespace tailpad {
   };
 
   char bar(struct foo *F, baz *B) {
-    return F->c1[3] + // expected-warning {{array index 3 is past the end of the array (which contains 1 element)}}
+    return F->c1[3] + // expected-warning {{array index 3 is past the end of the array (that has type 'char[1]')}}
            F->c2[3] + // no warning, foo could have tail padding allocated.
-           B->c1[3] + // expected-warning {{array index 3 is past the end of the array (which contains 1 element)}}
+           B->c1[3] + // expected-warning {{array index 3 is past the end of the array (that has type 'char[1]')}}
            B->c2[3]; // no warning, baz could have tail padding allocated.
   }
 }
@@ -215,20 +215,20 @@ struct foo {
   template <int N> struct bar { char c[N]; }; // expected-note {{declared here}}
 
   char test(foo *F, bar<1> *B) {
-    return F->c[3] + // expected-warning {{array index 3 is past the end of the array (which contains 1 element)}}
-           B->c[3];  // expected-warning {{array index 3 is past the end of the array (which contains 1 element)}}
+    return F->c[3] + // expected-warning {{array index 3 is past the end of the array (that has type 'char[1]')}}
+           B->c[3];  // expected-warning {{array index 3 is past the end of the array (that has type 'char[1]')}}
   }
 }
 
 void bar(int x) {}
 int test_more() {
   int foo[5]; // expected-note 5 {{array 'foo' declared here}}
-  bar(foo[5]); // expected-warning {{array index 5 is past the end of the array (which contains 5 elements)}}
-  ++foo[5]; // expected-warning {{array index 5 is past the end of the array (which contains 5 elements)}}
-  if (foo[6]) // expected-warning {{array index 6 is past the end of the array (which contains 5 elements)}}
-    return --foo[6]; // expected-warning {{array index 6 is past the end of the array (which contains 5 elements)}}
+  bar(foo[5]); // expected-warning {{array index 5 is past the end of the array (that has type 'int[5]')}}
+  ++foo[5]; // expected-warning {{array index 5 is past the end of the array (that has type 'int[5]')}}
+  if (foo[6]) // expected-warning {{array index 6 is past the end of the array (that has type 'int[5]')}}
+    return --foo[6]; // expected-warning {{array index 6 is past the end of the array (that has type 'int[5]')}}
   else
-    return foo[5]; // expected-warning {{array index 5 is past the end of the array (which contains 5 elements)}}
+    return foo[5]; // expected-warning {{array index 5 is past the end of the array (that has type 'int[5]')}}
 }
 
 void test_pr10771() {
@@ -237,7 +237,7 @@ void test_pr10771() {
     ((char*)foo)[sizeof(foo) - 1] = '\0';  // no-warning
     *(((char*)foo) + sizeof(foo) - 1) = '\0';  // no-warning
 
-    ((char*)foo)[sizeof(foo)] = '\0';  // expected-warning {{array index 32768 is past the end of the array (which contains 32768 elements)}}
+    ((char*)foo)[sizeof(foo)] = '\0';  // expected-warning {{array index 32768 is past the end of the array (that has type 'double[4096]', cast to 'char *')}}
 
     // TODO: This should probably warn, too.
     *(((char*)foo) + sizeof(foo)) = '\0';  // no-warning
@@ -248,13 +248,13 @@ int test_pr11007_aux(const char * restrict, ...);
 // Test checking with varargs.
 void test_pr11007() {
   double a[5]; // expected-note {{array 'a' declared here}}
-  test_pr11007_aux("foo", a[1000]); // expected-warning {{array index 1000 is past the end of the array}}
+  test_pr11007_aux("foo", a[1000]); // expected-warning {{array index 1000 is past the end of the array (that has type 'double[5]')}}
 }
 
 void test_rdar10916006(void)
 {
 	int a[128]; // expected-note {{array 'a' declared here}}
-	a[(unsigned char)'\xA1'] = 1; // expected-warning {{array index 161 is past the end of the array}}
+	a[(unsigned char)'\xA1'] = 1; // expected-warning {{array index 161 is past the end of the array (that has type 'int[128]')}}
 }
 
 struct P {
@@ -264,20 +264,20 @@ struct P {
 
 void test_struct_array_index() {
   struct P p[10]; // expected-note {{array 'p' declared here}}
-  p[11] = {0, 1}; // expected-warning {{array index 11 is past the end of the array (which contains 10 elements)}}
+  p[11] = {0, 1}; // expected-warning {{array index 11 is past the end of the array (that has type 'struct P[10]')}}
 }
 
 int operator+(const struct P &s1, const struct P &s2);
 int test_operator_overload_struct_array_index() {
   struct P x[10] = {0}; // expected-note {{array 'x' declared here}}
-  return x[1] + x[11]; // expected-warning {{array index 11 is past the end of the array (which contains 10 elements)}}
+  return x[1] + x[11]; // expected-warning {{array index 11 is past the end of the array (that has type 'struct P[10]')}}
 }
 
 int multi[2][2][2]; // expected-note 3 {{array 'multi' declared here}}
 int test_multiarray() {
-  return multi[2][0][0] + // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
-         multi[0][2][0] + // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
-         multi[0][0][2];  // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+  return multi[2][0][0] + // expected-warning {{array index 2 is past the end of the array (that has type 'int[2][2][2]')}}
+         multi[0][2][0] + // expected-warning {{array index 2 is past the end of the array (that has type 'int[2][2]')}}
+         multi[0][0][2];  // expected-warning {{array index 2 is past the end of the array (that has type 'int[2]')}}
 }
 
 struct multi_s {
@@ -285,7 +285,7 @@ struct multi_s {
 };
 struct multi_s multi2[4]; // expected-note {{array 'multi2' declared here}}
 int test_struct_multiarray() {
-  return multi2[4].arr[0]; // expected-warning {{array index 4 is past the end of the array (which contains 4 elements)}}
+  return multi2[4].arr[0]; // expected-warning {{array index 4 is past the end of the array (that has type 'struct multi_s[4]')}}
 }
 
 namespace PR39746 {
@@ -303,7 +303,7 @@ namespace PR39746 {
 namespace PR41087 {
   template <typename Ty> void foo() {
     Ty buffer[2]; // expected-note 3{{array 'buffer' declared here}}
-    ((char *)buffer)[2] = 'A'; // expected-warning 1{{array index 2 is past the end of the array (which contains 2 elements)}}
+    ((char *)buffer)[2] = 'A'; // expected-warning 1{{array index 2 is past the end of the array (that has type 'char[2]', cast to 'char *')}}
     ((char *)buffer)[-1] = 'A'; // expected-warning 2{{array index -1 is before the beginning of the array}}
   }
 
@@ -319,7 +319,7 @@ template <> int arr<float>[1];    // expected-note {{array 'arr<float>' declared
 
 void test() {
   arr<int>[1] = 0;   // ok
-  arr<int>[2] = 0;   // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
-  arr<float>[1] = 0; // expected-warning {{array index 1 is past the end of the array (which contains 1 element)}}
+  arr<int>[2] = 0;   // expected-warning {{array index 2 is past the end of the array (that has type 'int[2]')}}
+  arr<float>[1] = 0; // expected-warning {{array index 1 is past the end of the array (that has type 'int[1]')}}
 }
 } // namespace var_template_array

diff  --git a/clang/test/SemaCXX/integer-overflow.cpp b/clang/test/SemaCXX/integer-overflow.cpp
index c4d0d4084def1..2d8b7455f95f5 100644
--- a/clang/test/SemaCXX/integer-overflow.cpp
+++ b/clang/test/SemaCXX/integer-overflow.cpp
@@ -167,7 +167,7 @@ uint64_t check_integer_overflows(int i) { //expected-note 0+{{declared here}}
   uint64_t a[10];
   a[4608 * 1024 * 1024] = 1;
 #if __cplusplus < 201103L
-// expected-warning at -2 {{array index 536870912 is past the end of the array (which contains 10 elements)}}
+// expected-warning at -2 {{array index 536870912 is past the end of the array (that has type 'uint64_t[10]' (aka 'unsigned long long[10]'))}}
 // expected-note at -4 {{array 'a' declared here}}
 #endif
 

diff  --git a/clang/test/SemaObjC/flexible-array-bounds.m b/clang/test/SemaObjC/flexible-array-bounds.m
index 78202dc8c6c9f..1da535c8487ac 100644
--- a/clang/test/SemaObjC/flexible-array-bounds.m
+++ b/clang/test/SemaObjC/flexible-array-bounds.m
@@ -23,5 +23,4 @@ @interface Flexible1 {
 
 char readit(Flexible *p) { return p->flexible[2]; }
 char readit0(Flexible0 *p) { return p->flexible[2]; }
-char readit1(Flexible1 *p) { return p->flexible[2]; } // warn-warning {{array index 2 is past the end of the array (which contains 1 element)}}
-
+char readit1(Flexible1 *p) { return p->flexible[2]; } // warn-warning {{array index 2 is past the end of the array (that has type 'char[1]')}}


        


More information about the cfe-commits mailing list