diff options
author | Richard Smith <richard@metafoo.co.uk> | 2019-10-27 12:26:36 -0700 |
---|---|---|
committer | Richard Smith <richard@metafoo.co.uk> | 2019-10-27 12:31:16 -0700 |
commit | faee39baa87e43f4b746dd77e479268391163658 (patch) | |
tree | 1cdcc51059e75f0e035cff4def1533846ae777a0 /clang/lib/AST/ExprConstant.cpp | |
parent | 85a2146c155953d5bdfb2e7e6ba9780fc2dab1b9 (diff) | |
download | bcm5719-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.cpp | 13 |
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; |