ilya created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
[Sema] Fix -Warray-bounds false negative when casting an out-of-bounds array
item
Fixes: http://llvm.org/PR44343
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D71714
Files:
clang/lib/Sema/SemaChecking.cpp
clang/test/SemaCXX/array-bounds.cpp
Index: clang/test/SemaCXX/array-bounds.cpp
===================================================================
--- clang/test/SemaCXX/array-bounds.cpp
+++ 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<int>(); // 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<const int>(array[2]); // expected-warning {{array
index 2 is past the end of the array (which contains 2 elements)}}
+ const int &i3 = reinterpret_cast<const int&>(array[2]); // expected-warning
{{array index 2 is past the end of the array (which contains 2 elements)}}
+ unsigned int &i4 = const_cast<unsigned int&>(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<Derived *>(&baseArr[2]); // no warning for
one-past-end element's address retrieval
+ Derived &d2 = dynamic_cast<Derived &>(baseArr[2]); // expected-warning
{{array index 2 is past the end of the array (which contains 2 elements)}}
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ 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<ExplicitCastExpr>(expr);
+ expr = ECE->getSubExpr();
+ break;
+ }
default:
return;
}
Index: clang/test/SemaCXX/array-bounds.cpp
===================================================================
--- clang/test/SemaCXX/array-bounds.cpp
+++ 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<int>(); // 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<const int>(array[2]); // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+ const int &i3 = reinterpret_cast<const int&>(array[2]); // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+ unsigned int &i4 = const_cast<unsigned int&>(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<Derived *>(&baseArr[2]); // no warning for one-past-end element's address retrieval
+ Derived &d2 = dynamic_cast<Derived &>(baseArr[2]); // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ 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<ExplicitCastExpr>(expr);
+ expr = ECE->getSubExpr();
+ break;
+ }
default:
return;
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits