summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngel Garcia Gomez <angelgarcia@google.com>2015-11-06 15:47:04 +0000
committerAngel Garcia Gomez <angelgarcia@google.com>2015-11-06 15:47:04 +0000
commit2c19d4cee302c1e61bd39870e45c74ac9d140d87 (patch)
tree75e63ba536c611eca9953b6c677ec8e224f88c3c
parentbde4c81ffe1f4d753ecfc81bae99afea07ec2185 (diff)
downloadbcm5719-llvm-2c19d4cee302c1e61bd39870e45c74ac9d140d87.tar.gz
bcm5719-llvm-2c19d4cee302c1e61bd39870e45c74ac9d140d87.zip
Allow the alias to be of a different type.
Summary: Consider a declaration an alias even if it doesn't have the same unqualified type than the container element, as long as one can be converted to the other using only implicit casts. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D14442 llvm-svn: 252315
-rw-r--r--clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp30
-rw-r--r--clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp21
2 files changed, 38 insertions, 13 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
index 97e2f7e2191..c50e9238170 100644
--- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
@@ -342,21 +342,27 @@ static bool isAliasDecl(ASTContext *Context, const Decl *TheDecl,
if (!VDecl->hasInit())
return false;
- const Expr *Init =
- digThroughConstructors(VDecl->getInit()->IgnoreParenImpCasts());
+ bool OnlyCasts = true;
+ const Expr *Init = VDecl->getInit()->IgnoreParenImpCasts();
+ if (Init && isa<CXXConstructExpr>(Init)) {
+ Init = digThroughConstructors(Init);
+ OnlyCasts = false;
+ }
if (!Init)
return false;
// Check that the declared type is the same as (or a reference to) the
// container type.
- QualType InitType = Init->getType();
- QualType DeclarationType = VDecl->getType();
- if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
- DeclarationType = DeclarationType.getNonReferenceType();
-
- if (InitType.isNull() || DeclarationType.isNull() ||
- !Context->hasSameUnqualifiedType(DeclarationType, InitType))
- return false;
+ if (!OnlyCasts) {
+ QualType InitType = Init->getType();
+ QualType DeclarationType = VDecl->getType();
+ if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
+ DeclarationType = DeclarationType.getNonReferenceType();
+
+ if (InitType.isNull() || DeclarationType.isNull() ||
+ !Context->hasSameUnqualifiedType(DeclarationType, InitType))
+ return false;
+ }
switch (Init->getStmtClass()) {
case Stmt::ArraySubscriptExprClass: {
@@ -384,8 +390,8 @@ static bool isAliasDecl(ASTContext *Context, const Decl *TheDecl,
const auto *MemCall = cast<CXXMemberCallExpr>(Init);
// This check is needed because getMethodDecl can return nullptr if the
// callee is a member function pointer.
- if (MemCall->getMethodDecl() &&
- MemCall->getMethodDecl()->getName() == "at") {
+ const auto *MDecl = MemCall->getMethodDecl();
+ if (MDecl && !isa<CXXConversionDecl>(MDecl) && MDecl->getName() == "at") {
assert(MemCall->getNumArgs() == 1);
return isIndexInSubscriptExpr(MemCall->getArg(0), IndexVar);
}
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 2d4d73e0ff8..42796f22710 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
@@ -159,7 +159,7 @@ void aliasing() {
// CHECK-FIXES: for (int Alias : IntArr)
// CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J)
- struct IntRef { IntRef(const int& i); };
+ struct IntRef { IntRef(); IntRef(const int& i); operator int*(); };
for (int I = 0; I < N; ++I) {
IntRef Int(IntArr[I]);
}
@@ -167,6 +167,25 @@ void aliasing() {
// CHECK-FIXES: for (int I : IntArr)
// CHECK-FIXES-NEXT: IntRef Int(I);
+ int *PtrArr[N];
+ for (unsigned I = 0; I < N; ++I) {
+ const int* const P = PtrArr[I];
+ printf("%d\n", *P);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto P : PtrArr)
+ // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
+ IntRef Refs[N];
+ for (unsigned I = 0; I < N; ++I) {
+ int *P = Refs[I];
+ printf("%d\n", *P);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & Ref : Refs)
+ // CHECK-FIXES-NEXT: int *P = Ref;
+ // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
// Ensure that removing the alias doesn't leave empty lines behind.
for (int I = 0; I < N; ++I) {
auto &X = IntArr[I];
OpenPOWER on IntegriCloud