[PATCH] D34873: Fix miscompiled 32bit binaries by mingw

Ivan Donchevskii via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 31 01:37:14 PDT 2017


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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34873.108878.patch
Type: text/x-patch
Size: 2902 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170731/90c8a7d7/attachment.bin>


More information about the cfe-commits mailing list