Skip to content

ABI mismatch between MSVC and Clang when returning std::pair on Windows ARM64 #86384

Closed
@triplef

Description

@triplef

Using Clang 18.1.2 WoA on Windows ARM64 results in a failed assertion when adding more than 2 items to a QList due to the assertion Q_ASSERT(!data || !data->isShared()) failing in QArrayData::reallocateUnaligned. We reproduced the issue with both Clang 17 and 18 and Qt 6.5, 6.6, and 6.7.

QList<QString> list;
list.append("ONE");
list.append("TWO");
list.append("THREE"); // CRASH

In this debug session the value of the data pointer changes by 0x10 when calling ArrayData::reallocateUnaligned():

  • 0x000002b224a0bdb0 before reallocateUnaligned()
  • 0x000002b224a0bdc0 in reallocateUnaligned()

This pointer misalignment causes an invalid value for ref_, causing isShared() to return true.

Before:
debug-1

After:
debug-2

We submitted the bug to Qt and got the following feedback:

QTypedArrayData is-a QArrayData so the compiler is required to adjust the pointer to the base sub-object when casting. However, in this case, we expect and require that adjustment to be zero. QTypedArrayData adds no other members, so it has exactly the same size and alignment requirements as QArrayData. In fact, we actually static_assert the size equality in one of the two screenshots.
I actually don't think the issue is the adjustment of the base sub-object. This appears to be a codegen issue in selecting registers. Look at dataPointer at 0x18, which is not a valid pointer, but is sizeof(QString), the next parameter. objectSize is listed as 3, which is not a valid size for QString, but is a valid flag combination. The 0x10 difference between caller and callee is explained by the fact that it is also the difference between data and dataPointer.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions