https://github.com/kadircet updated https://github.com/llvm/llvm-project/pull/125199
From 696ef01effccbf6f666b444a8eea1eabaaa1f706 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya <kadir...@google.com> Date: Fri, 31 Jan 2025 11:17:27 +0100 Subject: [PATCH] [include-cleaner] Dont report explicit refs for global operator new/delete These are available for all translations implicitly. We shouldn't report explicit refs and enforce includes. --- .../include-cleaner/lib/WalkAST.cpp | 16 +++++- .../unittests/AnalysisTest.cpp | 49 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index aae3eda519ffdc..7a140c991925c8 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -22,6 +22,7 @@ #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/STLExtras.h" @@ -32,6 +33,11 @@ namespace clang::include_cleaner { namespace { +bool isOperatorNewDelete(OverloadedOperatorKind OpKind) { + return OpKind == OO_New || OpKind == OO_Delete || OpKind == OO_Array_New || + OpKind == OO_Array_Delete; +} + using DeclCallback = llvm::function_ref<void(SourceLocation, NamedDecl &, RefType)>; @@ -158,7 +164,15 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> { // the container decl instead, which is preferred as it'll handle // aliases/exports properly. if (!FD->isCXXClassMember() && !llvm::isa<EnumConstantDecl>(FD)) { - report(DRE->getLocation(), FD); + // Global operator new/delete [] is available implicitly in every + // translation unit, even without including any explicit headers. So treat + // those as ambigious to not force inclusion in TUs that transitively + // depend on those. + RefType RT = + isOperatorNewDelete(FD->getDeclName().getCXXOverloadedOperator()) + ? RefType::Ambiguous + : RefType::Explicit; + report(DRE->getLocation(), FD, RT); return true; } // If the ref is without a qualifier, and is a member, ignore it. As it is diff --git a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp index d2d137a0dfb42a..74321c312cb718 100644 --- a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp @@ -397,6 +397,55 @@ TEST_F(AnalyzeTest, SpellingIncludesWithSymlinks) { } } +// Make sure that the references to implicit operator new/delete are reported as +// ambigious. +TEST_F(AnalyzeTest, ImplicitOperatorNewDeleteNotMissing) { + ExtraFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>(); + ExtraFS->addFile("header.h", + /*ModificationTime=*/{}, + llvm::MemoryBuffer::getMemBufferCopy(guard(R"cpp( + void* operator new(decltype(sizeof(int))); + )cpp"))); + ExtraFS->addFile("wrapper.h", + /*ModificationTime=*/{}, + llvm::MemoryBuffer::getMemBufferCopy(guard(R"cpp( + #include "header.h" + )cpp"))); + + Inputs.Code = R"cpp( + #include "wrapper.h" + void bar() { + operator new(3); + })cpp"; + TestAST AST(Inputs); + std::vector<Decl *> DeclsInTU; + for (auto *D : AST.context().getTranslationUnitDecl()->decls()) + DeclsInTU.push_back(D); + auto Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor()); + EXPECT_THAT(Results.Missing, testing::IsEmpty()); +} + +TEST_F(AnalyzeTest, ImplicitOperatorNewDeleteNotUnused) { + ExtraFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>(); + ExtraFS->addFile("header.h", + /*ModificationTime=*/{}, + llvm::MemoryBuffer::getMemBufferCopy(guard(R"cpp( + void* operator new(decltype(sizeof(int))); + )cpp"))); + + Inputs.Code = R"cpp( + #include "header.h" + void bar() { + operator new(3); + })cpp"; + TestAST AST(Inputs); + std::vector<Decl *> DeclsInTU; + for (auto *D : AST.context().getTranslationUnitDecl()->decls()) + DeclsInTU.push_back(D); + auto Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor()); + EXPECT_THAT(Results.Unused, testing::IsEmpty()); +} + TEST(FixIncludes, Basic) { llvm::StringRef Code = R"cpp(#include "d.h" #include "a.h" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits