diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/APValue.cpp | 29 | ||||
-rw-r--r-- | clang/lib/AST/Decl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 29 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 5 |
7 files changed, 46 insertions, 29 deletions
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index c5db3cd582d..5d5e67a8902 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -219,9 +219,11 @@ APValue::UnionData::~UnionData () { delete Value; } -APValue::APValue(const APValue &RHS) : Kind(Uninitialized) { +APValue::APValue(const APValue &RHS) : Kind(None) { switch (RHS.getKind()) { - case Uninitialized: + case None: + case Indeterminate: + Kind = RHS.getKind(); break; case Int: MakeInt(); @@ -313,12 +315,13 @@ void APValue::DestroyDataAndMakeUninit() { ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData(); else if (Kind == AddrLabelDiff) ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData(); - Kind = Uninitialized; + Kind = None; } bool APValue::needsCleanup() const { switch (getKind()) { - case Uninitialized: + case None: + case Indeterminate: case AddrLabelDiff: return false; case Struct: @@ -376,8 +379,11 @@ static double GetApproxValue(const llvm::APFloat &F) { void APValue::dump(raw_ostream &OS) const { switch (getKind()) { - case Uninitialized: - OS << "Uninitialized"; + case None: + OS << "None"; + return; + case Indeterminate: + OS << "Indeterminate"; return; case Int: OS << "Int: " << getInt(); @@ -452,7 +458,10 @@ void APValue::dump(raw_ostream &OS) const { void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{ switch (getKind()) { - case APValue::Uninitialized: + case APValue::None: + Out << "<out of lifetime>"; + return; + case APValue::Indeterminate: Out << "<uninitialized>"; return; case APValue::Int: @@ -781,21 +790,21 @@ ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const { } void APValue::MakeLValue() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); static_assert(sizeof(LV) <= DataSize, "LV too big"); new ((void*)(char*)Data.buffer) LV(); Kind = LValue; } void APValue::MakeArray(unsigned InitElts, unsigned Size) { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) Arr(InitElts, Size); Kind = Array; } void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, ArrayRef<const CXXRecordDecl*> Path) { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData; Kind = MemberPointer; MPD->MemberAndIsDerivedMember.setPointer(Member); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index bc0a5a4c67e..8b77e01f4e8 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2302,7 +2302,7 @@ APValue *VarDecl::evaluateValue( // first time it is evaluated. FIXME: The notes won't always be emitted the // first time we try evaluation, so might not be produced at all. if (Eval->WasEvaluated) - return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated; + return Eval->Evaluated.isAbsent() ? nullptr : &Eval->Evaluated; const auto *Init = cast<Expr>(Eval->Value); assert(!Init->isValueDependent()); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index e654480f094..508456422b6 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1291,7 +1291,7 @@ APValue &CallStackFrame::createTemporary(const void *Key, bool IsLifetimeExtended) { unsigned Version = Info.CurrentCall->getTempVersion(); APValue &Result = Temporaries[MapKeyTy(Key, Version)]; - assert(Result.isUninit() && "temporary created multiple times"); + assert(Result.isAbsent() && "temporary created multiple times"); Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended)); return Result; } @@ -2025,7 +2025,7 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, Expr::ConstExprUsage Usage = Expr::EvaluateForCodeGen) { - if (Value.isUninit()) { + if (!Value.hasValue()) { Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized) << true << Type; return false; @@ -2108,7 +2108,8 @@ static bool EvalPointerValueAsBool(const APValue &Value, bool &Result) { static bool HandleConversionToBool(const APValue &Val, bool &Result) { switch (Val.getKind()) { - case APValue::Uninitialized: + case APValue::None: + case APValue::Indeterminate: return false; case APValue::Int: Result = Val.getInt().getBoolValue(); @@ -2971,10 +2972,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, // Walk the designator's path to find the subobject. for (unsigned I = 0, N = Sub.Entries.size(); /**/; ++I) { - if (O->isUninit()) { + if (!O->hasValue()) { if (!Info.checkingPotentialConstantExpression()) Info.FFDiag(E, diag::note_constexpr_access_uninit) - << handler.AccessKind; + << handler.AccessKind << O->isIndeterminate(); return handler.failed(); } @@ -5040,7 +5041,7 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This, } // Reserve space for the struct members. - if (!RD->isUnion() && Result.isUninit()) + if (!RD->isUnion() && !Result.hasValue()) Result = APValue(APValue::UninitStruct(), RD->getNumBases(), std::distance(RD->field_begin(), RD->field_end())); @@ -5097,7 +5098,7 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This, // subobject other than the first. // FIXME: In this case, the values of the other subobjects are // specified, since zero-initialization sets all padding bits to zero. - if (Value->isUninit() || + if (!Value->hasValue() || (Value->isUnion() && Value->getUnionField() != FD)) { if (CD->isUnion()) *Value = APValue(FD); @@ -5953,7 +5954,9 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) { APValue *V; if (!evaluateVarDeclInit(Info, E, VD, Frame, V, nullptr)) return false; - if (V->isUninit()) { + if (!V->hasValue()) { + // FIXME: Is it possible for V to be indeterminate here? If so, we should + // adjust the diagnostic to say that. if (!Info.checkingPotentialConstantExpression()) Info.FFDiag(E, diag::note_constexpr_use_uninit_reference); return false; @@ -7217,7 +7220,7 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) { return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr); } - if (Result.isUninit()) + if (!Result.hasValue()) Result = APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0, std::distance(RD->field_begin(), RD->field_end())); unsigned ElementNo = 0; @@ -7294,7 +7297,7 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, bool ZeroInit = E->requiresZeroInitialization(); if (CheckTrivialDefaultConstructor(Info, E->getExprLoc(), FD, ZeroInit)) { // If we've already performed zero-initialization, we're already done. - if (!Result.isUninit()) + if (Result.hasValue()) return true; // We can get here in two different ways: @@ -7794,7 +7797,7 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) { // If the array was previously zero-initialized, preserve the // zero-initialized values. - if (!Filler.isUninit()) { + if (Filler.hasValue()) { for (unsigned I = 0, E = Result.getArrayInitializedElts(); I != E; ++I) Result.getArrayInitializedElt(I) = Filler; if (Result.hasArrayFiller()) @@ -7863,7 +7866,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, const LValue &Subobject, APValue *Value, QualType Type) { - bool HadZeroInit = !Value->isUninit(); + bool HadZeroInit = Value->hasValue(); if (const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(Type)) { unsigned N = CAT->getSize().getZExtValue(); @@ -8427,7 +8430,7 @@ static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg) { return EvaluateBuiltinConstantPForLValue(V); // Otherwise, any constant value is good enough. - return V.getKind() != APValue::Uninitialized; + return V.hasValue(); } // Anything else isn't considered to be sufficiently constant. diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 70904b192a3..caa327c19a4 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1860,8 +1860,10 @@ ConstantLValueEmitter::VisitMaterializeTemporaryExpr( llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value, QualType DestType) { switch (Value.getKind()) { - case APValue::Uninitialized: - llvm_unreachable("Constant expressions should be initialized."); + case APValue::None: + case APValue::Indeterminate: + // Out-of-lifetime and indeterminate values can be modeled as 'undef'. + return llvm::UndefValue::get(CGM.getTypes().ConvertType(DestType)); case APValue::LValue: return ConstantLValueEmitter(*this, Value, DestType).tryEmit(); case APValue::Int: diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index a2d6d59800c..b9573f71a3a 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1990,7 +1990,7 @@ Address CodeGenFunction::EmitMSVAListRef(const Expr *E) { void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init) { - assert(!Init.isUninit() && "Invalid DeclRefExpr initializer!"); + assert(Init.hasValue() && "Invalid DeclRefExpr initializer!"); if (CGDebugInfo *Dbg = getDebugInfo()) if (CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo) Dbg->EmitGlobalVariable(E->getDecl(), Init); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index a16e7ce47f9..6daea419281 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4886,7 +4886,7 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( // evaluating the initializer if the surrounding constant expression // modifies the temporary. Value = getContext().getMaterializedTemporaryValue(E, false); - if (Value && Value->isUninit()) + if (Value && Value->isAbsent()) Value = nullptr; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 239b4ae7957..2483a28b252 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -6390,10 +6390,13 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // Convert the APValue to a TemplateArgument. switch (Value.getKind()) { - case APValue::Uninitialized: + case APValue::None: assert(ParamType->isNullPtrType()); Converted = TemplateArgument(CanonParamType, /*isNullPtr*/true); break; + case APValue::Indeterminate: + llvm_unreachable("result of constant evaluation should be initialized"); + break; case APValue::Int: assert(ParamType->isIntegralOrEnumerationType()); Converted = TemplateArgument(Context, Value.getInt(), CanonParamType); |