summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngel Garcia Gomez <angelgarcia@google.com>2015-11-06 09:59:14 +0000
committerAngel Garcia Gomez <angelgarcia@google.com>2015-11-06 09:59:14 +0000
commit7856ad0bccd6d4956b2dd319ccdf8375d3b73964 (patch)
treee8b9eeb44e01a4f6a1a2a325c63a22ce589fd592
parentdccffd4fcc5e23d6f79a39bf3c04146b2684c485 (diff)
downloadbcm5719-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.cpp6
-rw-r--r--clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp25
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
OpenPOWER on IntegriCloud