forked from OSchip/llvm-project
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:
parent
dccffd4fcc
commit
7856ad0bcc
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue