https://github.com/kazutakahirata created 
https://github.com/llvm/llvm-project/pull/219112

This patch fixes an iterator invalidation bug in isLayoutCompatibleUnion.

Without this patch, if we delete a matching field, we end up
evaluating I == E even though the iterators are invalidated.  Deleting
a match after the loop fixes the problem.

This bug was discovered with tightened epoch checks in
SmallPtrSetIterator.

Assisted-by: Antigravity


>From 6d3c7a3e9b3dc8a49d35f280d754f22b85c43406 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <[email protected]>
Date: Wed, 26 Aug 2026 21:51:03 -0700
Subject: [PATCH] [clang][Sema] Fix iterator invalidation in
 isLayoutCompatibleUnion

This patch fixes an iterator invalidation bug in isLayoutCompatibleUnion.

Without this patch, if we delete a matching field, we end up
evaluating I == E even though the iterators are invalidated.  Deleting
a match after the loop fixes the problem.

This bug was discovered with tightened epoch checks in
SmallPtrSetIterator.

Assisted-by: Antigravity
---
 clang/lib/Sema/SemaChecking.cpp | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7f3ccea82e8af..5c831e6cdebce 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16592,19 +16592,13 @@ static bool isLayoutCompatibleUnion(const ASTContext 
&C, const RecordDecl *RD1,
                                                           RD2->fields());
 
   for (auto *Field1 : RD1->fields()) {
-    auto I = UnmatchedFields.begin();
-    auto E = UnmatchedFields.end();
-
-    for ( ; I != E; ++I) {
-      if (isLayoutCompatible(C, Field1, *I, /*IsUnionMember=*/true)) {
-        bool Result = UnmatchedFields.erase(*I);
-        (void) Result;
-        assert(Result);
-        break;
-      }
-    }
-    if (I == E)
+    auto It = llvm::find_if(UnmatchedFields, [&](const FieldDecl *Field2) {
+      return isLayoutCompatible(C, Field1, Field2, /*IsUnionMember=*/true);
+    });
+    if (It == UnmatchedFields.end())
       return false;
+    [[maybe_unused]] bool Result = UnmatchedFields.erase(*It);
+    assert(Result);
   }
 
   return UnmatchedFields.empty();

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to