Skip to content

Commit 8963056

Browse files
committed
StrictMode
1 parent 6f55a1c commit 8963056

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,21 @@ allDeclRefExprsHonourLambda(const VarDecl &VarDecl, const Decl &Decl,
3636
return DeclRefs;
3737
}
3838

39+
static llvm::SmallPtrSet<const VarDecl *, 16>
40+
allVarDeclsExprs(const VarDecl &VarDecl, const Decl &Decl,
41+
ASTContext &Context) {
42+
auto Matches = match(
43+
decl(forEachDescendant(
44+
declRefExpr(to(varDecl(equalsNode(&VarDecl))),
45+
hasParent(decl(varDecl(hasType(qualType(referenceType()))).bind("varDecl"))),
46+
unless(hasAncestor(lambdaExpr(hasAnyCapture(lambdaCapture(
47+
capturesVar(varDecl(equalsNode(&VarDecl))))))))))),
48+
Decl, Context);
49+
llvm::SmallPtrSet<const class VarDecl *, 16> VarDecls;
50+
extractNodesByIdTo(Matches, "varDecl", VarDecls);
51+
return VarDecls;
52+
}
53+
3954
static const Expr *
4055
getLastVarUsage(const llvm::SmallPtrSet<const DeclRefExpr *, 16> &Exprs) {
4156
const Expr *LastExpr = nullptr;
@@ -54,6 +69,15 @@ AST_MATCHER(CXXRecordDecl, hasTrivialMoveConstructor) {
5469
return Node.hasDefinition() && Node.hasTrivialMoveConstructor();
5570
}
5671

72+
void LostStdMoveCheck::storeOptions(
73+
ClangTidyOptions::OptionMap &Opts) {
74+
Options.store(Opts, "StrictMode", StrictMode);
75+
}
76+
77+
LostStdMoveCheck::LostStdMoveCheck(StringRef Name, ClangTidyContext *Context)
78+
: ClangTidyCheck(Name, Context),
79+
StrictMode(Options.get("StrictMode", true)) {}
80+
5781
void LostStdMoveCheck::registerMatchers(MatchFinder *Finder) {
5882
auto ReturnParent =
5983
hasParent(expr(hasParent(cxxConstructExpr(hasParent(returnStmt())))));
@@ -125,15 +149,17 @@ void LostStdMoveCheck::check(const MatchFinder::MatchResult &Result) {
125149
return;
126150
}
127151

128-
llvm::SmallPtrSet<const DeclRefExpr *, 16> AllReferences =
129-
allDeclRefExprsHonourLambda(*MatchedDecl, *MatchedFunc, *Result.Context);
130-
for (const auto *Reference : AllReferences) {
131-
if (Reference->getType()->isLValueReferenceType()) {
132-
// variable may be caught by reference and still used via reference during
133-
// MatchedUse
152+
if (StrictMode) {
153+
llvm::SmallPtrSet<const VarDecl *, 16> AllVarDecls =
154+
allVarDeclsExprs(*MatchedDecl, *MatchedFunc, *Result.Context);
155+
if (!AllVarDecls.empty()) {
156+
// x is referenced by local var, it may outlive the "use"
134157
return;
135158
}
136159
}
160+
161+
llvm::SmallPtrSet<const DeclRefExpr *, 16> AllReferences =
162+
allDeclRefExprsHonourLambda(*MatchedDecl, *MatchedFunc, *Result.Context);
137163
const Expr *LastUsage = getLastVarUsage(AllReferences);
138164

139165
if (LastUsage && LastUsage->getBeginLoc() > MatchedUse->getBeginLoc()) {

clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@ namespace clang::tidy::performance {
2121
/// http://clang.llvm.org/extra/clang-tidy/checks/performance/lost-std-move.html
2222
class LostStdMoveCheck : public ClangTidyCheck {
2323
public:
24-
LostStdMoveCheck(StringRef Name, ClangTidyContext *Context)
25-
: ClangTidyCheck(Name, Context) {}
24+
LostStdMoveCheck(StringRef Name, ClangTidyContext *Context);
2625
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
2726
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
27+
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
2828
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
2929
return LangOpts.CPlusPlus11;
3030
}
31+
32+
private:
33+
const bool StrictMode;
3134
};
3235

3336
} // namespace clang::tidy::performance

0 commit comments

Comments
 (0)