llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: marius doerner (mariusdr) <details> <summary>Changes</summary> Fixes #<!-- -->152893. An assert was raised when a constexpr virtual function was called from an constexpr array element with -fexperimental-new-constant-interpreter set. --- Full diff: https://github.com/llvm/llvm-project/pull/158502.diff 2 Files Affected: - (modified) clang/lib/AST/ByteCode/Interp.cpp (+7-2) - (modified) clang/test/AST/ByteCode/cxx20.cpp (+22) ``````````diff 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()); +} `````````` </details> https://github.com/llvm/llvm-project/pull/158502 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits