Index: clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp =================================================================== --- clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp +++ clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp @@ -48,7 +48,8 @@ // constructor has an arraySubscriptExpr. Finder->addMatcher( arraySubscriptExpr( - hasBase(ignoringImpCasts(hasType(constantArrayType().bind("type")))), + hasBase(ignoringImpCasts(declRefExpr( + hasType(constantArrayType().bind("type"))).bind("declRef"))), hasIndex(expr().bind("index")), unless(hasAncestor(isImplicit()))) .bind("expr"), this); @@ -57,7 +58,8 @@ cxxOperatorCallExpr( hasOverloadedOperatorName("[]"), hasArgument( - 0, hasType(cxxRecordDecl(hasName("::std::array")).bind("type"))), + 0, declRefExpr(hasType(cxxRecordDecl( + hasName("::std::array")).bind("type"))).bind("declRef")), hasArgument(1, expr().bind("index"))) .bind("expr"), this); @@ -67,6 +69,7 @@ const MatchFinder::MatchResult &Result) { const auto *Matched = Result.Nodes.getNodeAs("expr"); const auto *IndexExpr = Result.Nodes.getNodeAs("index"); + const auto *DeclRef = Result.Nodes.getNodeAs("declRef"); if (IndexExpr->isValueDependent()) return; // We check in the specialization. @@ -74,13 +77,9 @@ llvm::APSInt Index; if (!IndexExpr->isIntegerConstantExpr(Index, *Result.Context, nullptr, /*isEvaluated=*/true)) { - SourceRange BaseRange; - if (const auto *ArraySubscriptE = dyn_cast(Matched)) - BaseRange = ArraySubscriptE->getBase()->getSourceRange(); - else - BaseRange = - dyn_cast(Matched)->getArg(0)->getSourceRange(); + SourceRange BaseRange = DeclRef->getSourceRange(); SourceRange IndexRange = IndexExpr->getSourceRange(); + StringRef DeclRefName = DeclRef->getFoundDecl()->getName(); auto Diag = diag(Matched->getExprLoc(), "do not use array subscript when the index is " @@ -89,9 +88,9 @@ if (!GslHeader.empty()) { Diag << FixItHint::CreateInsertion(BaseRange.getBegin(), "gsl::at(") << FixItHint::CreateReplacement( - SourceRange(BaseRange.getEnd().getLocWithOffset(1), + SourceRange(BaseRange.getBegin(), IndexRange.getBegin().getLocWithOffset(-1)), - ", ") + (DeclRefName + ", ").str()) << FixItHint::CreateReplacement(Matched->getEndLoc(), ")"); Optional Insertion = Inserter->CreateIncludeInsertion( Index: test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp =================================================================== --- test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp +++ test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp @@ -25,48 +25,48 @@ return base + 3; } -void f(std::array a, int pos) { - a [ pos / 2 /*comment*/] = 1; +void f(std::array list, int pos) { + list [ pos / 2 /*comment*/] = 1; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index] - // CHECK-FIXES: gsl::at(a, pos / 2 /*comment*/) = 1; - int j = a[pos - 1]; + // CHECK-FIXES: gsl::at(list, pos / 2 /*comment*/) = 1; + int j = list[pos - 1]; // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead - // CHECK-FIXES: int j = gsl::at(a, pos - 1); + // CHECK-FIXES: int j = gsl::at(list, pos - 1); - a.at(pos-1) = 2; // OK, at() instead of [] - gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of [] + list.at(pos-1) = 2; // OK, at() instead of [] + gsl::at(list, pos-1) = 2; // OK, gsl::at() instead of [] - a[-1] = 3; + list[-1] = 3; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index] - a[10] = 4; + list[10] = 4; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index] - a[const_index(7)] = 3; + list[const_index(7)] = 3; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) - a[0] = 3; // OK, constant index and inside bounds - a[1] = 3; // OK, constant index and inside bounds - a[9] = 3; // OK, constant index and inside bounds - a[const_index(6)] = 3; // OK, constant index and inside bounds + list[0] = 3; // OK, constant index and inside bounds + list[1] = 3; // OK, constant index and inside bounds + list[9] = 3; // OK, constant index and inside bounds + list[const_index(6)] = 3; // OK, constant index and inside bounds } void g() { - int a[10]; + int list[10]; for (int i = 0; i < 10; ++i) { - a[i] = i; + list[i] = i; // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead - // CHECK-FIXES: gsl::at(a, i) = i; - gsl::at(a, i) = i; // OK, gsl::at() instead of [] + // CHECK-FIXES: gsl::at(list, i) = i; + gsl::at(list, i) = i; // OK, gsl::at() instead of [] } - a[-1] = 3; // flagged by clang-diagnostic-array-bounds - a[10] = 4; // flagged by clang-diagnostic-array-bounds - a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds - - a[0] = 3; // OK, constant index and inside bounds - a[1] = 3; // OK, constant index and inside bounds - a[9] = 3; // OK, constant index and inside bounds - a[const_index(6)] = 3; // OK, constant index and inside bounds + list[-1] = 3; // flagged by clang-diagnostic-array-bounds + list[10] = 4; // flagged by clang-diagnostic-array-bounds + list[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds + + list[0] = 3; // OK, constant index and inside bounds + list[1] = 3; // OK, constant index and inside bounds + list[9] = 3; // OK, constant index and inside bounds + list[const_index(6)] = 3; // OK, constant index and inside bounds } struct S { Index: test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp =================================================================== --- test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp +++ test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp @@ -23,46 +23,46 @@ return base + 3; } -void f(std::array a, int pos) { - a [ pos / 2 /*comment*/] = 1; +void f(std::array list, int pos) { + list [ pos / 2 /*comment*/] = 1; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index] - int j = a[pos - 1]; + int j = list[pos - 1]; // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead - a.at(pos-1) = 2; // OK, at() instead of [] - gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of [] + list.at(pos-1) = 2; // OK, at() instead of [] + gsl::at(list, pos-1) = 2; // OK, gsl::at() instead of [] - a[-1] = 3; + list[-1] = 3; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index] - a[10] = 4; + list[10] = 4; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index] - a[const_index(7)] = 3; + list[const_index(7)] = 3; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) - a[0] = 3; // OK, constant index and inside bounds - a[1] = 3; // OK, constant index and inside bounds - a[9] = 3; // OK, constant index and inside bounds - a[const_index(6)] = 3; // OK, constant index and inside bounds + list[0] = 3; // OK, constant index and inside bounds + list[1] = 3; // OK, constant index and inside bounds + list[9] = 3; // OK, constant index and inside bounds + list[const_index(6)] = 3; // OK, constant index and inside bounds } void g() { - int a[10]; + int list[10]; for (int i = 0; i < 10; ++i) { - a[i] = i; + list[i] = i; // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead - // CHECK-FIXES: gsl::at(a, i) = i; - gsl::at(a, i) = i; // OK, gsl::at() instead of [] + // CHECK-FIXES: gsl::at(list, i) = i; + gsl::at(list, i) = i; // OK, gsl::at() instead of [] } - a[-1] = 3; // flagged by clang-diagnostic-array-bounds - a[10] = 4; // flagged by clang-diagnostic-array-bounds - a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds - - a[0] = 3; // OK, constant index and inside bounds - a[1] = 3; // OK, constant index and inside bounds - a[9] = 3; // OK, constant index and inside bounds - a[const_index(6)] = 3; // OK, constant index and inside bounds + list[-1] = 3; // flagged by clang-diagnostic-array-bounds + list[10] = 4; // flagged by clang-diagnostic-array-bounds + list[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds + + list[0] = 3; // OK, constant index and inside bounds + list[1] = 3; // OK, constant index and inside bounds + list[9] = 3; // OK, constant index and inside bounds + list[const_index(6)] = 3; // OK, constant index and inside bounds } struct S {