Skip to content

Commit f89fa23

Browse files
authored
[clang-tidy][use-internal-linkage]fix false positives for global overloaded operator new and operator delete (#117945)
1 parent 1c702d3 commit f89fa23

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
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

2022
using 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

83101
UseInternalLinkageCheck::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);

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ Changes in existing checks
247247
- Improved :doc:`misc-use-internal-linkage
248248
<clang-tidy/checks/misc/use-internal-linkage>` check to insert ``static``
249249
keyword before type qualifiers such as ``const`` and ``volatile`` and fix
250-
false positives for function declaration without body.
250+
false positives for function declaration without body and fix false positives
251+
for global scoped overloaded ``operator new`` and ``operator delete``.
251252

252253
- Improved :doc:`modernize-avoid-c-arrays
253254
<clang-tidy/checks/modernize/avoid-c-arrays>` check to suggest using

clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,13 @@ void func_with_body() {}
8585
void func_without_body();
8686
void func_without_body();
8787
}
88+
89+
// gh117489 start
90+
namespace std {
91+
using size_t = decltype(sizeof(int));
92+
}
93+
void * operator new(std::size_t) { return nullptr; }
94+
void * operator new[](std::size_t) { return nullptr; }
95+
void operator delete(void*) noexcept {}
96+
void operator delete[](void*) noexcept {}
97+
// gh117489 end

0 commit comments

Comments
 (0)