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
This commit is contained in:
Angel Garcia Gomez 2015-11-06 09:59:14 +00:00
parent dccffd4fcc
commit 7856ad0bcc
2 changed files with 28 additions and 3 deletions

View File

@ -352,12 +352,12 @@ static StringRef getStringFromRange(SourceManager &SourceMgr,
LangOpts); LangOpts);
} }
/// \brief If the given expression is actually a DeclRefExpr, find and return /// \brief If the given expression is actually a DeclRefExpr or a MemberExpr,
/// the underlying ValueDecl; otherwise, return NULL. /// find and return the underlying ValueDecl; otherwise, return NULL.
static const ValueDecl *getReferencedVariable(const Expr *E) { static const ValueDecl *getReferencedVariable(const Expr *E) {
if (const DeclRefExpr *DRE = getDeclRef(E)) if (const DeclRefExpr *DRE = getDeclRef(E))
return dyn_cast<VarDecl>(DRE->getDecl()); 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 dyn_cast<FieldDecl>(Mem->getMemberDecl());
return nullptr; return nullptr;
} }

View File

@ -240,6 +240,7 @@ void refs_and_vals() {
struct MemberNaming { struct MemberNaming {
const static int N = 10; const static int N = 10;
int Ints[N], Ints_[N]; int Ints[N], Ints_[N];
dependent<int> DInts;
void loops() { void loops() {
for (int I = 0; I < N; ++I) { for (int I = 0; I < N; ++I) {
printf("%d\n", Ints[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-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
// CHECK-FIXES: for (int Int : Ints_) // CHECK-FIXES: for (int Int : Ints_)
// CHECK-FIXES-NEXT: printf("%d\n", Int); // 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 } // namespace NamingAlias