Skip to content

Commit

Permalink
Use ExprMutationAnalyzer in performance-for-range-copy
Browse files Browse the repository at this point in the history
Summary:
This gives better coverage to the check as ExprMutationAnalyzer is more
accurate comparing to isOnlyUsedAsConst.

Majority of wins come from const usage of member field, e.g.:
for (auto widget : container) { // copy of loop variable
  if (widget.type == BUTTON) { // const usage only recognized by ExprMutationAnalyzer
    // ...
  }
}

Reviewers: george.karpenkov

Subscribers: a.sidorin, cfe-commits

Differential Revision: https://reviews.llvm.org/D48854

llvm-svn: 336737
  • Loading branch information
Shuai Wang committed Jul 10, 2018
1 parent 3482871 commit 0ed0feb
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
Expand Up @@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//

#include "ForRangeCopyCheck.h"
#include "../utils/DeclRefExprUtils.h"
#include "../utils/ExprMutationAnalyzer.h"
#include "../utils/FixItHintUtils.h"
#include "../utils/TypeTraits.h"

Expand Down Expand Up @@ -79,8 +79,8 @@ bool ForRangeCopyCheck::handleCopyIsOnlyConstReferenced(
utils::type_traits::isExpensiveToCopy(LoopVar.getType(), Context);
if (LoopVar.getType().isConstQualified() || !Expensive || !*Expensive)
return false;
if (!utils::decl_ref_expr::isOnlyUsedAsConst(LoopVar, *ForRange.getBody(),
Context))
if (utils::ExprMutationAnalyzer(ForRange.getBody(), &Context)
.isMutated(&LoopVar))
return false;
diag(LoopVar.getLocation(),
"loop variable is copied but only used as const reference; consider "
Expand Down
14 changes: 14 additions & 0 deletions clang-tools-extra/test/clang-tidy/performance-for-range-copy.cpp
Expand Up @@ -117,6 +117,11 @@ struct Mutable {
~Mutable() {}
};

struct Point {
~Point() {}
int x, y;
};

Mutable& operator<<(Mutable &Out, bool B) {
Out.setBool(B);
return Out;
Expand Down Expand Up @@ -214,6 +219,15 @@ void positiveOnlyUsedAsConstArguments() {
}
}

void positiveOnlyAccessedFieldAsConst() {
for (auto UsedAsConst : View<Iterator<Point>>()) {
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
// CHECK-FIXES: for (const auto& UsedAsConst : View<Iterator<Point>>()) {
use(UsedAsConst.x);
use(UsedAsConst.y);
}
}

void positiveOnlyUsedInCopyConstructor() {
for (auto A : View<Iterator<Mutable>>()) {
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]
Expand Down

0 comments on commit 0ed0feb

Please sign in to comment.