summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2019-10-27 12:26:36 -0700
committerRichard Smith <richard@metafoo.co.uk>2019-10-27 12:31:16 -0700
commitfaee39baa87e43f4b746dd77e479268391163658 (patch)
tree1cdcc51059e75f0e035cff4def1533846ae777a0 /clang/lib/AST/ExprConstant.cpp
parent85a2146c155953d5bdfb2e7e6ba9780fc2dab1b9 (diff)
downloadbcm5719-llvm-faee39baa87e43f4b746dd77e479268391163658.tar.gz
bcm5719-llvm-faee39baa87e43f4b746dd77e479268391163658.zip
PR43762: when implicitly changing the active union member for an
assignment during constant evaluation, only start the lifetime of trivially-default-constructible union members.
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r--clang/lib/AST/ExprConstant.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 42c746e6028..7ed08218567 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -5333,9 +5333,16 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr,
if (!FD || FD->getType()->isReferenceType())
break;
- // ... and also contains A.B if B names a union member
- if (FD->getParent()->isUnion())
- UnionPathLengths.push_back({PathLength - 1, FD});
+ // ... and also contains A.B if B names a union member ...
+ if (FD->getParent()->isUnion()) {
+ // ... of a non-class, non-array type, or of a class type with a
+ // trivial default constructor that is not deleted, or an array of
+ // such types.
+ auto *RD =
+ FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
+ if (!RD || RD->hasTrivialDefaultConstructor())
+ UnionPathLengths.push_back({PathLength - 1, FD});
+ }
E = ME->getBase();
--PathLength;
OpenPOWER on IntegriCloud