15
15
#include " clang/Basic/SourceLocation.h"
16
16
#include " clang/Basic/Specifiers.h"
17
17
#include " clang/Lex/Token.h"
18
+ #include " llvm/ADT/DenseSet.h"
18
19
#include " llvm/ADT/STLExtras.h"
20
+ #include " llvm/ADT/SmallVector.h"
19
21
20
22
using namespace clang ::ast_matchers;
21
23
@@ -78,6 +80,22 @@ AST_POLYMORPHIC_MATCHER(isExternStorageClass,
78
80
return Node.getStorageClass () == SC_Extern;
79
81
}
80
82
83
+ AST_MATCHER (FunctionDecl, isAllocationOrDeallocationOverloadedFunction) {
84
+ // [basic.stc.dynamic.allocation]
85
+ // An allocation function that is not a class member function shall belong to
86
+ // the global scope and not have a name with internal linkage.
87
+ // [basic.stc.dynamic.deallocation]
88
+ // A deallocation function that is not a class member function shall belong to
89
+ // the global scope and not have a name with internal linkage.
90
+ static const llvm::DenseSet<OverloadedOperatorKind> OverloadedOperators{
91
+ OverloadedOperatorKind::OO_New,
92
+ OverloadedOperatorKind::OO_Array_New,
93
+ OverloadedOperatorKind::OO_Delete,
94
+ OverloadedOperatorKind::OO_Array_Delete,
95
+ };
96
+ return OverloadedOperators.contains (Node.getOverloadedOperator ());
97
+ }
98
+
81
99
} // namespace
82
100
83
101
UseInternalLinkageCheck::UseInternalLinkageCheck (StringRef Name,
@@ -103,7 +121,10 @@ void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
103
121
// 4. friend
104
122
hasAncestor (friendDecl ()))));
105
123
Finder->addMatcher (
106
- functionDecl (Common, hasBody (), unless (cxxMethodDecl ()), unless (isMain ()))
124
+ functionDecl (Common, hasBody (),
125
+ unless (anyOf (cxxMethodDecl (),
126
+ isAllocationOrDeallocationOverloadedFunction (),
127
+ isMain ())))
107
128
.bind (" fn" ),
108
129
this );
109
130
Finder->addMatcher (varDecl (Common, hasGlobalStorage ()).bind (" var" ), this );
0 commit comments