@@ -70,6 +70,11 @@ AST_MATCHER(CXXRecordDecl, hasTrivialMoveConstructor) {
70
70
return Node.hasDefinition () && Node.hasTrivialMoveConstructor ();
71
71
}
72
72
73
+ AST_MATCHER_P (Expr, ignoreParens, ast_matchers::internal::Matcher<Expr>,
74
+ innerMatcher) {
75
+ return innerMatcher.matches (*Node.IgnoreParens (), Finder, Builder);
76
+ }
77
+
73
78
void LostStdMoveCheck::storeOptions (ClangTidyOptions::OptionMap &Opts) {
74
79
Options.store (Opts, " StrictMode" , StrictMode);
75
80
}
@@ -86,48 +91,40 @@ void LostStdMoveCheck::registerMatchers(MatchFinder *Finder) {
86
91
auto LeafStatement = stmt (OutermostExpr);
87
92
88
93
Finder->addMatcher (
89
- declRefExpr (
90
- // not "return x;"
91
- unless (ReturnParent),
92
- unless (hasType (namedDecl (hasName (" ::std::string_view" )))),
93
- // non-trivial type
94
- hasType (hasCanonicalType (hasDeclaration (cxxRecordDecl ()))),
95
- // non-trivial X(X&&)
96
- unless (hasType (hasCanonicalType (
97
- hasDeclaration (cxxRecordDecl (hasTrivialMoveConstructor ()))))),
98
- // Not in a cycle
99
- unless (hasAncestor (forStmt ())), unless (hasAncestor (doStmt ())),
100
- unless (hasAncestor (whileStmt ())),
101
- // Not in a body of lambda
102
- unless (hasAncestor (compoundStmt (hasAncestor (lambdaExpr ())))),
103
- // only non-X&
104
- unless (hasDeclaration (
105
- varDecl (hasType (qualType (lValueReferenceType ()))))),
106
- hasAncestor (LeafStatement.bind (" leaf_statement" )),
107
- hasDeclaration (
108
- varDecl (hasAncestor (functionDecl ().bind (" func" ))).bind (" decl" )),
109
- anyOf (
110
- // f(x)
111
- hasParent (expr (hasParent (cxxConstructExpr ())).bind (" use_parent" )),
112
- // f((x))
113
- hasParent (parenExpr (hasParent (
114
- expr (hasParent (cxxConstructExpr ())).bind (" use_parent" ))))))
115
- .bind (" use" ),
94
+ cxxConstructExpr (has (expr (has (ignoreParens (
95
+ declRefExpr (
96
+ // not "return x;"
97
+ unless (ReturnParent),
98
+ unless (hasType (namedDecl (hasName (" ::std::string_view" )))),
99
+ // non-trivial type
100
+ hasType (hasCanonicalType (hasDeclaration (cxxRecordDecl ()))),
101
+ // non-trivial X(X&&)
102
+ unless (hasType (hasCanonicalType (
103
+ hasDeclaration (cxxRecordDecl (hasTrivialMoveConstructor ()))))),
104
+ // Not in a cycle
105
+ unless (hasAncestor (forStmt ())), unless (hasAncestor (doStmt ())),
106
+ unless (hasAncestor (whileStmt ())),
107
+ // Not in a body of lambda
108
+ unless (hasAncestor (compoundStmt (hasAncestor (lambdaExpr ())))),
109
+ // only non-X&
110
+ unless (hasDeclaration (
111
+ varDecl (hasType (qualType (lValueReferenceType ()))))),
112
+ hasAncestor (LeafStatement.bind (" leaf_statement" )),
113
+ hasDeclaration (varDecl (hasAncestor (functionDecl ().bind (" func" )))
114
+ .bind (" decl" )))
115
+ .bind (" use" )))))),
116
116
this );
117
117
}
118
118
119
119
void LostStdMoveCheck::check (const MatchFinder::MatchResult &Result) {
120
120
const auto *MatchedDecl = Result.Nodes .getNodeAs <VarDecl>(" decl" );
121
121
const auto *MatchedFunc = Result.Nodes .getNodeAs <FunctionDecl>(" func" );
122
122
const auto *MatchedUse = Result.Nodes .getNodeAs <Expr>(" use" );
123
- const auto *MatchedUseCall = Result.Nodes .getNodeAs <CallExpr>(" use_parent" );
124
123
const auto *MatchedLeafStatement =
125
124
Result.Nodes .getNodeAs <Stmt>(" leaf_statement" );
126
125
127
- if (!MatchedDecl->hasLocalStorage ())
128
- return ;
129
-
130
- if (MatchedUseCall) {
126
+ if (!MatchedDecl->hasLocalStorage ()) {
127
+ // global or static variable
131
128
return ;
132
129
}
133
130
0 commit comments