@@ -1230,29 +1230,29 @@ class GenericValue {
1230
1230
else {
1231
1231
RAPIDJSON_ASSERT (false ); // see above note
1232
1232
1233
- // Use thread-local storage to prevent races between threads.
1234
- #if defined(_MSC_VER) && _MSC_VER < 1900
1235
- // MSVC 2013 or earlier does not support `thread_local` attribute even in C++11
1236
- // mode.
1237
- #define RAPIDJSON_THREAD_LOCAL __declspec (thread)
1238
- #elif RAPIDJSON_HAS_CXX11
1239
- #define RAPIDJSON_THREAD_LOCAL thread_local
1240
- #elif defined(__GNUC__) || defined(__clang__)
1241
- #define RAPIDJSON_THREAD_LOCAL __thread
1242
- #else
1243
- #define RAPIDJSON_THREAD_LOCAL
1244
- #endif
1245
-
1246
1233
#if RAPIDJSON_HAS_CXX11
1247
- // Use static buffer and placement-new to prevent destruction.
1248
- alignas (GenericValue) RAPIDJSON_THREAD_LOCAL static char buffer[sizeof (GenericValue)];
1234
+ // Use thread-local storage to prevent races between threads.
1235
+ // Use static buffer and placement-new to prevent destruction, with
1236
+ // alignas() to ensure proper alignment.
1237
+ alignas (GenericValue) thread_local static char buffer[sizeof (GenericValue)];
1249
1238
return *new (buffer) GenericValue ();
1239
+ #elif defined(_MSC_VER) && _MSC_VER < 1900
1240
+ // There's no way to solve both thread locality and proper alignment
1241
+ // simultaneously.
1242
+ __declspec (thread) static char buffer[sizeof (GenericValue)];
1243
+ return *new (buffer) GenericValue ();
1244
+ #elif defined(__GNUC__) || defined(__clang__)
1245
+ // This will generate -Wexit-time-destructors in clang, but that's
1246
+ // better than having under-alignment.
1247
+ __thread static GenericValue buffer;
1248
+ return buffer;
1250
1249
#else
1251
- // This will generate -Wexit-time-destructors in clang.
1252
- RAPIDJSON_THREAD_LOCAL static GenericValue buffer;
1250
+ // Don't know what compiler this is, so don't know how to ensure
1251
+ // thread-locality.
1252
+ static GenericValue buffer;
1253
1253
return buffer;
1254
1254
#endif
1255
- }
1255
+ }
1256
1256
}
1257
1257
template <typename SourceAllocator>
1258
1258
const GenericValue& operator [](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast <GenericValue&>(*this )[name]; }
0 commit comments