@@ -4475,37 +4475,48 @@ static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E,
4475
4475
}
4476
4476
4477
4477
/// Get the value to use for a default-initialized object of type T.
4478
- static APValue getDefaultInitValue(QualType T) {
4478
+ /// Return false if it encounters something invalid.
4479
+ static bool getDefaultInitValue(QualType T, APValue &Result) {
4480
+ bool Success = true;
4479
4481
if (auto *RD = T->getAsCXXRecordDecl()) {
4480
- if (RD->isUnion())
4481
- return APValue((const FieldDecl*)nullptr);
4482
-
4483
- APValue Struct(APValue::UninitStruct(), RD->getNumBases(),
4484
- std::distance(RD->field_begin(), RD->field_end()));
4482
+ if (RD->isInvalidDecl()) {
4483
+ Result = APValue();
4484
+ return false;
4485
+ }
4486
+ if (RD->isUnion()) {
4487
+ Result = APValue((const FieldDecl *)nullptr);
4488
+ return true;
4489
+ }
4490
+ Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
4491
+ std::distance(RD->field_begin(), RD->field_end()));
4485
4492
4486
4493
unsigned Index = 0;
4487
4494
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
4488
- End = RD->bases_end(); I != End; ++I, ++Index)
4489
- Struct.getStructBase(Index) = getDefaultInitValue(I->getType());
4495
+ End = RD->bases_end();
4496
+ I != End; ++I, ++Index)
4497
+ Success &= getDefaultInitValue(I->getType(), Result.getStructBase(Index));
4490
4498
4491
4499
for (const auto *I : RD->fields()) {
4492
4500
if (I->isUnnamedBitfield())
4493
4501
continue;
4494
- Struct.getStructField (I->getFieldIndex()) =
4495
- getDefaultInitValue (I->getType( ));
4502
+ Success &= getDefaultInitValue (I->getType(),
4503
+ Result.getStructField (I->getFieldIndex() ));
4496
4504
}
4497
- return Struct ;
4505
+ return Success ;
4498
4506
}
4499
4507
4500
4508
if (auto *AT =
4501
4509
dyn_cast_or_null<ConstantArrayType>(T->getAsArrayTypeUnsafe())) {
4502
- APValue Array(APValue::UninitArray(), 0, AT->getSize().getZExtValue());
4503
- if (Array.hasArrayFiller())
4504
- Array.getArrayFiller() = getDefaultInitValue(AT->getElementType());
4505
- return Array;
4510
+ Result = APValue(APValue::UninitArray(), 0, AT->getSize().getZExtValue());
4511
+ if (Result.hasArrayFiller())
4512
+ Success &=
4513
+ getDefaultInitValue(AT->getElementType(), Result.getArrayFiller());
4514
+
4515
+ return Success;
4506
4516
}
4507
4517
4508
- return APValue::IndeterminateValue();
4518
+ Result = APValue::IndeterminateValue();
4519
+ return true;
4509
4520
}
4510
4521
4511
4522
namespace {
@@ -4535,10 +4546,8 @@ static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD) {
4535
4546
Info.CurrentCall->createTemporary(VD, VD->getType(), true, Result);
4536
4547
4537
4548
const Expr *InitE = VD->getInit();
4538
- if (!InitE) {
4539
- Val = getDefaultInitValue(VD->getType());
4540
- return true;
4541
- }
4549
+ if (!InitE)
4550
+ return getDefaultInitValue(VD->getType(), Val);
4542
4551
4543
4552
if (InitE->isValueDependent())
4544
4553
return false;
@@ -5535,11 +5544,11 @@ struct StartLifetimeOfUnionMemberHandler {
5535
5544
const Expr *LHSExpr;
5536
5545
const FieldDecl *Field;
5537
5546
bool DuringInit;
5538
-
5547
+ bool Failed = false;
5539
5548
static const AccessKinds AccessKind = AK_Assign;
5540
5549
5541
5550
typedef bool result_type;
5542
- bool failed() { return false ; }
5551
+ bool failed() { return Failed ; }
5543
5552
bool found(APValue &Subobj, QualType SubobjType) {
5544
5553
// We are supposed to perform no initialization but begin the lifetime of
5545
5554
// the object. We interpret that as meaning to do what default
@@ -5563,8 +5572,9 @@ struct StartLifetimeOfUnionMemberHandler {
5563
5572
diag::note_constexpr_union_member_change_during_init);
5564
5573
return false;
5565
5574
}
5566
-
5567
- Subobj.setUnion(Field, getDefaultInitValue(Field->getType()));
5575
+ APValue Result;
5576
+ Failed = !getDefaultInitValue(Field->getType(), Result);
5577
+ Subobj.setUnion(Field, Result);
5568
5578
return true;
5569
5579
}
5570
5580
bool found(APSInt &Value, QualType SubobjType) {
@@ -5880,8 +5890,9 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
5880
5890
for (; !declaresSameEntity(*FieldIt, FD); ++FieldIt) {
5881
5891
assert(FieldIt != RD->field_end() && "missing field?");
5882
5892
if (!FieldIt->isUnnamedBitfield())
5883
- Result.getStructField(FieldIt->getFieldIndex()) =
5884
- getDefaultInitValue(FieldIt->getType());
5893
+ Success &= getDefaultInitValue(
5894
+ FieldIt->getType(),
5895
+ Result.getStructField(FieldIt->getFieldIndex()));
5885
5896
}
5886
5897
++FieldIt;
5887
5898
};
@@ -5933,10 +5944,10 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
5933
5944
if (CD->isUnion())
5934
5945
*Value = APValue(FD);
5935
5946
else
5936
- // FIXME: This immediately starts the lifetime of all members of an
5937
- // anonymous struct. It would be preferable to strictly start member
5938
- // lifetime in initialization order.
5939
- *Value = getDefaultInitValue(Info.Ctx.getRecordType(CD));
5947
+ // FIXME: This immediately starts the lifetime of all members of
5948
+ // an anonymous struct. It would be preferable to strictly start
5949
+ // member lifetime in initialization order.
5950
+ Success & = getDefaultInitValue(Info.Ctx.getRecordType(CD), *Value );
5940
5951
}
5941
5952
// Store Subobject as its parent before updating it for the last element
5942
5953
// in the chain.
@@ -5983,8 +5994,9 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
5983
5994
if (!RD->isUnion()) {
5984
5995
for (; FieldIt != RD->field_end(); ++FieldIt) {
5985
5996
if (!FieldIt->isUnnamedBitfield())
5986
- Result.getStructField(FieldIt->getFieldIndex()) =
5987
- getDefaultInitValue(FieldIt->getType());
5997
+ Success &= getDefaultInitValue(
5998
+ FieldIt->getType(),
5999
+ Result.getStructField(FieldIt->getFieldIndex()));
5988
6000
}
5989
6001
}
5990
6002
@@ -9070,8 +9082,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
9070
9082
} else if (Init) {
9071
9083
if (!EvaluateInPlace(*Val, Info, Result, Init))
9072
9084
return false;
9073
- } else {
9074
- *Val = getDefaultInitValue(AllocType) ;
9085
+ } else if (!getDefaultInitValue(AllocType, *Val)) {
9086
+ return false ;
9075
9087
}
9076
9088
9077
9089
// Array new returns a pointer to the first element, not a pointer to the
@@ -9442,8 +9454,7 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
9442
9454
if (ZeroInit)
9443
9455
return ZeroInitialization(E, T);
9444
9456
9445
- Result = getDefaultInitValue(T);
9446
- return true;
9457
+ return getDefaultInitValue(T, Result);
9447
9458
}
9448
9459
9449
9460
const FunctionDecl *Definition = nullptr;
@@ -14209,10 +14220,11 @@ bool VarDecl::evaluateDestruction(
14209
14220
// Make a copy of the value for the destructor to mutate, if we know it.
14210
14221
// Otherwise, treat the value as default-initialized; if the destructor works
14211
14222
// anyway, then the destruction is constant (and must be essentially empty).
14212
- APValue DestroyedValue =
14213
- (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
14214
- ? *getEvaluatedValue()
14215
- : getDefaultInitValue(getType());
14223
+ APValue DestroyedValue;
14224
+ if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
14225
+ DestroyedValue = *getEvaluatedValue();
14226
+ else if (!getDefaultInitValue(getType(), DestroyedValue))
14227
+ return false;
14216
14228
14217
14229
EvalInfo Info(getASTContext(), EStatus, EvalInfo::EM_ConstantExpression);
14218
14230
Info.setEvaluatingDecl(this, DestroyedValue,
0 commit comments