[clang] [clang][bytecode] Fix crash when dynamic_cast'ing a root pointer (PR #217540)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 19 23:56:55 PDT 2026
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/217540
We can't call getBase(), so move the isRoot() check before.
>From 8b4a48f4a6dca5c2291c9bb62cc006708671d58b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Thu, 20 Aug 2026 08:55:15 +0200
Subject: [PATCH] [clang][bytecode] Fix crash when dynamic_cast'ing a root
pointer
We can't call getBase(), so move the isRoot() check before.
---
clang/lib/AST/ByteCode/Interp.cpp | 7 ++++---
clang/test/AST/ByteCode/dynamic-cast.cpp | 15 +++++++++++++++
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 7704550a12d82..8f0a36877aa2b 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -2246,15 +2246,16 @@ bool DynamicCast(InterpState &S, CodePtr OpPC, const Type *DestTypePtr,
if (R.valid()) {
Result = Iter.atField(*R.Offset);
break;
- } else if (R.Ambiguous) {
+ }
+ if (R.Ambiguous) {
Ambiguous = true;
break;
}
- // This moves us DOWN the type hierarchy.
- Iter = Iter.getBase();
if (Iter.isRoot() || !Iter.isBaseClass())
break;
+ // This moves us DOWN the type hierarchy.
+ Iter = Iter.getBase();
}
if (Ambiguous)
diff --git a/clang/test/AST/ByteCode/dynamic-cast.cpp b/clang/test/AST/ByteCode/dynamic-cast.cpp
index 83a745e271a28..8a4678b092c2e 100644
--- a/clang/test/AST/ByteCode/dynamic-cast.cpp
+++ b/clang/test/AST/ByteCode/dynamic-cast.cpp
@@ -352,3 +352,18 @@ namespace VirtualBase {
}
static_assert(test());
}
+
+namespace RootPtr {
+ struct S {
+ constexpr virtual int foo() { return 0; }
+ };
+
+ struct T {};
+
+ struct U : virtual T {
+ constexpr S *bar() const { return (S *)this; } // both-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+ };
+ constexpr U u;
+ static_assert(dynamic_cast<T *>(u.bar())); // both-error {{not an integral constant expression}} \
+ // both-note {{in call to}}
+}
More information about the cfe-commits
mailing list