https://github.com/mariusdr created https://github.com/llvm/llvm-project/pull/158502
Fixes #152893. An assert was raised when a constexpr virtual function was called from an constexpr array element with -fexperimental-new-constant-interpreter set. >From 26e222a60af111c638d87176c20e9cb6a11a4ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marius=20D=C3=B6rner?= <marius.doern...@icloud.com> Date: Sun, 14 Sep 2025 21:03:57 +0200 Subject: [PATCH] [Clang][Interp] Assert on virtual func call from array elem Fixes #152893. An assert was raised when a constexpr virtual function was called from an constexpr array element with -fexperimental-new-constant-interpreter set. --- clang/lib/AST/ByteCode/Interp.cpp | 9 +++++++-- clang/test/AST/ByteCode/cxx20.cpp | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index f1b9104c04feb..c739fa0c19d84 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1664,10 +1664,15 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func, TypePtr = TypePtr.getBase(); QualType DynamicType = TypePtr.getType(); - if (DynamicType->isPointerType() || DynamicType->isReferenceType()) + if (DynamicType->isPointerType() || DynamicType->isReferenceType()) { DynamicDecl = DynamicType->getPointeeCXXRecordDecl(); - else + } else if (DynamicType->isArrayType()) { + const Type *ElemType = DynamicType->getPointeeOrArrayElementType(); + assert(ElemType); + DynamicDecl = ElemType->getAsCXXRecordDecl(); + } else { DynamicDecl = DynamicType->getAsCXXRecordDecl(); + } } assert(DynamicDecl); diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp index 67bf9a732d8b7..8e77a081e3e60 100644 --- a/clang/test/AST/ByteCode/cxx20.cpp +++ b/clang/test/AST/ByteCode/cxx20.cpp @@ -1100,3 +1100,25 @@ namespace DiscardedTrivialCXXConstructExpr { constexpr int y = foo(12); // both-error {{must be initialized by a constant expression}} \ // both-note {{in call to}} } + +namespace VirtualFunctionCallThroughArrayElem { + struct X { + constexpr virtual int foo() const { + return 3; + } + }; + constexpr X xs[5]; + static_assert(xs[3].foo() == 3); + + constexpr X xs2[1][2]; + static_assert(xs2[0].foo() == 3); // both-error {{is not a structure or union}} + static_assert(xs2[0][0].foo() == 3); + + struct Y: public X { + constexpr int foo() const override { + return 1; + } + }; + constexpr Y ys[20]; + static_assert(ys[12].foo() == static_cast<const X&>(ys[12]).foo()); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits