yvvan updated this revision to Diff 108878. yvvan marked 2 inline comments as done. yvvan added a comment.
Make safe solution without regression https://reviews.llvm.org/D34873 Files: lib/AST/ExprConstant.cpp 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<uint32_t>(-1), static_cast<uint32_t>(-1)}; + uint64_t GetArrayInitIndex() { + return (static_cast<uint64_t>(ArrayInitIndex[0]) << 32) + + static_cast<uint64_t>(ArrayInitIndex[1]); + } + void SetArrayInitIndex(uint64_t index) { + ArrayInitIndex[0] = static_cast<uint32_t>(index >> 32); + ArrayInitIndex[1] = static_cast<uint32_t>(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,13 +940,27 @@ uint64_t OuterIndex; public: +#ifndef _WIN32 ArrayInitLoopIndex(EvalInfo &Info) : Info(Info), OuterIndex(Info.ArrayInitIndex) { Info.ArrayInitIndex = 0; } ~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.
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<uint32_t>(-1), static_cast<uint32_t>(-1)}; + uint64_t GetArrayInitIndex() { + return (static_cast<uint64_t>(ArrayInitIndex[0]) << 32) + + static_cast<uint64_t>(ArrayInitIndex[1]); + } + void SetArrayInitIndex(uint64_t index) { + ArrayInitIndex[0] = static_cast<uint32_t>(index >> 32); + ArrayInitIndex[1] = static_cast<uint32_t>(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,13 +940,27 @@ uint64_t OuterIndex; public: +#ifndef _WIN32 ArrayInitLoopIndex(EvalInfo &Info) : Info(Info), OuterIndex(Info.ArrayInitIndex) { Info.ArrayInitIndex = 0; } ~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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits