angelgarcia created this revision. angelgarcia added a reviewer: klimek. angelgarcia added subscribers: alexfh, cfe-commits.
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. http://reviews.llvm.org/D14378 Files: clang-tidy/modernize/LoopConvertCheck.cpp test/clang-tidy/modernize-loop-convert-extra.cpp Index: test/clang-tidy/modernize-loop-convert-extra.cpp =================================================================== --- test/clang-tidy/modernize-loop-convert-extra.cpp +++ test/clang-tidy/modernize-loop-convert-extra.cpp @@ -240,6 +240,7 @@ 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 @@ // 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 Index: clang-tidy/modernize/LoopConvertCheck.cpp =================================================================== --- clang-tidy/modernize/LoopConvertCheck.cpp +++ clang-tidy/modernize/LoopConvertCheck.cpp @@ -357,7 +357,7 @@ 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; }
Index: test/clang-tidy/modernize-loop-convert-extra.cpp =================================================================== --- test/clang-tidy/modernize-loop-convert-extra.cpp +++ test/clang-tidy/modernize-loop-convert-extra.cpp @@ -240,6 +240,7 @@ 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 @@ // 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 Index: clang-tidy/modernize/LoopConvertCheck.cpp =================================================================== --- clang-tidy/modernize/LoopConvertCheck.cpp +++ clang-tidy/modernize/LoopConvertCheck.cpp @@ -357,7 +357,7 @@ 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; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits