@@ -36,9 +36,9 @@ ast_matchers::internal::Matcher<Stmt> handleFromTemporaryValue(
36
36
// If a ternary operator returns a temporary value, then both branches hold a
37
37
// temporary value. If one of them is not a temporary then it must be copied
38
38
// into one to satisfy the type of the operator.
39
- const auto TemporaryTernary =
40
- conditionalOperator ( hasTrueExpression (cxxBindTemporaryExpr ()),
41
- hasFalseExpression (cxxBindTemporaryExpr ()));
39
+ const auto TemporaryTernary = conditionalOperator (
40
+ hasTrueExpression (ignoringParenImpCasts ( cxxBindTemporaryExpr () )),
41
+ hasFalseExpression (ignoringParenImpCasts ( cxxBindTemporaryExpr () )));
42
42
43
43
return handleFrom (IsAHandle, anyOf (cxxBindTemporaryExpr (), TemporaryTernary));
44
44
}
@@ -103,26 +103,17 @@ void DanglingHandleCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
103
103
void DanglingHandleCheck::registerMatchersForVariables (MatchFinder *Finder) {
104
104
const auto ConvertedHandle = handleFromTemporaryValue (IsAHandle);
105
105
106
- // Find 'Handle foo(ReturnsAValue());'
106
+ // Find 'Handle foo(ReturnsAValue());', 'Handle foo = ReturnsAValue();'
107
107
Finder->addMatcher (
108
108
varDecl (hasType (hasUnqualifiedDesugaredType (
109
109
recordType (hasDeclaration (cxxRecordDecl (IsAHandle))))),
110
+ unless (parmVarDecl ()),
110
111
hasInitializer (
111
- exprWithCleanups (has (ignoringParenImpCasts (ConvertedHandle)))
112
+ exprWithCleanups (ignoringElidableConstructorCall (has (
113
+ ignoringParenImpCasts (ConvertedHandle))))
112
114
.bind (" bad_stmt" ))),
113
115
this );
114
116
115
- // Find 'Handle foo = ReturnsAValue();'
116
- Finder->addMatcher (
117
- traverse (TK_AsIs,
118
- varDecl (hasType (hasUnqualifiedDesugaredType (recordType (
119
- hasDeclaration (cxxRecordDecl (IsAHandle))))),
120
- unless (parmVarDecl ()),
121
- hasInitializer (exprWithCleanups (
122
- has (ignoringParenImpCasts (handleFrom (
123
- IsAHandle, ConvertedHandle))))
124
- .bind (" bad_stmt" )))),
125
- this );
126
117
// Find 'foo = ReturnsAValue(); // foo is Handle'
127
118
Finder->addMatcher (
128
119
traverse (TK_AsIs,
@@ -141,36 +132,35 @@ void DanglingHandleCheck::registerMatchersForVariables(MatchFinder *Finder) {
141
132
void DanglingHandleCheck::registerMatchersForReturn (MatchFinder *Finder) {
142
133
// Return a local.
143
134
Finder->addMatcher (
144
- traverse (
145
- TK_AsIs,
146
- returnStmt (
147
- // The AST contains two constructor calls:
148
- // 1. Value to Handle conversion.
149
- // 2. Handle copy construction.
150
- // We have to match both.
151
- has (ignoringImplicit (handleFrom (
152
- IsAHandle,
153
- handleFrom (IsAHandle,
154
- declRefExpr (to (varDecl (
155
- // Is function scope ...
156
- hasAutomaticStorageDuration (),
157
- // ... and it is a local array or Value.
158
- anyOf (hasType (arrayType ()),
159
- hasType (hasUnqualifiedDesugaredType (
160
- recordType (hasDeclaration (recordDecl (
161
- unless (IsAHandle)))))))))))))),
162
- // Temporary fix for false positives inside lambdas.
163
- unless (hasAncestor (lambdaExpr ())))
164
- .bind (" bad_stmt" )),
135
+ traverse (TK_AsIs,
136
+ returnStmt (
137
+ // The AST contains two constructor calls:
138
+ // 1. Value to Handle conversion.
139
+ // 2. Handle copy construction (elided in C++17+).
140
+ // We have to match both.
141
+ has (ignoringImplicit (ignoringElidableConstructorCall (
142
+ ignoringImplicit (handleFrom (
143
+ IsAHandle,
144
+ declRefExpr (to (varDecl (
145
+ // Is function scope ...
146
+ hasAutomaticStorageDuration (),
147
+ // ... and it is a local array or Value.
148
+ anyOf (hasType (arrayType ()),
149
+ hasType (hasUnqualifiedDesugaredType (
150
+ recordType (hasDeclaration (recordDecl (
151
+ unless (IsAHandle))))))))))))))),
152
+ // Temporary fix for false positives inside lambdas.
153
+ unless (hasAncestor (lambdaExpr ())))
154
+ .bind (" bad_stmt" )),
165
155
this );
166
156
167
157
// Return a temporary.
168
158
Finder->addMatcher (
169
- traverse (
170
- TK_AsIs,
171
- returnStmt ( has (exprWithCleanups ( has ( ignoringParenImpCasts ( handleFrom (
172
- IsAHandle, handleFromTemporaryValue (IsAHandle)))))))
173
- .bind (" bad_stmt" )),
159
+ traverse (TK_AsIs,
160
+ returnStmt ( has ( exprWithCleanups ( ignoringElidableConstructorCall (
161
+ has (ignoringParenImpCasts (
162
+ handleFromTemporaryValue (IsAHandle)))))))
163
+ .bind (" bad_stmt" )),
174
164
this );
175
165
}
176
166
0 commit comments