From 7e74074e48cf861e7632b65dd27176089fc2338a Mon Sep 17 00:00:00 2001 From: term-est Date: Tue, 14 Oct 2025 15:52:49 +0300 Subject: [PATCH 1/3] [clang][Interp] Fix null Descriptor dereference in ArrayElemPtrPop ByteCode interpretor could deref a null descriptor when handling typeid (or function pointers) in ArrayElemPtrPop. We need to treat this case as having no descriptor --- clang/lib/AST/ByteCode/Interp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 57cc705282d1b..7b177f3a9fdb7 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -3126,7 +3126,8 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) { } if (Offset.isZero()) { - if (Ptr.getFieldDesc()->isArray() && Ptr.getIndex() == 0) { + if (const Descriptor *Desc = Ptr.getFieldDesc(); + Desc && Desc->isArray() && Ptr.getIndex() == 0) { S.Stk.push(Ptr.atIndex(0).narrow()); return true; } From 0076d686bb580e6bed1eb6d97880d5b557966b1b Mon Sep 17 00:00:00 2001 From: term-est Date: Wed, 15 Oct 2025 12:58:11 +0300 Subject: [PATCH 2/3] [clang][Interp] Add regression test for crash with typeid pointers --- clang/test/AST/ByteCode/typeid.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/clang/test/AST/ByteCode/typeid.cpp b/clang/test/AST/ByteCode/typeid.cpp index 00b01c8e40682..090309d16e737 100644 --- a/clang/test/AST/ByteCode/typeid.cpp +++ b/clang/test/AST/ByteCode/typeid.cpp @@ -59,3 +59,13 @@ namespace TypeidPtrInEvaluationResult { consteval const std::type_info *ftype_info() { return &typeid(c); } const std::type_info *T1 = ftype_info(); } + +// Regression test for crash in ArrayElemPtrPop with typeid pointers. GH-163127 +namespace TypeidPtrRegression { + void dontcrash() { + // this should just be an error and not an ICE + constexpr auto res = ((void**)&typeid(int))[0]; // both-error {{must be initialized by a constant expression}} \ + // both-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + } +} + From dae76b12c8a89e652835d8a0110d167650941350 Mon Sep 17 00:00:00 2001 From: term-est Date: Wed, 15 Oct 2025 15:10:02 +0300 Subject: [PATCH 3/3] [clang][Interp] ArrayElemPtr should also do null check on the descriptor --- clang/lib/AST/ByteCode/Interp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 7b177f3a9fdb7..812d25fc79490 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -3096,7 +3096,8 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) { } if (Offset.isZero()) { - if (Ptr.getFieldDesc()->isArray() && Ptr.getIndex() == 0) { + if (const Descriptor *Desc = Ptr.getFieldDesc(); + Desc && Desc->isArray() && Ptr.getIndex() == 0) { S.Stk.push(Ptr.atIndex(0).narrow()); return true; }