[llvm] [Verifier] Don't look up the funclet color of an unreachable block (PR #222500)

Timur Baidusenov via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 9 20:46:03 PDT 2026


https://github.com/bai-tim created https://github.com/llvm/llvm-project/pull/222500

Fixes #192015.

>From 2910022c4bb6c0edc8f7d1ae067b8d56149737ff Mon Sep 17 00:00:00 2001
From: Timur Baidusenov <timurbaidusenov at gmail.com>
Date: Tue, 8 Sep 2026 21:58:22 +0300
Subject: [PATCH] [Verifier] Don't look up the funclet color of an unreachable
 block

Fixes #192015.
---
 llvm/lib/IR/Verifier.cpp                      | 44 +++++++++++--------
 .../Verifier/funclet-unreachable-block.ll     | 17 +++++++
 2 files changed, 42 insertions(+), 19 deletions(-)
 create mode 100644 llvm/test/Verifier/funclet-unreachable-block.ll

diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 20df60ed61da3..b26e3b9f84263 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -7260,26 +7260,32 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
       if (BlockEHFuncletColors.empty())
         BlockEHFuncletColors = colorEHFunclets(*F);
 
-      // Check for catch-/cleanup-pad in first funclet block
-      bool InEHFunclet = false;
+      // colorEHFunclets() leaves unreachable blocks colorless. Such a call
+      // is in no funclet and WinEHPrepare will not see it, so there is
+      // nothing to check.
       BasicBlock *CallBB = Call.getParent();
-      const ColorVector &CV = BlockEHFuncletColors.find(CallBB)->second;
-      assert(CV.size() > 0 && "Uncolored block");
-      for (BasicBlock *ColorFirstBB : CV)
-        if (auto It = ColorFirstBB->getFirstNonPHIIt();
-            It != ColorFirstBB->end())
-          if (isa_and_nonnull<FuncletPadInst>(&*It))
-            InEHFunclet = true;
-
-      // Check for funclet operand bundle
-      bool HasToken = false;
-      for (unsigned I = 0, E = Call.getNumOperandBundles(); I != E; ++I)
-        if (Call.getOperandBundleAt(I).getTagID() == LLVMContext::OB_funclet)
-          HasToken = true;
-
-      // This would cause silent code truncation in WinEHPrepare
-      if (InEHFunclet)
-        Check(HasToken, "Missing funclet token on intrinsic call", &Call);
+      auto ColorsIt = BlockEHFuncletColors.find(CallBB);
+      if (ColorsIt != BlockEHFuncletColors.end()) {
+        // Check for catch-/cleanup-pad in first funclet block
+        bool InEHFunclet = false;
+        const ColorVector &CV = ColorsIt->second;
+        assert(CV.size() > 0 && "Uncolored block");
+        for (BasicBlock *ColorFirstBB : CV)
+          if (auto It = ColorFirstBB->getFirstNonPHIIt();
+              It != ColorFirstBB->end())
+            if (isa_and_nonnull<FuncletPadInst>(&*It))
+              InEHFunclet = true;
+
+        // Check for funclet operand bundle
+        bool HasToken = false;
+        for (unsigned I = 0, E = Call.getNumOperandBundles(); I != E; ++I)
+          if (Call.getOperandBundleAt(I).getTagID() == LLVMContext::OB_funclet)
+            HasToken = true;
+
+        // This would cause silent code truncation in WinEHPrepare
+        if (InEHFunclet)
+          Check(HasToken, "Missing funclet token on intrinsic call", &Call);
+      }
     }
   }
 
diff --git a/llvm/test/Verifier/funclet-unreachable-block.ll b/llvm/test/Verifier/funclet-unreachable-block.ll
new file mode 100644
index 0000000000000..4ecc8902a9a30
--- /dev/null
+++ b/llvm/test/Verifier/funclet-unreachable-block.ll
@@ -0,0 +1,17 @@
+; RUN: llvm-as -disable-output %s
+
+; colorEHFunclets() leaves unreachable blocks colorless, so there is no funclet
+; color to look up for a call in one. The verifier must not crash on that.
+
+declare i32 @__CxxFrameHandler3(...)
+declare ptr @llvm.objc.retain(ptr returned) nounwind
+
+define void @f(ptr %p) personality ptr @__CxxFrameHandler3 {
+entry:
+  ret void
+
+unreachable.funclet:                              ; No predecessors!
+  %pad = cleanuppad within none []
+  %call = call ptr @llvm.objc.retain(ptr %p) [ "funclet"(token %pad) ]
+  cleanupret from %pad unwind to caller
+}



More information about the llvm-commits mailing list