Skip to content

Commit

Permalink
Adapt to MSVC difference in behavior in initializing non-aggregates
Browse files Browse the repository at this point in the history
Testcase:

 struct A
 {
     A() = default;
     constexpr A(int v) :i(v) {}
     int i;
 };
 extern const A y[1] = {};

In our case, A = std::atomic<int> 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:
microsoft/STL#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
Pick-to: 5.12
Change-Id: I3d4f433ff6e94fd390a9fffd161b4a7e8c1867b1
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
  • Loading branch information
thiagomacieira committed Jun 30, 2020
1 parent 10a2f38 commit b619f2a
Showing 1 changed file with 6 additions and 9 deletions.
15 changes: 6 additions & 9 deletions src/corelib/tools/qarraydata.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2019 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.
Expand Down Expand Up @@ -149,19 +149,16 @@ qCalculateGrowingBlockSize(size_t elementCount, size_t elementSize, size_t heade

// End of qtools_p.h implementation

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];
Expand Down

0 comments on commit b619f2a

Please sign in to comment.