summaryrefslogtreecommitdiff
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-29 18:10:07 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-09-29 18:10:41 +0000
commit4bbf1f460eb3fabdb7cf7cd731af0c227e6539c8 (patch)
tree8fb51c31848f1d9835688ea1730410efb2c3f7ee /clang/lib/AST/ExprConstant.cpp
parent8092e001bcd76c0b9fec2311f3a515aa60d2ed07 (diff)
Vendor import of llvm-project branch release/17.x llvmorg-17.0.1-25-g098e653a5bed.vendor/llvm-project/llvmorg-17.0.1-25-g098e653a5bed
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r--clang/lib/AST/ExprConstant.cpp17
1 files changed, 12 insertions, 5 deletions
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(),