From 4bbf1f460eb3fabdb7cf7cd731af0c227e6539c8 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 29 Sep 2023 20:10:07 +0200 Subject: Vendor import of llvm-project branch release/17.x llvmorg-17.0.1-25-g098e653a5bed. --- clang/lib/AST/ExprConstant.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'clang/lib/AST/ExprConstant.cpp') diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f1bad0c7f7f2..c62044f36194 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6013,8 +6013,9 @@ const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind; /// operator whose left-hand side might involve a union member access. If it /// does, implicitly start the lifetime of any accessed union elements per /// C++20 [class.union]5. -static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, - const LValue &LHS) { +static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, + const Expr *LHSExpr, + const LValue &LHS) { if (LHS.InvalidBase || LHS.Designator.Invalid) return false; @@ -6069,8 +6070,14 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, break; // Walk path backwards as we walk up from the base to the derived class. for (const CXXBaseSpecifier *Elt : llvm::reverse(ICE->path())) { + if (Elt->isVirtual()) { + // A class with virtual base classes never has a trivial default + // constructor, so S(E) is empty in this case. + E = nullptr; + break; + } + --PathLength; - (void)Elt; assert(declaresSameEntity(Elt->getType()->getAsCXXRecordDecl(), LHS.Designator.Entries[PathLength] .getAsBaseOrMember().getPointer())); @@ -7748,7 +7755,7 @@ public: // per C++20 [class.union]5. if (Info.getLangOpts().CPlusPlus20 && OCE && OCE->getOperator() == OO_Equal && MD->isTrivial() && - !HandleUnionActiveMemberChange(Info, Args[0], ThisVal)) + !MaybeHandleUnionActiveMemberChange(Info, Args[0], ThisVal)) return false; Args = Args.slice(1); @@ -8621,7 +8628,7 @@ bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) { return false; if (Info.getLangOpts().CPlusPlus20 && - !HandleUnionActiveMemberChange(Info, E->getLHS(), Result)) + !MaybeHandleUnionActiveMemberChange(Info, E->getLHS(), Result)) return false; return handleAssignment(this->Info, E, Result, E->getLHS()->getType(), -- cgit v1.3