diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -13421,6 +13421,15 @@ CheckArrayAccess(Arg); return; } + case Stmt::CStyleCastExprClass: + case Stmt::CXXStaticCastExprClass: + case Stmt::CXXDynamicCastExprClass: + case Stmt::CXXReinterpretCastExprClass: + case Stmt::CXXConstCastExprClass: { + const auto *ECE = cast(expr); + expr = ECE->getSubExpr(); + break; + } default: return; } diff --git a/clang/test/SemaCXX/array-bounds.cpp b/clang/test/SemaCXX/array-bounds.cpp --- a/clang/test/SemaCXX/array-bounds.cpp +++ b/clang/test/SemaCXX/array-bounds.cpp @@ -27,7 +27,7 @@ }; void f1(int a[1]) { - int val = a[3]; // no warning for function argumnet + int val = a[3]; // no warning for function argument } void f2(const int (&a)[2]) { // expected-note {{declared here}} @@ -133,7 +133,7 @@ int test_sizeof_as_condition(int flag) { int arr[2] = { 0, 0 }; // expected-note {{array 'arr' declared here}} - if (flag) + 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)}} } @@ -241,7 +241,7 @@ } int test_pr11007_aux(const char * restrict, ...); - + // Test checking with varargs. void test_pr11007() { double a[5]; // expected-note {{array 'a' declared here}} @@ -309,3 +309,23 @@ foo(); // expected-note 1{{in instantiation of function template specialization}} }; } + +namespace PR44343 { + const unsigned int array[2] = {0, 1}; // expected-note 4{{array 'array' declared here}} + + const int i1 = (const int)array[2]; // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} + const int i2 = static_cast(array[2]); // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} + const int &i3 = reinterpret_cast(array[2]); // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} + unsigned int &i4 = const_cast(array[2]); // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} + + struct Base { + virtual ~Base(); + }; + + struct Derived : Base { + }; + + Base baseArr[2]; // expected-note {{array 'baseArr' declared here}} + Derived *d1 = dynamic_cast(&baseArr[2]); // no warning for one-past-end element's address retrieval + Derived &d2 = dynamic_cast(baseArr[2]); // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} +}