Author: einvbri Date: 2021-02-08T06:38:31-06:00 New Revision: 9083d0a40d980928f2f45236a4616528a7ab19ce
URL: https://github.com/llvm/llvm-project/commit/9083d0a40d980928f2f45236a4616528a7ab19ce DIFF: https://github.com/llvm/llvm-project/commit/9083d0a40d980928f2f45236a4616528a7ab19ce.diff LOG: 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 Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaChecking.cpp clang/test/Parser/cxx-ambig-decl-expr.cpp clang/test/SemaCXX/array-bounds.cpp Removed: ################################################################################ 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 @@ class Sema final { 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)}} -} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits