[clang] Add error check for HeuristicResolver (PR #155561)

Mythreya Kuricheti via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 26 23:35:05 PDT 2025


https://github.com/MythreyaK updated https://github.com/llvm/llvm-project/pull/155561

>From e2e72a40e9833a28d79221a3f1e9acd616c068ec Mon Sep 17 00:00:00 2001
From: Mythreya Kuricheti <git at mythreya.dev>
Date: Tue, 26 Aug 2025 23:19:26 -0700
Subject: [PATCH 1/2] Add error check for HeuristicResolver

---
 .../unittests/Sema/HeuristicResolverTest.cpp  | 75 ++++++++++++++++++-
 1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/clang/unittests/Sema/HeuristicResolverTest.cpp b/clang/unittests/Sema/HeuristicResolverTest.cpp
index 21aca7a3489b8..ab4a423085c5b 100644
--- a/clang/unittests/Sema/HeuristicResolverTest.cpp
+++ b/clang/unittests/Sema/HeuristicResolverTest.cpp
@@ -8,7 +8,12 @@
 #include "clang/Sema/HeuristicResolver.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticIDs.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
 #include "gmock/gmock-matchers.h"
 #include "gtest/gtest.h"
 
@@ -31,6 +36,69 @@ template <typename InputNode>
 using ResolveFnT = std::function<std::vector<const NamedDecl *>(
     const HeuristicResolver *, InputNode)>;
 
+struct DiagsConsumer : DiagnosticConsumer {
+  struct PrettyDiagnostic {
+    unsigned int ID;
+    DiagnosticsEngine::Level DiagLevel;
+    llvm::SmallString<64> Message;
+
+    template <typename Stream>
+    friend Stream &operator<<(Stream &OS, const PrettyDiagnostic &D) {
+      if (D.DiagLevel == DiagnosticsEngine::Level::Ignored)
+        OS << "Ignored: ";
+      if (D.DiagLevel == DiagnosticsEngine::Level::Note)
+        OS << "Note: ";
+      if (D.DiagLevel == DiagnosticsEngine::Level::Remark)
+        OS << "Remark: ";
+      if (D.DiagLevel == DiagnosticsEngine::Level::Warning)
+        OS << "Warning: ";
+      if (D.DiagLevel == DiagnosticsEngine::Level::Error)
+        OS << "Error: ";
+      if (D.DiagLevel == DiagnosticsEngine::Level::Fatal)
+        OS << "Fatal: ";
+      OS << "ID: " << D.ID << " Message: " << D.Message.str().str() << '\n';
+      return OS;
+    }
+  };
+
+  llvm::SmallSet<unsigned int, 16> IgnoredDiagnostics{};
+  llvm::SmallVector<PrettyDiagnostic, 16> GeneratedDiagnostics{};
+
+  void HandleDiagnostic(DiagnosticsEngine::Level Level,
+                        const Diagnostic &Info) override {
+    DiagnosticConsumer::HandleDiagnostic(Level, Info);
+    const auto ID = Info.getID();
+
+    if (Level >= DiagnosticsEngine::Level::Warning &&
+        !IgnoredDiagnostics.contains(ID)) {
+      llvm::SmallString<64> Message;
+
+      Info.FormatDiagnostic(Message);
+      GeneratedDiagnostics.emplace_back(PrettyDiagnostic{ID, Level, Message});
+    }
+  }
+};
+
+std::unique_ptr<ASTUnit>
+buildASTUnit(llvm::StringRef Code, std::vector<std::string> Args,
+             llvm::SmallSet<unsigned int, 16> IgnoredDiagnostics) {
+  auto VFS = llvm::vfs::getRealFileSystem();
+  DiagnosticOptions DiagOpts{};
+  DiagsConsumer DiagConsumer{};
+  DiagConsumer.IgnoredDiagnostics = IgnoredDiagnostics;
+
+  auto TU = tooling::buildASTFromCodeWithArgs(
+      Code, Args, "input.cc", "clang-tool",
+      std::make_shared<PCHContainerOperations>(),
+      tooling::getClangStripDependencyFileAdjuster(),
+      tooling::FileContentMappings(), &DiagConsumer, VFS);
+
+  auto Diags =
+      CompilerInstance::createDiagnostics(*VFS, DiagOpts, &DiagConsumer, false);
+  EXPECT_TRUE(DiagConsumer.GeneratedDiagnostics.size() == 0);
+  return TU;
+}
+
 // Test heuristic resolution on `Code` using the resolution procedure
 // `ResolveFn`, which takes a `HeuristicResolver` and an input AST node of type
 // `InputNode` and returns a `std::vector<const NamedDecl *>`.
@@ -41,8 +109,10 @@ template <typename InputNode, typename ParamT, typename InputMatcher,
           typename... OutputMatchers>
 void expectResolution(llvm::StringRef Code, ResolveFnT<ParamT> ResolveFn,
                       const InputMatcher &IM, const OutputMatchers &...OMS) {
-  auto TU = tooling::buildASTFromCodeWithArgs(Code, {"-std=c++23"});
-  auto &Ctx = TU->getASTContext();
+
+  auto AST = buildASTUnit(Code, {"-std=c++23"}, {});
+  auto &Ctx = AST->getASTContext();
+
   auto InputMatches = match(IM, Ctx);
   ASSERT_EQ(1u, InputMatches.size());
   const auto *Input = InputMatches[0].template getNodeAs<InputNode>("input");
@@ -105,6 +175,7 @@ TEST(HeuristicResolver, MemberExpr_Overloads) {
     struct S {
       void bar(int);
       void bar(float);
+      void bar(this S);
     };
 
     template <typename T, typename U>

>From 110b460d72902a5fe260aff3bceec86fb0aca67d Mon Sep 17 00:00:00 2001
From: Mythreya Kuricheti <git at mythreya.dev>
Date: Tue, 26 Aug 2025 23:34:57 -0700
Subject: [PATCH 2/2] Remove debug code

---
 clang/unittests/Sema/HeuristicResolverTest.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/unittests/Sema/HeuristicResolverTest.cpp b/clang/unittests/Sema/HeuristicResolverTest.cpp
index ab4a423085c5b..888c22083ca73 100644
--- a/clang/unittests/Sema/HeuristicResolverTest.cpp
+++ b/clang/unittests/Sema/HeuristicResolverTest.cpp
@@ -175,7 +175,6 @@ TEST(HeuristicResolver, MemberExpr_Overloads) {
     struct S {
       void bar(int);
       void bar(float);
-      void bar(this S);
     };
 
     template <typename T, typename U>



More information about the cfe-commits mailing list