aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/ExprConstant.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/ExprConstant.cpp17
1 files changed, 12 insertions, 5 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp b/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
index f1bad0c7f7f2..c62044f36194 100644
--- a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
+++ b/contrib/llvm-project/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(),