[clang] e60b4b6 - [clang][bytecode] Fix an assertion failure in dynamic_cast handling (#206447)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 29 04:51:41 PDT 2026
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 {};
More information about the cfe-commits
mailing list