[llvm] [RadixTree] Use std::optional for Node::Value (PR #165299)

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 27 12:22:48 PDT 2025


https://github.com/vitalybuka created https://github.com/llvm/llvm-project/pull/165299

Don't rely on comparison to singular iterator, it's UB.

Fixes bot crashes after https://github.com/llvm/llvm-project/pull/164524.


>From ab785bde52a670fdbc0805154a66025762ae43af Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Mon, 27 Oct 2025 12:22:30 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7
---
 llvm/include/llvm/ADT/RadixTree.h | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h
index 9e2ab9753d50c..87e2a3ebecc06 100644
--- a/llvm/include/llvm/ADT/RadixTree.h
+++ b/llvm/include/llvm/ADT/RadixTree.h
@@ -20,6 +20,7 @@
 #include <cstddef>
 #include <iterator>
 #include <list>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -92,7 +93,7 @@ template <typename KeyType, typename T> class RadixTree {
     /// If this node does not have a value (i.e., it's an internal node that
     /// only serves as a path to other values), this iterator will be equal
     /// to default constructed `ContainerType::iterator()`.
-    typename ContainerType::iterator Value;
+    std::optional<typename ContainerType::iterator> Value;
 
     /// The first character of the Key. Used for fast child lookup.
     KeyValueType KeyFront;
@@ -215,7 +216,7 @@ template <typename KeyType, typename T> class RadixTree {
                                     KeyConstIteratorType{}};
 
     void findNextValid() {
-      while (Curr && Curr->Value == typename ContainerType::iterator())
+      while (Curr && !Curr->Value.has_value())
         advance();
     }
 
@@ -249,7 +250,7 @@ template <typename KeyType, typename T> class RadixTree {
   public:
     IteratorImpl() = default;
 
-    MappedType &operator*() const { return *Curr->Value; }
+    MappedType &operator*() const { return **Curr->Value; }
 
     IteratorImpl &operator++() {
       advance();
@@ -315,12 +316,12 @@ template <typename KeyType, typename T> class RadixTree {
     const value_type &NewValue = KeyValuePairs.emplace_front(
         std::move(Key), T(std::forward<Ts>(Args)...));
     Node &Node = findOrCreate(NewValue.first);
-    bool HasValue = Node.Value != typename ContainerType::iterator();
+    bool HasValue = Node.Value.has_value();
     if (!HasValue)
       Node.Value = KeyValuePairs.begin();
     else
       KeyValuePairs.pop_front();
-    return {Node.Value, !HasValue};
+    return {*Node.Value, !HasValue};
   }
 
   ///



More information about the llvm-commits mailing list