diff options
author | Angel Garcia Gomez <angelgarcia@google.com> | 2015-11-06 09:59:14 +0000 |
---|---|---|
committer | Angel Garcia Gomez <angelgarcia@google.com> | 2015-11-06 09:59:14 +0000 |
commit | 7856ad0bccd6d4956b2dd319ccdf8375d3b73964 (patch) | |
tree | e8b9eeb44e01a4f6a1a2a325c63a22ce589fd592 | |
parent | dccffd4fcc5e23d6f79a39bf3c04146b2684c485 (diff) | |
download | bcm5719-llvm-7856ad0bccd6d4956b2dd319ccdf8375d3b73964.tar.gz bcm5719-llvm-7856ad0bccd6d4956b2dd319ccdf8375d3b73964.zip |
Fix another case where loop-convert wasn't handling correctly data members.
Summary:
If the container expression was obtained from the point where "size" (which usually is a const method) is invoked, then the topmost node in this expression may be an implicit cast to const.
When the container is a data member, the check was trying to obtain the member expression directly and was failing in the case mentioned above. This is solved by ignoring implicit casts.
Reviewers: klimek
Subscribers: cfe-commits, alexfh
Differential Revision: http://reviews.llvm.org/D14378
llvm-svn: 252278
-rw-r--r-- | clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp | 6 | ||||
-rw-r--r-- | clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp | 25 |
2 files changed, 28 insertions, 3 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp index c09e3278589..bd476dd5e79 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -352,12 +352,12 @@ static StringRef getStringFromRange(SourceManager &SourceMgr, LangOpts); } -/// \brief If the given expression is actually a DeclRefExpr, find and return -/// the underlying ValueDecl; otherwise, return NULL. +/// \brief If the given expression is actually a DeclRefExpr or a MemberExpr, +/// find and return the underlying ValueDecl; otherwise, return NULL. static const ValueDecl *getReferencedVariable(const Expr *E) { if (const DeclRefExpr *DRE = getDeclRef(E)) return dyn_cast<VarDecl>(DRE->getDecl()); - if (const auto *Mem = dyn_cast<MemberExpr>(E)) + if (const auto *Mem = dyn_cast<MemberExpr>(E->IgnoreParenImpCasts())) return dyn_cast<FieldDecl>(Mem->getMemberDecl()); return nullptr; } diff --git a/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp b/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp index 104b2b2e5cd..576dedcdafa 100644 --- a/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp +++ b/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp @@ -240,6 +240,7 @@ void refs_and_vals() { struct MemberNaming { const static int N = 10; int Ints[N], Ints_[N]; + dependent<int> DInts; void loops() { for (int I = 0; I < N; ++I) { printf("%d\n", Ints[I]); @@ -254,8 +255,32 @@ struct MemberNaming { // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead // CHECK-FIXES: for (int Int : Ints_) // CHECK-FIXES-NEXT: printf("%d\n", Int); + + for (int I = 0; I < DInts.size(); ++I) { + printf("%d\n", DInts[I]); + } + // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead + // CHECK-FIXES: for (int DInt : DInts) + // CHECK-FIXES-NEXT: printf("%d\n", DInt); } + + void outOfLine(); }; +void MemberNaming::outOfLine() { + for (int I = 0; I < N; ++I) { + printf("%d\n", Ints[I]); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES-NEXT: printf("%d\n", Int); + + for (int I = 0; I < N; ++I) { + printf("%d\n", Ints_[I]); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (int Int : Ints_) + // CHECK-FIXES-NEXT: printf("%d\n", Int); +} } // namespace NamingAlias |