Skip to content

Commit fcb1234

Browse files
authored
[include-cleaner] Dont report explicit refs for global operator new/delete (#125199)
These are available for all translations implicitly. We shouldn't report explicit refs and enforce includes.
1 parent eb1a571 commit fcb1234

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

clang-tools-extra/include-cleaner/lib/WalkAST.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "clang/AST/Type.h"
2323
#include "clang/AST/TypeLoc.h"
2424
#include "clang/Basic/IdentifierTable.h"
25+
#include "clang/Basic/OperatorKinds.h"
2526
#include "clang/Basic/SourceLocation.h"
2627
#include "clang/Basic/Specifiers.h"
2728
#include "llvm/ADT/STLExtras.h"
@@ -32,6 +33,11 @@
3233

3334
namespace clang::include_cleaner {
3435
namespace {
36+
bool isOperatorNewDelete(OverloadedOperatorKind OpKind) {
37+
return OpKind == OO_New || OpKind == OO_Delete || OpKind == OO_Array_New ||
38+
OpKind == OO_Array_Delete;
39+
}
40+
3541
using DeclCallback =
3642
llvm::function_ref<void(SourceLocation, NamedDecl &, RefType)>;
3743

@@ -158,7 +164,15 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
158164
// the container decl instead, which is preferred as it'll handle
159165
// aliases/exports properly.
160166
if (!FD->isCXXClassMember() && !llvm::isa<EnumConstantDecl>(FD)) {
161-
report(DRE->getLocation(), FD);
167+
// Global operator new/delete [] is available implicitly in every
168+
// translation unit, even without including any explicit headers. So treat
169+
// those as ambigious to not force inclusion in TUs that transitively
170+
// depend on those.
171+
RefType RT =
172+
isOperatorNewDelete(FD->getDeclName().getCXXOverloadedOperator())
173+
? RefType::Ambiguous
174+
: RefType::Explicit;
175+
report(DRE->getLocation(), FD, RT);
162176
return true;
163177
}
164178
// If the ref is without a qualifier, and is a member, ignore it. As it is

clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,55 @@ TEST_F(AnalyzeTest, SpellingIncludesWithSymlinks) {
397397
}
398398
}
399399

400+
// Make sure that the references to implicit operator new/delete are reported as
401+
// ambigious.
402+
TEST_F(AnalyzeTest, ImplicitOperatorNewDeleteNotMissing) {
403+
ExtraFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
404+
ExtraFS->addFile("header.h",
405+
/*ModificationTime=*/{},
406+
llvm::MemoryBuffer::getMemBufferCopy(guard(R"cpp(
407+
void* operator new(decltype(sizeof(int)));
408+
)cpp")));
409+
ExtraFS->addFile("wrapper.h",
410+
/*ModificationTime=*/{},
411+
llvm::MemoryBuffer::getMemBufferCopy(guard(R"cpp(
412+
#include "header.h"
413+
)cpp")));
414+
415+
Inputs.Code = R"cpp(
416+
#include "wrapper.h"
417+
void bar() {
418+
operator new(3);
419+
})cpp";
420+
TestAST AST(Inputs);
421+
std::vector<Decl *> DeclsInTU;
422+
for (auto *D : AST.context().getTranslationUnitDecl()->decls())
423+
DeclsInTU.push_back(D);
424+
auto Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor());
425+
EXPECT_THAT(Results.Missing, testing::IsEmpty());
426+
}
427+
428+
TEST_F(AnalyzeTest, ImplicitOperatorNewDeleteNotUnused) {
429+
ExtraFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
430+
ExtraFS->addFile("header.h",
431+
/*ModificationTime=*/{},
432+
llvm::MemoryBuffer::getMemBufferCopy(guard(R"cpp(
433+
void* operator new(decltype(sizeof(int)));
434+
)cpp")));
435+
436+
Inputs.Code = R"cpp(
437+
#include "header.h"
438+
void bar() {
439+
operator new(3);
440+
})cpp";
441+
TestAST AST(Inputs);
442+
std::vector<Decl *> DeclsInTU;
443+
for (auto *D : AST.context().getTranslationUnitDecl()->decls())
444+
DeclsInTU.push_back(D);
445+
auto Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor());
446+
EXPECT_THAT(Results.Unused, testing::IsEmpty());
447+
}
448+
400449
TEST(FixIncludes, Basic) {
401450
llvm::StringRef Code = R"cpp(#include "d.h"
402451
#include "a.h"

0 commit comments

Comments
 (0)