Index: clang-tidy/modernize/LoopConvertCheck.cpp =================================================================== --- clang-tidy/modernize/LoopConvertCheck.cpp +++ clang-tidy/modernize/LoopConvertCheck.cpp @@ -472,11 +472,21 @@ // variable. for (const auto &Usage : Usages) { std::string ReplaceText; + SourceRange Range = Usage.Range; if (Usage.Expression) { // If this is an access to a member through the arrow operator, after // the replacement it must be accessed through the '.' operator. ReplaceText = Usage.Kind == Usage::UK_MemberThroughArrow ? VarName + "." : VarName; + auto Parents = Context->getParents(*Usage.Expression); + if (Parents.size() == 1) { + if (const auto *Paren = Parents[0].get()) { + // Usage.Expression will be replaced with the new index variable, + // and parenthesis around a simple DeclRefExpr can always be + // removed. + Range = Paren->getSourceRange(); + } + } } else { // The Usage expression is only null in case of lambda captures (which // are VarDecl). If the index is captured by value, add '&' to capture @@ -486,7 +496,7 @@ } TUInfo->getReplacedVars().insert(std::make_pair(Loop, IndexVar)); Diag << FixItHint::CreateReplacement( - CharSourceRange::getTokenRange(Usage.Range), ReplaceText); + CharSourceRange::getTokenRange(Range), ReplaceText); } } Index: test/clang-tidy/modernize-loop-convert-basic.cpp =================================================================== --- test/clang-tidy/modernize-loop-convert-basic.cpp +++ test/clang-tidy/modernize-loop-convert-basic.cpp @@ -199,7 +199,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : s) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x); S *ps; for (S::iterator it = ps->begin(), e = ps->end(); it != e; ++it) { @@ -207,7 +207,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & p : *ps) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (p).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", p.x); for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { printf("s has value %d\n", it->x); @@ -228,7 +228,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : s) - // CHECK-FIXES-NEXT: (elem).x = 3; + // CHECK-FIXES-NEXT: elem.x = 3; for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { it->nonConstFun(4, 5); @@ -250,7 +250,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : u) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x); U::iterator A; for (U::iterator i = u.begin(), e = u.end(); i != e; ++i) @@ -321,6 +321,21 @@ (void) *I; } } + + dependent dpp; + for (dependent::iterator I = dpp.begin(), E = dpp.end(); I != E; ++I) { + printf("%d\n", (**I).x); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & elem : dpp) + // CHECK-FIXES-NEXT: printf("%d\n", (*elem).x); + + for (dependent::iterator I = dpp.begin(), E = dpp.end(); I != E; ++I) { + printf("%d\n", (*I)->x); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & elem : dpp) + // CHECK-FIXES-NEXT: printf("%d\n", elem->x); } // Tests to verify the proper use of auto where the init variable type and the @@ -334,7 +349,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto elem : s) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x); S *ps; for (S::const_iterator it = ps->begin(), e = ps->end(); it != e; ++it) { @@ -342,7 +357,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto p : *ps) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (p).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", p.x); // v.begin() returns a user-defined type 'iterator' which, since it's // different from const_iterator, disqualifies these loops from 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 @@ -267,7 +267,7 @@ } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & MAXs_it : MAXs) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (MAXs_it).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", MAXs_it.x); // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5)); for (S::const_iterator it = MAXs.begin(), e = MAXs.end(); it != e; ++it) { @@ -276,7 +276,7 @@ } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto MAXs_it : MAXs) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (MAXs_it).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", MAXs_it.x); // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5)); T DEFs; @@ -307,7 +307,7 @@ } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & __FUNCTION__s_elem : __FUNCTION__s) - // CHECK-FIXES-NEXT: int __FUNCTION__s_it = (__FUNCTION__s_elem).x + 2; + // CHECK-FIXES-NEXT: int __FUNCTION__s_it = __FUNCTION__s_elem.x + 2; } void typeConflict() { @@ -457,7 +457,7 @@ } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : NestT) - // CHECK-FIXES-NEXT: for (T::iterator TI = (elem).begin(), TE = (elem).end(); TI != TE; ++TI) + // CHECK-FIXES-NEXT: for (T::iterator TI = elem.begin(), TE = elem.end(); TI != TE; ++TI) // CHECK-FIXES-NEXT: printf("%d", *TI); // The inner loop is also convertible. @@ -469,7 +469,7 @@ } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto elem : NestS) - // CHECK-FIXES-NEXT: for (S::const_iterator SI = (elem).begin(), SE = (elem).end(); SI != SE; ++SI) + // CHECK-FIXES-NEXT: for (S::const_iterator SI = elem.begin(), SE = elem.end(); SI != SE; ++SI) // CHECK-FIXES-NEXT: printf("%d", *SI); for (Nested::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) { @@ -557,7 +557,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : s) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x); S *ps; for (S::iterator it = ps->begin(); it != ps->end(); ++it) { @@ -565,7 +565,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & p : *ps) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (p).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", p.x); for (S::iterator it = s.begin(); it != s.end(); ++it) { printf("s has value %d\n", it->x); @@ -586,7 +586,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : s) - // CHECK-FIXES-NEXT: (elem).x = 3; + // CHECK-FIXES-NEXT: elem.x = 3; for (S::iterator it = s.begin(); it != s.end(); ++it) { it->nonConstFun(4, 5); @@ -608,7 +608,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : u) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x); U::iterator A; for (U::iterator i = u.begin(); i != u.end(); ++i) @@ -656,7 +656,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto elem : s) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x); S *ps; for (S::const_iterator it = ps->begin(); it != ps->end(); ++it) { @@ -664,7 +664,7 @@ } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto p : *ps) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (p).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", p.x); // v.begin() returns a user-defined type 'iterator' which, since it's // different from const_iterator, disqualifies these loops from