Author: Timm Baeder Date: 2026-06-29T13:51:37+02:00 New Revision: e60b4b69dc72b1f7d9faa2e811ae161e9aef78e4
URL: https://github.com/llvm/llvm-project/commit/e60b4b69dc72b1f7d9faa2e811ae161e9aef78e4 DIFF: https://github.com/llvm/llvm-project/commit/e60b4b69dc72b1f7d9faa2e811ae161e9aef78e4.diff LOG: [clang][bytecode] Fix an assertion failure in dynamic_cast handling (#206447) If `Ptr` is already a root pointer, the `getBase()` call ran into an assertion. Fix this by moving the check to the start of the loop. Added: Modified: clang/lib/AST/ByteCode/Interp.cpp clang/test/AST/ByteCode/dynamic-cast.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 0396482517046..42736d108aec1 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -2139,14 +2139,15 @@ bool DynamicCast(InterpState &S, CodePtr OpPC, const Type *DestTypePtr, std::optional<PtrView> Result; // First, check simple downcasts without ambiguities. for (PtrView Iter = Ptr.view();;) { + if (Iter.isRoot() || !Iter.isBaseClass()) + break; + if (typesMatch(TargetType, Iter.getType())) { Result = Iter; break; } // Moving DOWN the type hierarchy. Iter = Iter.getBase(); - if (Iter.isRoot() || !Iter.isBaseClass()) - break; } // Simply walking down the type hierarchy has produced a valid result, use diff --git a/clang/test/AST/ByteCode/dynamic-cast.cpp b/clang/test/AST/ByteCode/dynamic-cast.cpp index a40b455cecabf..bfde7a2a4c0c2 100644 --- a/clang/test/AST/ByteCode/dynamic-cast.cpp +++ b/clang/test/AST/ByteCode/dynamic-cast.cpp @@ -295,6 +295,20 @@ namespace UnrelatedAndRootPtr{ static_assert(f()); } +namespace UnrelatedAndRootReference { + struct A { + virtual void foo(); + }; + struct B1 : A {}; + + struct B2 : A {}; + struct C : B2 {}; + + constexpr C c; + static_assert(&dynamic_cast<B2 &>((B1 &)c), ""); // both-error {{not an integral constant expression}} \ + // both-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} +} + namespace Invalid { struct S { virtual void s(); }; struct A : S {}; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
