summaryrefslogtreecommitdiff
path: root/devel/llvm60/files/clang/patch-stable12-r342281.diff
diff options
context:
space:
mode:
Diffstat (limited to 'devel/llvm60/files/clang/patch-stable12-r342281.diff')
-rw-r--r--devel/llvm60/files/clang/patch-stable12-r342281.diff834
1 files changed, 0 insertions, 834 deletions
diff --git a/devel/llvm60/files/clang/patch-stable12-r342281.diff b/devel/llvm60/files/clang/patch-stable12-r342281.diff
deleted file mode 100644
index 4a6e9f615889..000000000000
--- a/devel/llvm60/files/clang/patch-stable12-r342281.diff
+++ /dev/null
@@ -1,834 +0,0 @@
-r342281 | dim | 2018-12-20 19:28:53 +0100 (Thu, 20 Dec 2018) | 24 lines
-
-Pull in r329671 from upstream clang trunk (by Akira Hatanaka):
-
- [ExprConstant] Use an AST node and a version number as a key to
- create an APValue and retrieve it from map Temporaries.
-
- The version number is needed when a single AST node is visited
- multiple times and is used to create APValues that are required to be
- distinct from each other (for example, MaterializeTemporaryExprs in
- default arguments and VarDecls in loops).
-
- rdar://problem/36505742
-
- Differential Revision: https://reviews.llvm.org/D42776
-
-This should fix 'Assertion failed: (Result.isUninit() && "temporary
-created multiple times"), function createTemporary' errors (if
-assertions are enabled, otherwise the compiler internal state might go
-bad), when building the graphics/rawtherapee port.
-
-Direct commit to stable/11 and stable/12, since head already has clang
-7.0.1, which includes this change.
-
-PR: 234144
-
-Index: tools/clang/include/clang/AST/APValue.h
-===================================================================
---- tools/clang/include/clang/AST/APValue.h (revision 342280)
-+++ tools/clang/include/clang/AST/APValue.h (revision 342281)
-@@ -53,7 +53,58 @@ class APValue {
- MemberPointer,
- AddrLabelDiff
- };
-- typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
-+
-+ class LValueBase {
-+ public:
-+ typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy;
-+
-+ LValueBase() : CallIndex(0), Version(0) {}
-+
-+ template <class T>
-+ LValueBase(T P, unsigned I = 0, unsigned V = 0)
-+ : Ptr(P), CallIndex(I), Version(V) {}
-+
-+ template <class T>
-+ bool is() const { return Ptr.is<T>(); }
-+
-+ template <class T>
-+ T get() const { return Ptr.get<T>(); }
-+
-+ template <class T>
-+ T dyn_cast() const { return Ptr.dyn_cast<T>(); }
-+
-+ void *getOpaqueValue() const;
-+
-+ bool isNull() const;
-+
-+ explicit operator bool () const;
-+
-+ PtrTy getPointer() const {
-+ return Ptr;
-+ }
-+
-+ unsigned getCallIndex() const {
-+ return CallIndex;
-+ }
-+
-+ void setCallIndex(unsigned Index) {
-+ CallIndex = Index;
-+ }
-+
-+ unsigned getVersion() const {
-+ return Version;
-+ }
-+
-+ bool operator==(const LValueBase &Other) const {
-+ return Ptr == Other.Ptr && CallIndex == Other.CallIndex &&
-+ Version == Other.Version;
-+ }
-+
-+ private:
-+ PtrTy Ptr;
-+ unsigned CallIndex, Version;
-+ };
-+
- typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
- union LValuePathEntry {
- /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
-@@ -135,15 +186,15 @@ class APValue {
- }
- APValue(const APValue &RHS);
- APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
-- APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
-+ APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
- bool IsNullPtr = false)
- : Kind(Uninitialized) {
-- MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
-+ MakeLValue(); setLValue(B, O, N, IsNullPtr);
- }
- APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
-- bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
-+ bool OnePastTheEnd, bool IsNullPtr = false)
- : Kind(Uninitialized) {
-- MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
-+ MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
- }
- APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
- MakeArray(InitElts, Size);
-@@ -255,6 +306,7 @@ class APValue {
- bool hasLValuePath() const;
- ArrayRef<LValuePathEntry> getLValuePath() const;
- unsigned getLValueCallIndex() const;
-+ unsigned getLValueVersion() const;
- bool isNullPointer() const;
-
- APValue &getVectorElt(unsigned I) {
-@@ -376,10 +428,10 @@ class APValue {
- ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
- }
- void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
-- unsigned CallIndex, bool IsNullPtr);
-+ bool IsNullPtr);
- void setLValue(LValueBase B, const CharUnits &O,
- ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
-- unsigned CallIndex, bool IsNullPtr);
-+ bool IsNullPtr);
- void setUnion(const FieldDecl *Field, const APValue &Value) {
- assert(isUnion() && "Invalid accessor");
- ((UnionData*)(char*)Data.buffer)->Field = Field;
-@@ -451,4 +503,14 @@ class APValue {
-
- } // end namespace clang.
-
-+namespace llvm {
-+template<> struct DenseMapInfo<clang::APValue::LValueBase> {
-+ static clang::APValue::LValueBase getEmptyKey();
-+ static clang::APValue::LValueBase getTombstoneKey();
-+ static unsigned getHashValue(const clang::APValue::LValueBase &Base);
-+ static bool isEqual(const clang::APValue::LValueBase &LHS,
-+ const clang::APValue::LValueBase &RHS);
-+};
-+}
-+
- #endif
-Index: tools/clang/lib/AST/APValue.cpp
-===================================================================
---- tools/clang/lib/AST/APValue.cpp (revision 342280)
-+++ tools/clang/lib/AST/APValue.cpp (revision 342281)
-@@ -23,14 +23,57 @@ using namespace clang;
-
- namespace {
- struct LVBase {
-- llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
-+ APValue::LValueBase Base;
- CharUnits Offset;
- unsigned PathLength;
-- unsigned CallIndex;
-- bool IsNullPtr;
-+ bool IsNullPtr : 1;
-+ bool IsOnePastTheEnd : 1;
- };
- }
-
-+void *APValue::LValueBase::getOpaqueValue() const {
-+ return Ptr.getOpaqueValue();
-+}
-+
-+bool APValue::LValueBase::isNull() const {
-+ return Ptr.isNull();
-+}
-+
-+APValue::LValueBase::operator bool () const {
-+ return static_cast<bool>(Ptr);
-+}
-+
-+clang::APValue::LValueBase
-+llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
-+ return clang::APValue::LValueBase(
-+ DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getEmptyKey(),
-+ DenseMapInfo<unsigned>::getEmptyKey(),
-+ DenseMapInfo<unsigned>::getEmptyKey());
-+}
-+
-+clang::APValue::LValueBase
-+llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
-+ return clang::APValue::LValueBase(
-+ DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getTombstoneKey(),
-+ DenseMapInfo<unsigned>::getTombstoneKey(),
-+ DenseMapInfo<unsigned>::getTombstoneKey());
-+}
-+
-+unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(
-+ const clang::APValue::LValueBase &Base) {
-+ llvm::FoldingSetNodeID ID;
-+ ID.AddPointer(Base.getOpaqueValue());
-+ ID.AddInteger(Base.getCallIndex());
-+ ID.AddInteger(Base.getVersion());
-+ return ID.ComputeHash();
-+}
-+
-+bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(
-+ const clang::APValue::LValueBase &LHS,
-+ const clang::APValue::LValueBase &RHS) {
-+ return LHS == RHS;
-+}
-+
- struct APValue::LV : LVBase {
- static const unsigned InlinePathSpace =
- (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
-@@ -150,11 +193,10 @@ APValue::APValue(const APValue &RHS) : Kind(Uninit
- MakeLValue();
- if (RHS.hasLValuePath())
- setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
-- RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex(),
-- RHS.isNullPointer());
-+ RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
- else
- setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
-- RHS.getLValueCallIndex(), RHS.isNullPointer());
-+ RHS.isNullPointer());
- break;
- case Array:
- MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
-@@ -552,12 +594,12 @@ std::string APValue::getAsString(ASTContext &Ctx,
-
- const APValue::LValueBase APValue::getLValueBase() const {
- assert(isLValue() && "Invalid accessor");
-- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
-+ return ((const LV*)(const void*)Data.buffer)->Base;
- }
-
- bool APValue::isLValueOnePastTheEnd() const {
- assert(isLValue() && "Invalid accessor");
-- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
-+ return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
- }
-
- CharUnits &APValue::getLValueOffset() {
-@@ -578,9 +620,14 @@ ArrayRef<APValue::LValuePathEntry> APValue::getLVa
-
- unsigned APValue::getLValueCallIndex() const {
- assert(isLValue() && "Invalid accessor");
-- return ((const LV*)(const char*)Data.buffer)->CallIndex;
-+ return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
- }
-
-+unsigned APValue::getLValueVersion() const {
-+ assert(isLValue() && "Invalid accessor");
-+ return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
-+}
-+
- bool APValue::isNullPointer() const {
- assert(isLValue() && "Invalid usage");
- return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
-@@ -587,13 +634,12 @@ bool APValue::isNullPointer() const {
- }
-
- void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
-- unsigned CallIndex, bool IsNullPtr) {
-+ bool IsNullPtr) {
- assert(isLValue() && "Invalid accessor");
- LV &LVal = *((LV*)(char*)Data.buffer);
-- LVal.BaseAndIsOnePastTheEnd.setPointer(B);
-- LVal.BaseAndIsOnePastTheEnd.setInt(false);
-+ LVal.Base = B;
-+ LVal.IsOnePastTheEnd = false;
- LVal.Offset = O;
-- LVal.CallIndex = CallIndex;
- LVal.resizePath((unsigned)-1);
- LVal.IsNullPtr = IsNullPtr;
- }
-@@ -600,13 +646,12 @@ void APValue::setLValue(LValueBase B, const CharUn
-
- void APValue::setLValue(LValueBase B, const CharUnits &O,
- ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
-- unsigned CallIndex, bool IsNullPtr) {
-+ bool IsNullPtr) {
- assert(isLValue() && "Invalid accessor");
- LV &LVal = *((LV*)(char*)Data.buffer);
-- LVal.BaseAndIsOnePastTheEnd.setPointer(B);
-- LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
-+ LVal.Base = B;
-+ LVal.IsOnePastTheEnd = IsOnePastTheEnd;
- LVal.Offset = O;
-- LVal.CallIndex = CallIndex;
- LVal.resizePath(Path.size());
- memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
- LVal.IsNullPtr = IsNullPtr;
-Index: tools/clang/lib/AST/ExprConstant.cpp
-===================================================================
---- tools/clang/lib/AST/ExprConstant.cpp (revision 342280)
-+++ tools/clang/lib/AST/ExprConstant.cpp (revision 342281)
-@@ -446,8 +446,8 @@ namespace {
-
- // Note that we intentionally use std::map here so that references to
- // values are stable.
-- typedef std::map<const void*, APValue> MapTy;
-- typedef MapTy::const_iterator temp_iterator;
-+ typedef std::pair<const void *, unsigned> MapKeyTy;
-+ typedef std::map<MapKeyTy, APValue> MapTy;
- /// Temporaries - Temporary lvalues materialized within this stack frame.
- MapTy Temporaries;
-
-@@ -457,6 +457,20 @@ namespace {
- /// Index - The call index of this call.
- unsigned Index;
-
-+ /// The stack of integers for tracking version numbers for temporaries.
-+ SmallVector<unsigned, 2> TempVersionStack = {1};
-+ unsigned CurTempVersion = TempVersionStack.back();
-+
-+ unsigned getTempVersion() const { return TempVersionStack.back(); }
-+
-+ void pushTempVersion() {
-+ TempVersionStack.push_back(++CurTempVersion);
-+ }
-+
-+ void popTempVersion() {
-+ TempVersionStack.pop_back();
-+ }
-+
- // FIXME: Adding this to every 'CallStackFrame' may have a nontrivial impact
- // on the overall stack usage of deeply-recursing constexpr evaluataions.
- // (We should cache this map rather than recomputing it repeatedly.)
-@@ -473,10 +487,36 @@ namespace {
- APValue *Arguments);
- ~CallStackFrame();
-
-- APValue *getTemporary(const void *Key) {
-- MapTy::iterator I = Temporaries.find(Key);
-- return I == Temporaries.end() ? nullptr : &I->second;
-+ // Return the temporary for Key whose version number is Version.
-+ APValue *getTemporary(const void *Key, unsigned Version) {
-+ MapKeyTy KV(Key, Version);
-+ auto LB = Temporaries.lower_bound(KV);
-+ if (LB != Temporaries.end() && LB->first == KV)
-+ return &LB->second;
-+ // Pair (Key,Version) wasn't found in the map. Check that no elements
-+ // in the map have 'Key' as their key.
-+ assert((LB == Temporaries.end() || LB->first.first != Key) &&
-+ (LB == Temporaries.begin() || std::prev(LB)->first.first != Key) &&
-+ "Element with key 'Key' found in map");
-+ return nullptr;
- }
-+
-+ // Return the current temporary for Key in the map.
-+ APValue *getCurrentTemporary(const void *Key) {
-+ auto UB = Temporaries.upper_bound(MapKeyTy(Key, UINT_MAX));
-+ if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
-+ return &std::prev(UB)->second;
-+ return nullptr;
-+ }
-+
-+ // Return the version number of the current temporary for Key.
-+ unsigned getCurrentTemporaryVersion(const void *Key) const {
-+ auto UB = Temporaries.upper_bound(MapKeyTy(Key, UINT_MAX));
-+ if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
-+ return std::prev(UB)->first.second;
-+ return 0;
-+ }
-+
- APValue &createTemporary(const void *Key, bool IsLifetimeExtended);
- };
-
-@@ -606,7 +646,8 @@ namespace {
-
- /// EvaluatingObject - Pair of the AST node that an lvalue represents and
- /// the call index that that lvalue was allocated in.
-- typedef std::pair<APValue::LValueBase, unsigned> EvaluatingObject;
-+ typedef std::pair<APValue::LValueBase, std::pair<unsigned, unsigned>>
-+ EvaluatingObject;
-
- /// EvaluatingConstructors - Set of objects that are currently being
- /// constructed.
-@@ -625,8 +666,10 @@ namespace {
- }
- };
-
-- bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex) {
-- return EvaluatingConstructors.count(EvaluatingObject(Decl, CallIndex));
-+ bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex,
-+ unsigned Version) {
-+ return EvaluatingConstructors.count(
-+ EvaluatingObject(Decl, {CallIndex, Version}));
- }
-
- /// The current array initialization index, if we're performing array
-@@ -722,7 +765,7 @@ namespace {
- void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
- EvaluatingDecl = Base;
- EvaluatingDeclValue = &Value;
-- EvaluatingConstructors.insert({Base, 0});
-+ EvaluatingConstructors.insert({Base, {0, 0}});
- }
-
- const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); }
-@@ -1086,11 +1129,16 @@ namespace {
- unsigned OldStackSize;
- public:
- ScopeRAII(EvalInfo &Info)
-- : Info(Info), OldStackSize(Info.CleanupStack.size()) {}
-+ : Info(Info), OldStackSize(Info.CleanupStack.size()) {
-+ // Push a new temporary version. This is needed to distinguish between
-+ // temporaries created in different iterations of a loop.
-+ Info.CurrentCall->pushTempVersion();
-+ }
- ~ScopeRAII() {
- // Body moved to a static method to encourage the compiler to inline away
- // instances of this class.
- cleanup(Info, OldStackSize);
-+ Info.CurrentCall->popTempVersion();
- }
- private:
- static void cleanup(EvalInfo &Info, unsigned OldStackSize) {
-@@ -1170,7 +1218,8 @@ CallStackFrame::~CallStackFrame() {
-
- APValue &CallStackFrame::createTemporary(const void *Key,
- bool IsLifetimeExtended) {
-- APValue &Result = Temporaries[Key];
-+ unsigned Version = Info.CurrentCall->getTempVersion();
-+ APValue &Result = Temporaries[MapKeyTy(Key, Version)];
- assert(Result.isUninit() && "temporary created multiple times");
- Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
- return Result;
-@@ -1262,27 +1311,27 @@ namespace {
- struct LValue {
- APValue::LValueBase Base;
- CharUnits Offset;
-- unsigned InvalidBase : 1;
-- unsigned CallIndex : 31;
- SubobjectDesignator Designator;
-- bool IsNullPtr;
-+ bool IsNullPtr : 1;
-+ bool InvalidBase : 1;
-
- const APValue::LValueBase getLValueBase() const { return Base; }
- CharUnits &getLValueOffset() { return Offset; }
- const CharUnits &getLValueOffset() const { return Offset; }
-- unsigned getLValueCallIndex() const { return CallIndex; }
- SubobjectDesignator &getLValueDesignator() { return Designator; }
- const SubobjectDesignator &getLValueDesignator() const { return Designator;}
- bool isNullPointer() const { return IsNullPtr;}
-
-+ unsigned getLValueCallIndex() const { return Base.getCallIndex(); }
-+ unsigned getLValueVersion() const { return Base.getVersion(); }
-+
- void moveInto(APValue &V) const {
- if (Designator.Invalid)
-- V = APValue(Base, Offset, APValue::NoLValuePath(), CallIndex,
-- IsNullPtr);
-+ V = APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
- else {
- assert(!InvalidBase && "APValues can't handle invalid LValue bases");
- V = APValue(Base, Offset, Designator.Entries,
-- Designator.IsOnePastTheEnd, CallIndex, IsNullPtr);
-+ Designator.IsOnePastTheEnd, IsNullPtr);
- }
- }
- void setFrom(ASTContext &Ctx, const APValue &V) {
-@@ -1290,12 +1339,11 @@ namespace {
- Base = V.getLValueBase();
- Offset = V.getLValueOffset();
- InvalidBase = false;
-- CallIndex = V.getLValueCallIndex();
- Designator = SubobjectDesignator(Ctx, V);
- IsNullPtr = V.isNullPointer();
- }
-
-- void set(APValue::LValueBase B, unsigned I = 0, bool BInvalid = false) {
-+ void set(APValue::LValueBase B, bool BInvalid = false) {
- #ifndef NDEBUG
- // We only allow a few types of invalid bases. Enforce that here.
- if (BInvalid) {
-@@ -1308,7 +1356,6 @@ namespace {
- Base = B;
- Offset = CharUnits::fromQuantity(0);
- InvalidBase = BInvalid;
-- CallIndex = I;
- Designator = SubobjectDesignator(getType(B));
- IsNullPtr = false;
- }
-@@ -1317,13 +1364,12 @@ namespace {
- Base = (Expr *)nullptr;
- Offset = CharUnits::fromQuantity(TargetVal);
- InvalidBase = false;
-- CallIndex = 0;
- Designator = SubobjectDesignator(PointerTy->getPointeeType());
- IsNullPtr = true;
- }
-
- void setInvalid(APValue::LValueBase B, unsigned I = 0) {
-- set(B, I, true);
-+ set(B, true);
- }
-
- // Check that this LValue is not based on a null pointer. If it is, produce
-@@ -1525,6 +1571,15 @@ static bool EvaluateAsRValue(EvalInfo &Info, const
- // Misc utilities
- //===----------------------------------------------------------------------===//
-
-+/// A helper function to create a temporary and set an LValue.
-+template <class KeyTy>
-+static APValue &createTemporary(const KeyTy *Key, bool IsLifetimeExtended,
-+ LValue &LV, CallStackFrame &Frame) {
-+ LV.set({Key, Frame.Info.CurrentCall->Index,
-+ Frame.Info.CurrentCall->getTempVersion()});
-+ return Frame.createTemporary(Key, IsLifetimeExtended);
-+}
-+
- /// Negate an APSInt in place, converting it to a signed form if necessary, and
- /// preserving its value (by extending by up to one bit as needed).
- static void negateAsSigned(APSInt &Int) {
-@@ -1854,7 +1909,7 @@ static const ValueDecl *GetLValueBaseDecl(const LV
- }
-
- static bool IsLiteralLValue(const LValue &Value) {
-- if (Value.CallIndex)
-+ if (Value.getLValueCallIndex())
- return false;
- const Expr *E = Value.Base.dyn_cast<const Expr*>();
- return E && !isa<MaterializeTemporaryExpr>(E);
-@@ -2404,7 +2459,7 @@ static bool handleLValueToRValueConversion(EvalInf
- /// \param Result Filled in with a pointer to the value of the variable.
- static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
- const VarDecl *VD, CallStackFrame *Frame,
-- APValue *&Result) {
-+ APValue *&Result, const LValue *LVal) {
-
- // If this is a parameter to an active constexpr function call, perform
- // argument substitution.
-@@ -2423,7 +2478,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, co
-
- // If this is a local variable, dig out its value.
- if (Frame) {
-- Result = Frame->getTemporary(VD);
-+ Result = LVal ? Frame->getTemporary(VD, LVal->getLValueVersion())
-+ : Frame->getCurrentTemporary(VD);
- if (!Result) {
- // Assume variables referenced within a lambda's call operator that were
- // not declared within the call operator are captures and during checking
-@@ -3000,8 +3056,8 @@ static CompleteObject findCompleteObject(EvalInfo
- }
-
- CallStackFrame *Frame = nullptr;
-- if (LVal.CallIndex) {
-- Frame = Info.getCallFrame(LVal.CallIndex);
-+ if (LVal.getLValueCallIndex()) {
-+ Frame = Info.getCallFrame(LVal.getLValueCallIndex());
- if (!Frame) {
- Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
- << AK << LVal.Base.is<const ValueDecl*>();
-@@ -3113,7 +3169,7 @@ static CompleteObject findCompleteObject(EvalInfo
- }
- }
-
-- if (!evaluateVarDeclInit(Info, E, VD, Frame, BaseVal))
-+ if (!evaluateVarDeclInit(Info, E, VD, Frame, BaseVal, &LVal))
- return CompleteObject();
- } else {
- const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
-@@ -3155,7 +3211,7 @@ static CompleteObject findCompleteObject(EvalInfo
- return CompleteObject();
- }
- } else {
-- BaseVal = Frame->getTemporary(Base);
-+ BaseVal = Frame->getTemporary(Base, LVal.Base.getVersion());
- assert(BaseVal && "missing value for temporary");
- }
-
-@@ -3175,7 +3231,9 @@ static CompleteObject findCompleteObject(EvalInfo
- // During the construction of an object, it is not yet 'const'.
- // FIXME: This doesn't do quite the right thing for const subobjects of the
- // object under construction.
-- if (Info.isEvaluatingConstructor(LVal.getLValueBase(), LVal.CallIndex)) {
-+ if (Info.isEvaluatingConstructor(LVal.getLValueBase(),
-+ LVal.getLValueCallIndex(),
-+ LVal.getLValueVersion())) {
- BaseType = Info.Ctx.getCanonicalType(BaseType);
- BaseType.removeLocalConst();
- }
-@@ -3212,7 +3270,7 @@ static bool handleLValueToRValueConversion(EvalInf
-
- // Check for special cases where there is no existing APValue to look at.
- const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
-- if (Base && !LVal.CallIndex && !Type.isVolatileQualified()) {
-+ if (Base && !LVal.getLValueCallIndex() && !Type.isVolatileQualified()) {
- if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(Base)) {
- // In C99, a CompoundLiteralExpr is an lvalue, and we defer evaluating the
- // initializer until now for such expressions. Such an expression can't be
-@@ -3715,8 +3773,7 @@ static bool EvaluateVarDecl(EvalInfo &Info, const
- return true;
-
- LValue Result;
-- Result.set(VD, Info.CurrentCall->Index);
-- APValue &Val = Info.CurrentCall->createTemporary(VD, true);
-+ APValue &Val = createTemporary(VD, true, Result, *Info.CurrentCall);
-
- const Expr *InitE = VD->getInit();
- if (!InitE) {
-@@ -3772,6 +3829,19 @@ struct StmtResult {
- /// The location containing the result, if any (used to support RVO).
- const LValue *Slot;
- };
-+
-+struct TempVersionRAII {
-+ CallStackFrame &Frame;
-+
-+ TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
-+ Frame.pushTempVersion();
-+ }
-+
-+ ~TempVersionRAII() {
-+ Frame.popTempVersion();
-+ }
-+};
-+
- }
-
- static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
-@@ -4329,7 +4399,8 @@ static bool HandleConstructorCall(const Expr *E, c
- }
-
- EvalInfo::EvaluatingConstructorRAII EvalObj(
-- Info, {This.getLValueBase(), This.CallIndex});
-+ Info, {This.getLValueBase(),
-+ {This.getLValueCallIndex(), This.getLValueVersion()}});
- CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
-
- // FIXME: Creating an APValue just to hold a nonexistent return value is
-@@ -4578,9 +4649,12 @@ class ExprEvaluatorBase
- { return StmtVisitorTy::Visit(E->getResultExpr()); }
- bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
- { return StmtVisitorTy::Visit(E->getReplacement()); }
-- bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
-- { return StmtVisitorTy::Visit(E->getExpr()); }
-+ bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) {
-+ TempVersionRAII RAII(*Info.CurrentCall);
-+ return StmtVisitorTy::Visit(E->getExpr());
-+ }
- bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
-+ TempVersionRAII RAII(*Info.CurrentCall);
- // The initializer may not have been parsed yet, or might be erroneous.
- if (!E->getExpr())
- return Error(E);
-@@ -4658,7 +4732,7 @@ class ExprEvaluatorBase
- }
-
- bool VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
-- if (APValue *Value = Info.CurrentCall->getTemporary(E))
-+ if (APValue *Value = Info.CurrentCall->getCurrentTemporary(E))
- return DerivedSuccess(*Value, E);
-
- const Expr *Source = E->getSourceExpr();
-@@ -5216,7 +5290,8 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr
-
- if (!VD->getType()->isReferenceType()) {
- if (Frame) {
-- Result.set(VD, Frame->Index);
-+ Result.set({VD, Frame->Index,
-+ Info.CurrentCall->getCurrentTemporaryVersion(VD)});
- return true;
- }
- return Success(VD);
-@@ -5223,7 +5298,7 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr
- }
-
- APValue *V;
-- if (!evaluateVarDeclInit(Info, E, VD, Frame, V))
-+ if (!evaluateVarDeclInit(Info, E, VD, Frame, V, nullptr))
- return false;
- if (V->isUninit()) {
- if (!Info.checkingPotentialConstantExpression())
-@@ -5255,9 +5330,8 @@ bool LValueExprEvaluator::VisitMaterializeTemporar
- *Value = APValue();
- Result.set(E);
- } else {
-- Value = &Info.CurrentCall->
-- createTemporary(E, E->getStorageDuration() == SD_Automatic);
-- Result.set(E, Info.CurrentCall->Index);
-+ Value = &createTemporary(E, E->getStorageDuration() == SD_Automatic, Result,
-+ *Info.CurrentCall);
- }
-
- QualType Type = Inner->getType();
-@@ -5736,7 +5810,6 @@ bool PointerExprEvaluator::VisitCastExpr(const Cas
- Result.Base = (Expr*)nullptr;
- Result.InvalidBase = false;
- Result.Offset = CharUnits::fromQuantity(N);
-- Result.CallIndex = 0;
- Result.Designator.setInvalid();
- Result.IsNullPtr = false;
- return true;
-@@ -5752,9 +5825,9 @@ bool PointerExprEvaluator::VisitCastExpr(const Cas
- if (!evaluateLValue(SubExpr, Result))
- return false;
- } else {
-- Result.set(SubExpr, Info.CurrentCall->Index);
-- if (!EvaluateInPlace(Info.CurrentCall->createTemporary(SubExpr, false),
-- Info, Result, SubExpr))
-+ APValue &Value = createTemporary(SubExpr, false, Result,
-+ *Info.CurrentCall);
-+ if (!EvaluateInPlace(Value, Info, Result, SubExpr))
- return false;
- }
- // The result is a pointer to the first element of the array.
-@@ -6520,9 +6593,8 @@ class TemporaryExprEvaluator
-
- /// Visit an expression which constructs the value of this temporary.
- bool VisitConstructExpr(const Expr *E) {
-- Result.set(E, Info.CurrentCall->Index);
-- return EvaluateInPlace(Info.CurrentCall->createTemporary(E, false),
-- Info, Result, E);
-+ APValue &Value = createTemporary(E, false, Result, *Info.CurrentCall);
-+ return EvaluateInPlace(Value, Info, Result, E);
- }
-
- bool VisitCastExpr(const CastExpr *E) {
-@@ -8007,7 +8079,8 @@ static bool HasSameBase(const LValue &A, const LVa
- }
-
- return IsGlobalLValue(A.getLValueBase()) ||
-- A.getLValueCallIndex() == B.getLValueCallIndex();
-+ (A.getLValueCallIndex() == B.getLValueCallIndex() &&
-+ A.getLValueVersion() == B.getLValueVersion());
- }
-
- /// \brief Determine whether this is a pointer past the end of the complete
-@@ -9941,15 +10014,13 @@ static bool Evaluate(APValue &Result, EvalInfo &In
- return true;
- } else if (T->isArrayType()) {
- LValue LV;
-- LV.set(E, Info.CurrentCall->Index);
-- APValue &Value = Info.CurrentCall->createTemporary(E, false);
-+ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall);
- if (!EvaluateArray(E, LV, Value, Info))
- return false;
- Result = Value;
- } else if (T->isRecordType()) {
- LValue LV;
-- LV.set(E, Info.CurrentCall->Index);
-- APValue &Value = Info.CurrentCall->createTemporary(E, false);
-+ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall);
- if (!EvaluateRecord(E, LV, Value, Info))
- return false;
- Result = Value;
-@@ -9963,8 +10034,7 @@ static bool Evaluate(APValue &Result, EvalInfo &In
- QualType Unqual = T.getAtomicUnqualifiedType();
- if (Unqual->isArrayType() || Unqual->isRecordType()) {
- LValue LV;
-- LV.set(E, Info.CurrentCall->Index);
-- APValue &Value = Info.CurrentCall->createTemporary(E, false);
-+ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall);
- if (!EvaluateAtomic(E, &LV, Value, Info))
- return false;
- } else {
-@@ -10786,7 +10856,7 @@ bool Expr::isPotentialConstantExpr(const FunctionD
- // is a temporary being used as the 'this' pointer.
- LValue This;
- ImplicitValueInitExpr VIE(RD ? Info.Ctx.getRecordType(RD) : Info.Ctx.IntTy);
-- This.set(&VIE, Info.CurrentCall->Index);
-+ This.set({&VIE, Info.CurrentCall->Index});
-
- ArrayRef<const Expr*> Args;
-
-Index: tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp
-===================================================================
---- tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp (revision 342280)
-+++ tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp (revision 342281)
-@@ -852,7 +852,6 @@ namespace Lifetime {
- static_assert(h(2) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
- static_assert(h(3) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
-
-- // FIXME: This function should be treated as non-constant.
- constexpr void lifetime_versus_loops() {
- int *p = 0;
- for (int i = 0; i != 2; ++i) {
-@@ -862,10 +861,10 @@ namespace Lifetime {
- if (i)
- // This modifies the 'n' from the previous iteration of the loop outside
- // its lifetime.
-- ++*q;
-+ ++*q; // expected-note {{increment of object outside its lifetime}}
- }
- }
-- static_assert((lifetime_versus_loops(), true), "");
-+ static_assert((lifetime_versus_loops(), true), ""); // expected-error {{constant expression}} expected-note {{in call}}
- }
-
- namespace Bitfields {
-Index: tools/clang/test/SemaCXX/constexpr-default-arg.cpp
-===================================================================
---- tools/clang/test/SemaCXX/constexpr-default-arg.cpp (nonexistent)
-+++ tools/clang/test/SemaCXX/constexpr-default-arg.cpp (revision 342281)
-@@ -0,0 +1,38 @@
-+// RUN: %clang_cc1 -std=c++1y -S -o - -emit-llvm -verify %s
-+
-+namespace default_arg_temporary {
-+
-+constexpr bool equals(const float& arg = 1.0f) {
-+ return arg == 1.0f;
-+}
-+
-+constexpr const int &x(const int &p = 0) {
-+ return p;
-+}
-+
-+struct S {
-+ constexpr S(const int &a = 0) {}
-+};
-+
-+void test_default_arg2() {
-+ // This piece of code used to cause an assertion failure in
-+ // CallStackFrame::createTemporary because the same MTE is used to initilize
-+ // both elements of the array (see PR33140).
-+ constexpr S s[2] = {};
-+
-+ // This piece of code used to cause an assertion failure in
-+ // CallStackFrame::createTemporary because multiple CXXDefaultArgExpr share
-+ // the same MTE (see PR33140).
-+ static_assert(equals() && equals(), "");
-+
-+ // Test that constant expression evaluation produces distinct lvalues for
-+ // each call.
-+ static_assert(&x() != &x(), "");
-+}
-+
-+// Check that multiple CXXDefaultInitExprs don't cause an assertion failure.
-+struct A { int &&r = 0; }; // expected-warning {{binding reference member}} // expected-note {{reference member declared here}}
-+struct B { A x, y; };
-+B b = {};
-+
-+}