Fix hang during constant evaluation of union assignment.
HandleUnionActiveMemberChange forgot to walk over a nop implicit conversion node and got stuck in the process. As a cleanup I changed the declaration of `E` so it can't be accidentally accessed after the loop. llvm-svn: 361571
This commit is contained in:
parent
093c922205
commit
ffafdb9afc
|
@ -4994,9 +4994,8 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr,
|
|||
llvm::SmallVector<std::pair<unsigned, const FieldDecl*>, 4> UnionPathLengths;
|
||||
// C++ [class.union]p5:
|
||||
// define the set S(E) of subexpressions of E as follows:
|
||||
const Expr *E = LHSExpr;
|
||||
unsigned PathLength = LHS.Designator.Entries.size();
|
||||
while (E) {
|
||||
for (const Expr *E = LHSExpr; E != nullptr;) {
|
||||
// -- If E is of the form A.B, S(E) contains the elements of S(A)...
|
||||
if (auto *ME = dyn_cast<MemberExpr>(E)) {
|
||||
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
|
||||
|
@ -5026,6 +5025,7 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr,
|
|||
|
||||
} else if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
|
||||
// Step over a derived-to-base conversion.
|
||||
E = ICE->getSubExpr();
|
||||
if (ICE->getCastKind() == CK_NoOp)
|
||||
continue;
|
||||
if (ICE->getCastKind() != CK_DerivedToBase &&
|
||||
|
@ -5038,7 +5038,6 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr,
|
|||
LHS.Designator.Entries[PathLength]
|
||||
.getAsBaseOrMember().getPointer()));
|
||||
}
|
||||
E = ICE->getSubExpr();
|
||||
|
||||
// -- Otherwise, S(E) is empty.
|
||||
} else {
|
||||
|
|
|
@ -513,4 +513,12 @@ namespace Union {
|
|||
static_assert(return_init_all().a.p == 7); // expected-error {{}} expected-note {{read of member 'p' of union with no active member}}
|
||||
static_assert(return_init_all().a.q == 8); // expected-error {{}} expected-note {{read of member 'q' of union with no active member}}
|
||||
constexpr B init_all = return_init_all();
|
||||
|
||||
constexpr bool test_no_member_change = []{
|
||||
union U { char dummy = {}; };
|
||||
U u1;
|
||||
U u2;
|
||||
u1 = u2;
|
||||
return true;
|
||||
}();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue