Pārlūkot izejas kodu

Work around MSVC issue with std::atomic initialization (#4777)

* Work around MSVC issue with std::atomic initialization

MSVC seems to have a bug where it does not use constant initialization
for std::atomic, which ends up causing crashes during initialization.
This change introduces a workaround by putting the std::atomic inside a
union, which causes the compiler to use constant initialization for it.

* Added an AppVeyor test for static linking with MSVC
Adam Cozzette 7 gadi atpakaļ
vecāks
revīzija
885be9c982
2 mainītis faili ar 14 papildinājumiem un 3 dzēšanām
  1. 5 3
      appveyor.yml
  2. 9 0
      src/google/protobuf/generated_message_util.h

+ 5 - 3
appveyor.yml

@@ -1,6 +1,3 @@
-# Only test one combination: "Visual Studio 12 + Win64 + Debug + DLL". We can
-# test more combinations but AppVeyor just takes too long to finish (each
-# combination takes ~15mins).
 platform:
 platform:
   - Win64
   - Win64
 
 
@@ -14,6 +11,11 @@ environment:
       BUILD_DLL: ON
       BUILD_DLL: ON
       UNICODE: ON
       UNICODE: ON
 
 
+    - language: cpp
+      image: Visual Studio 2017
+      BUILD_DLL: OFF
+      UNICODE: ON
+
     - language: csharp
     - language: csharp
       image: Visual Studio 2017
       image: Visual Studio 2017
 
 

+ 9 - 0
src/google/protobuf/generated_message_util.h

@@ -335,7 +335,16 @@ struct LIBPROTOBUF_EXPORT SCCInfoBase {
     kRunning = 1,
     kRunning = 1,
     kUninitialized = -1,  // initial state
     kUninitialized = -1,  // initial state
   };
   };
+#ifndef _MSC_VER
   std::atomic<int> visit_status;
   std::atomic<int> visit_status;
+#else
+  // MSVC doesnt make std::atomic constant initialized. This union trick
+  // makes it so.
+  union {
+    int visit_status_to_make_linker_init;
+    std::atomic<int> visit_status;
+  };
+#endif
   int num_deps;
   int num_deps;
   void (*init_func)();
   void (*init_func)();
   // This is followed by an array  of num_deps
   // This is followed by an array  of num_deps