1515#include " clang/Basic/SourceLocation.h"
1616#include " clang/Basic/Specifiers.h"
1717#include " clang/Lex/Token.h"
18+ #include " llvm/ADT/DenseSet.h"
1819#include " llvm/ADT/STLExtras.h"
20+ #include " llvm/ADT/SmallVector.h"
1921
2022using namespace clang ::ast_matchers;
2123
@@ -78,6 +80,22 @@ AST_POLYMORPHIC_MATCHER(isExternStorageClass,
7880 return Node.getStorageClass () == SC_Extern;
7981}
8082
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+
8199} // namespace
82100
83101UseInternalLinkageCheck::UseInternalLinkageCheck (StringRef Name,
@@ -103,7 +121,10 @@ void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
103121 // 4. friend
104122 hasAncestor (friendDecl ()))));
105123 Finder->addMatcher (
106- functionDecl (Common, hasBody (), unless (cxxMethodDecl ()), unless (isMain ()))
124+ functionDecl (Common, hasBody (),
125+ unless (anyOf (cxxMethodDecl (),
126+ isAllocationOrDeallocationOverloadedFunction (),
127+ isMain ())))
107128 .bind (" fn" ),
108129 this );
109130 Finder->addMatcher (varDecl (Common, hasGlobalStorage ()).bind (" var" ), this );
0 commit comments