File tree Expand file tree Collapse file tree 4 files changed +35
-21
lines changed Expand file tree Collapse file tree 4 files changed +35
-21
lines changed Original file line number Diff line number Diff line change 10
10
11
11
#include " clang/AST/Expr.h"
12
12
#include " clang/AST/ExprCXX.h"
13
- #include " clang/AST/ExprConcepts.h"
14
13
#include " clang/ASTMatchers/ASTMatchers.h"
15
14
#include " clang/Analysis/CFG.h"
16
15
#include " clang/Lex/Lexer.h"
17
16
#include " llvm/ADT/STLExtras.h"
18
17
19
18
#include " ../utils/ExprSequence.h"
19
+ #include " ../utils/Matchers.h"
20
20
#include < optional>
21
21
22
22
using namespace clang ::ast_matchers;
23
23
using namespace clang ::tidy::utils;
24
24
25
25
namespace clang ::tidy::bugprone {
26
26
27
- namespace {
27
+ using matchers::hasUnevaluatedContext;
28
28
29
- AST_MATCHER (Expr, hasUnevaluatedContext) {
30
- if (isa<CXXNoexceptExpr>(Node) || isa<RequiresExpr>(Node))
31
- return true ;
32
- if (const auto *UnaryExpr = dyn_cast<UnaryExprOrTypeTraitExpr>(&Node)) {
33
- switch (UnaryExpr->getKind ()) {
34
- case UETT_SizeOf:
35
- case UETT_AlignOf:
36
- return true ;
37
- default :
38
- return false ;
39
- }
40
- }
41
- if (const auto *TypeIDExpr = dyn_cast<CXXTypeidExpr>(&Node))
42
- return !TypeIDExpr->isPotentiallyEvaluated ();
43
- return false ;
44
- }
29
+ namespace {
45
30
46
31
// / Contains information about a use-after-move.
47
32
struct UseAfterMove {
@@ -86,7 +71,6 @@ class UseAfterMoveFinder {
86
71
87
72
} // namespace
88
73
89
-
90
74
// Matches nodes that are
91
75
// - Part of a decltype argument or class template argument (we check this by
92
76
// seeing if they are children of a TypeLoc), or
Original file line number Diff line number Diff line change 7
7
// ===----------------------------------------------------------------------===//
8
8
9
9
#include " RvalueReferenceParamNotMovedCheck.h"
10
+ #include " ../utils/Matchers.h"
10
11
#include " clang/AST/ASTContext.h"
11
12
#include " clang/ASTMatchers/ASTMatchFinder.h"
12
13
13
14
using namespace clang ::ast_matchers;
14
15
15
16
namespace clang ::tidy::cppcoreguidelines {
16
17
18
+ using matchers::hasUnevaluatedContext;
19
+
17
20
namespace {
18
21
AST_MATCHER_P (LambdaExpr, valueCapturesVar, DeclarationMatcher, VarMatcher) {
19
22
return std::find_if (Node.capture_begin (), Node.capture_end (),
@@ -39,16 +42,18 @@ void RvalueReferenceParamNotMovedCheck::registerMatchers(MatchFinder *Finder) {
39
42
40
43
StatementMatcher MoveCallMatcher =
41
44
callExpr (
45
+ argumentCountIs (1 ),
42
46
anyOf (callee (functionDecl (hasName (" ::std::move" ))),
43
47
callee (unresolvedLookupExpr (hasAnyDeclaration (
44
48
namedDecl (hasUnderlyingDecl (hasName (" ::std::move" ))))))),
45
- argumentCountIs (1 ),
46
49
hasArgument (
47
50
0 , argumentOf (
48
51
AllowPartialMove,
49
52
declRefExpr (to (equalsBoundNode (" param" ))).bind (" ref" ))),
50
53
unless (hasAncestor (
51
- lambdaExpr (valueCapturesVar (equalsBoundNode (" param" ))))))
54
+ lambdaExpr (valueCapturesVar (equalsBoundNode (" param" ))))),
55
+ unless (anyOf (hasAncestor (typeLoc ()),
56
+ hasAncestor (expr (hasUnevaluatedContext ())))))
52
57
.bind (" move-call" );
53
58
54
59
Finder->addMatcher (
Original file line number Diff line number Diff line change 10
10
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_MATCHERS_H
11
11
12
12
#include " TypeTraits.h"
13
+ #include " clang/AST/ExprConcepts.h"
13
14
#include " clang/ASTMatchers/ASTMatchers.h"
14
15
#include < optional>
15
16
@@ -48,6 +49,23 @@ AST_MATCHER_FUNCTION(ast_matchers::TypeMatcher, isPointerToConst) {
48
49
return pointerType (pointee (qualType (isConstQualified ())));
49
50
}
50
51
52
+ AST_MATCHER (Expr, hasUnevaluatedContext) {
53
+ if (isa<CXXNoexceptExpr>(Node) || isa<RequiresExpr>(Node))
54
+ return true ;
55
+ if (const auto *UnaryExpr = dyn_cast<UnaryExprOrTypeTraitExpr>(&Node)) {
56
+ switch (UnaryExpr->getKind ()) {
57
+ case UETT_SizeOf:
58
+ case UETT_AlignOf:
59
+ return true ;
60
+ default :
61
+ return false ;
62
+ }
63
+ }
64
+ if (const auto *TypeIDExpr = dyn_cast<CXXTypeidExpr>(&Node))
65
+ return !TypeIDExpr->isPotentiallyEvaluated ();
66
+ return false ;
67
+ }
68
+
51
69
// A matcher implementation that matches a list of type name regular expressions
52
70
// against a NamedDecl. If a regular expression contains the substring "::"
53
71
// matching will occur against the qualified name, otherwise only the typename.
Original file line number Diff line number Diff line change @@ -156,6 +156,13 @@ void moves_parameter_extra_parens(Obj&& o) {
156
156
Obj moved = std::move ((o));
157
157
}
158
158
159
+ void does_not_move_in_evaluated (Obj&& o) {
160
+ // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
161
+ using result_t = decltype (std::move (o));
162
+ unsigned size = sizeof (std::move (o));
163
+ Obj moved = o;
164
+ }
165
+
159
166
template <typename T1, typename T2>
160
167
struct mypair {
161
168
T1 first;
You can’t perform that action at this time.
0 commit comments