Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -537,7 +537,11 @@ /// rules. For example, the RHS of (0 && foo()) is not evaluated. We can /// evaluate the expression regardless of what the RHS is, but C only allows /// certain things in certain situations. +#ifndef _WIN32 struct LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) EvalInfo { +#else + struct EvalInfo { +#endif ASTContext &Ctx; /// EvalStatus - Contains information about the evaluation. @@ -575,7 +579,21 @@ /// The current array initialization index, if we're performing array /// initialization. +#ifndef _WIN32 uint64_t ArrayInitIndex = -1; +#else + /// uint64_t value is split into two uint32_t values as a workaround + /// to deal with mingw 32-bit miscompilation + uint32_t ArrayInitIndex[2] = {static_cast(-1), static_cast(-1)}; + uint64_t GetArrayInitIndex() { + return (static_cast(ArrayInitIndex[0]) << 32) + + static_cast(ArrayInitIndex[1]); + } + void SetArrayInitIndex(uint64_t index) { + ArrayInitIndex[0] = static_cast(index >> 32); + ArrayInitIndex[1] = static_cast(index); + } +#endif /// HasActiveDiagnostic - Was the previous diagnostic stored? If so, further /// notes attached to it will also be stored, otherwise they will not be. @@ -922,6 +940,7 @@ uint64_t OuterIndex; public: +#ifndef _WIN32 ArrayInitLoopIndex(EvalInfo &Info) : Info(Info), OuterIndex(Info.ArrayInitIndex) { Info.ArrayInitIndex = 0; @@ -929,6 +948,19 @@ ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; } operator uint64_t&() { return Info.ArrayInitIndex; } +#else + ArrayInitLoopIndex(EvalInfo &Info) + : Info(Info), OuterIndex(Info.GetArrayInitIndex()) { + Info.SetArrayInitIndex(0); + } + ~ArrayInitLoopIndex() { Info.SetArrayInitIndex(OuterIndex); } + + operator uint64_t() { return Info.GetArrayInitIndex(); } + ArrayInitLoopIndex& operator++() { + Info.SetArrayInitIndex(Info.GetArrayInitIndex() + 1); + return *this; + } +#endif }; }; @@ -6973,13 +7005,21 @@ } bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) { +#ifndef _WIN32 if (Info.ArrayInitIndex == uint64_t(-1)) { +#else + if (Info.GetArrayInitIndex() == uint64_t(-1)) { +#endif // We were asked to evaluate this subexpression independent of the // enclosing ArrayInitLoopExpr. We can't do that. Info.FFDiag(E); return false; } +#ifndef _WIN32 return Success(Info.ArrayInitIndex, E); +#else + return Success(Info.GetArrayInitIndex(), E); +#endif } // Note, GNU defines __null as an integer, not a pointer.