boostorg / boostorg/boost-ci

Upgrade s390x job to clang 13

Open
#348 1 comment 0 reactions 1 assignee Claimed by @jeking3 View on GitHub
Dominant language
Shell
Stars
17
Forks
22
PR merge metrics
No merged PRs in 30d

Description

OpenMethod fails some of the tests on the posix GHA job (bigendian-s390x, yes, clang, 17, ubuntu-22.04, no, fedora, 34, s390x). Claude traces it (convincingly, see below) to a clang 12 bug on all big-endian platforms. Please upgrade to clang 13.

```
The root cause: a clang ≤ 12 big-endian codegen bug

Ruling out the layers one by one (symbols/exports correct; LD_DEBUG=bindings shows ld.so binding the DSO's fn and guard to the exe correctly), the smoking gun was in the disassembly
of the guard code itself:

asm
llc %r0, 0(%r1) ; CHECK: load byte 0 of the guard
mvghi 0(%r1), 1 ; SET: store 8-byte immediate 1

For non-local guarded variables (template statics take clang's unsynchronized guard path), clang 12 emits the check as load byte 0 but the set as store i64 1. On big-endian, the 0x01
lands in byte 7 — byte 0 stays 0 forever, so every DSO's initializer believes the guard is unset and re-runs the constructor on the correctly-unified object. Debug: second push_back
on the same method_info → your assert. Release: odr_check::inc re-runs → count == 2 → "conflicting definitions" — a false positive, because the detector itself is built on the same
broken primitive. Little-endian is immune (byte 0 of i64 1 is 0x01); gcc is immune (byte store + GNU_UNIQUE).

Confirmed in source: clang 12's ItaniumCXXABI.cpp:2475 does CreateStore(ConstantInt::get(guardTy, 1)); fixed in clang 13 by LLVM commit 6b1e2fc893 ("Manipulate the first byte of
guard variable type in both load and store operation", 2021-02-08) — verified present in release/12.x and gone in 13.x through 18.x.
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.