From 9115c841030be5a0d937b62a051d9b666b95131a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 23 Jun 2020 13:51:32 -0700 Subject: [PATCH] Adapt to MSVC difference in behavior in initializing non-aggregates Testcase: struct A { A() = default; constexpr A(int v) :i(v) {} int i; }; extern const A y[1] = {}; In our case, A = std::atomic and y = shared_null. With GCC, ICC, and Clang that "y" variable is value-initialized at static initialization time, and no dynamic initialization code is generated. However, with MSVC, because A is not an aggregate, the default constructor isn't constexpr (it leaves A::i uninitialized) so "y" must be dynamically initialized. That leads to Static Initialization Order Fiasco. This seems to be a regression in the MSVC 2019 16.6 STL: https://github.com/microsoft/STL/issues/661 The solution is simple: call the constexpr constructor. Code is different in 6.0 so sending separately from 5.x. Fixes: QTBUG-71548 Task-number: QTBUG-59721 Change-Id: I3d4f433ff6e94fd390a9fffd161b4a7e8c1867b1 Reviewed-by: Kai Koehne (cherry picked from commit b619f2a26ea2ab56e18a3f9a8b635f96fc479563) Reviewed-by: Thiago Macieira --- src/corelib/tools/qarraydata.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index a04536b18be..6aa1ae0bcf0 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2020 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -46,19 +46,16 @@ QT_BEGIN_NAMESPACE -QT_WARNING_PUSH -QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") - const QArrayData QArrayData::shared_null[2] = { { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, sizeof(QArrayData) }, // shared null - /* zero initialized terminator */}; + { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 } /* zero initialized terminator */ +}; static const QArrayData qt_array[3] = { { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, sizeof(QArrayData) }, // shared empty { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, sizeof(QArrayData) }, // unsharable empty - /* zero initialized terminator */}; - -QT_WARNING_POP + { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 } /* zero initialized terminator */ +}; static const QArrayData &qt_array_empty = qt_array[0]; static const QArrayData &qt_array_unsharable_empty = qt_array[1];