blob: 28c492fa4411c997cd58fc8964981c105f45759b [file] [log] [blame]
commit 9083d0a40d980928f2f45236a4616528a7ab19ce
Author: einvbri <vince.a.bridgers@ericsson.com>
Date: Mon Feb 8 06:38:31 2021 -0600
Revert "[Sema] Fix -Warray-bounds false negative when casting an out-of-bounds array item"
This reverts commit e48f444751cf781c42934b242b81f549da77bad0.
thakis noticed false reports, so reverting this change for now until
those can be sorted out.
See https://reviews.llvm.org/D71714
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 68420fcbb85f..8b5619945865 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12313,7 +12313,7 @@ private:
void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
const ArraySubscriptExpr *ASE=nullptr,
bool AllowOnePastEnd=true, bool IndexNegated=false);
- void CheckArrayAccess(const Expr *E, int AllowOnePastEnd = 0);
+ void CheckArrayAccess(const Expr *E);
// Used to grab the relevant information from a FormatAttr and a
// FunctionDeclaration.
struct FormatStringInfo {
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 17dd5c9e8d99..2d3d36f4adad 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14387,63 +14387,62 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
PDiag(diag::note_array_declared_here) << ND);
}
-void Sema::CheckArrayAccess(const Expr *expr, int AllowOnePastEnd) {
- if (!expr)
- return;
-
- expr = expr->IgnoreParenCasts();
- switch (expr->getStmtClass()) {
- case Stmt::ArraySubscriptExprClass: {
- const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(expr);
- CheckArrayAccess(ASE->getBase(), ASE->getIdx(), ASE, AllowOnePastEnd > 0);
- CheckArrayAccess(ASE->getBase(), AllowOnePastEnd);
- return;
- }
- case Stmt::MemberExprClass: {
- expr = cast<MemberExpr>(expr)->getBase();
- CheckArrayAccess(expr, /*AllowOnePastEnd=*/0);
- return;
- }
- case Stmt::OMPArraySectionExprClass: {
- const OMPArraySectionExpr *ASE = cast<OMPArraySectionExpr>(expr);
- if (ASE->getLowerBound())
- CheckArrayAccess(ASE->getBase(), ASE->getLowerBound(),
- /*ASE=*/nullptr, AllowOnePastEnd > 0);
- return;
- }
- case Stmt::UnaryOperatorClass: {
- // Only unwrap the * and & unary operators
- const UnaryOperator *UO = cast<UnaryOperator>(expr);
- expr = UO->getSubExpr();
- switch (UO->getOpcode()) {
- case UO_AddrOf:
- AllowOnePastEnd++;
- break;
- case UO_Deref:
- AllowOnePastEnd--;
- break;
- default:
- return;
+void Sema::CheckArrayAccess(const Expr *expr) {
+ int AllowOnePastEnd = 0;
+ while (expr) {
+ expr = expr->IgnoreParenImpCasts();
+ switch (expr->getStmtClass()) {
+ case Stmt::ArraySubscriptExprClass: {
+ const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(expr);
+ CheckArrayAccess(ASE->getBase(), ASE->getIdx(), ASE,
+ AllowOnePastEnd > 0);
+ expr = ASE->getBase();
+ break;
+ }
+ case Stmt::MemberExprClass: {
+ expr = cast<MemberExpr>(expr)->getBase();
+ break;
+ }
+ case Stmt::OMPArraySectionExprClass: {
+ const OMPArraySectionExpr *ASE = cast<OMPArraySectionExpr>(expr);
+ if (ASE->getLowerBound())
+ CheckArrayAccess(ASE->getBase(), ASE->getLowerBound(),
+ /*ASE=*/nullptr, AllowOnePastEnd > 0);
+ return;
+ }
+ case Stmt::UnaryOperatorClass: {
+ // Only unwrap the * and & unary operators
+ const UnaryOperator *UO = cast<UnaryOperator>(expr);
+ expr = UO->getSubExpr();
+ switch (UO->getOpcode()) {
+ case UO_AddrOf:
+ AllowOnePastEnd++;
+ break;
+ case UO_Deref:
+ AllowOnePastEnd--;
+ break;
+ default:
+ return;
+ }
+ break;
+ }
+ case Stmt::ConditionalOperatorClass: {
+ const ConditionalOperator *cond = cast<ConditionalOperator>(expr);
+ if (const Expr *lhs = cond->getLHS())
+ CheckArrayAccess(lhs);
+ if (const Expr *rhs = cond->getRHS())
+ CheckArrayAccess(rhs);
+ return;
+ }
+ case Stmt::CXXOperatorCallExprClass: {
+ const auto *OCE = cast<CXXOperatorCallExpr>(expr);
+ for (const auto *Arg : OCE->arguments())
+ CheckArrayAccess(Arg);
+ return;
+ }
+ default:
+ return;
}
- CheckArrayAccess(expr, AllowOnePastEnd);
- return;
- }
- case Stmt::ConditionalOperatorClass: {
- const ConditionalOperator *cond = cast<ConditionalOperator>(expr);
- if (const Expr *lhs = cond->getLHS())
- CheckArrayAccess(lhs, AllowOnePastEnd);
- if (const Expr *rhs = cond->getRHS())
- CheckArrayAccess(rhs, AllowOnePastEnd);
- return;
- }
- case Stmt::CXXOperatorCallExprClass: {
- const auto *OCE = cast<CXXOperatorCallExpr>(expr);
- for (const auto *Arg : OCE->arguments())
- CheckArrayAccess(Arg);
- return;
- }
- default:
- return;
}
}
diff --git a/clang/test/Parser/cxx-ambig-decl-expr.cpp b/clang/test/Parser/cxx-ambig-decl-expr.cpp
index 373fe250c6b5..6203db2fbd22 100644
--- a/clang/test/Parser/cxx-ambig-decl-expr.cpp
+++ b/clang/test/Parser/cxx-ambig-decl-expr.cpp
@@ -24,7 +24,7 @@ void arr() {
// This is array indexing not an array declarator because a comma expression
// is not syntactically a constant-expression.
- int(x[1,0]); // expected-warning 2{{unused}}
+ int(x[1,1]); // expected-warning 2{{unused}}
// This is array indexing not an array declaration because a braced-init-list
// is not syntactically a constant-expression.
diff --git a/clang/test/SemaCXX/array-bounds.cpp b/clang/test/SemaCXX/array-bounds.cpp
index 837175014fe5..47be6c2423dc 100644
--- a/clang/test/SemaCXX/array-bounds.cpp
+++ b/clang/test/SemaCXX/array-bounds.cpp
@@ -27,7 +27,7 @@ template <char *sz> class Qux {
};
void f1(int a[1]) {
- int val = a[3]; // no warning for function argument
+ int val = a[3]; // no warning for function argumnet
}
void f2(const int (&a)[2]) { // expected-note {{declared here}}
@@ -133,7 +133,7 @@ int test_pr9296() {
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 @@ void test_pr10771() {
}
int test_pr11007_aux(const char * restrict, ...);
-
+
// Test checking with varargs.
void test_pr11007() {
double a[5]; // expected-note {{array 'a' declared here}}
@@ -320,33 +320,3 @@ void test() {
arr<float>[1] = 0; // expected-warning {{array index 1 is past the end of the array (which contains 1 element)}}
}
} // namespace var_template_array
-
-namespace PR44343 {
- const unsigned int array[2] = {0, 1}; // expected-note 5{{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)}}
- int i5 = int(array[2]); // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
- const unsigned int *i6 = &(1 > 0 ? array[2] : array[1]); // no warning for one-past-end element's address retrieval
-
- // Test dynamic cast
- struct Base {
- virtual ~Base();
- };
- struct Derived : Base {
- };
- Base baseArr[2]; // expected-note {{array 'baseArr' declared here}}
- Derived *d1 = dynamic_cast<Derived *>(&baseArr[2]); // FIXME: Should actually warn because dynamic_cast accesses the vptr
- Derived &d2 = dynamic_cast<Derived &>(baseArr[2]); // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
-
- // Test operator `&` in combination with operators `.` and `->`
- struct A {
- int n;
- };
- A a[2]; // expected-note {{array 'a' declared here}}
- int *n = &a[2].n; // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
- A *aPtr[2]; // expected-note {{array 'aPtr' declared here}}
- int *n2 = &aPtr[2]->n; // expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
-}