Skip to content

atomic::compare_exchange returns wrong value #30023

@KernelAddress

Description

@KernelAddress
Bugzilla Link 30675
Version trunk
OS Linux
CC @chandlerc,@eugenis,@kcc,@mclow,@rengolin

Extended Description

llvm/clang/libc++ are on rev 271514.

Test is:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <atomic>

template<int kSize>
struct MyStruct {
  char data[kSize];

  explicit MyStruct(char v = 0) noexcept {
    memset(&data[0], v, sizeof(data));
  }

  bool operator == (const MyStruct &other) const {
    return memcmp(&data[0], &other.data[0], sizeof(data)) == 0;
  }

  bool operator != (const MyStruct &other) const {
    return !(*this == other);
  }

  operator int() const {
    return data[0];
  }
};

int main() {
  typedef MyStruct<6> T;
  std::atomic<T> a(T(0));
  T cmp(17);
  if (a.compare_exchange_strong(cmp, T(18), std::memory_order_acquire)) {
    fprintf(stderr, "%d: bad atomic value %d\n", __LINE__, (int)cmp);
    exit(1);
  }
  if (cmp != T(0)) {
    fprintf(stderr, "%d: bad atomic value %d\n", __LINE__, (int)cmp);
    exit(1);
  }
}

The test works with libstdc++:

$ bin/clang++ /tmp/atomic.cc -std=c++11 -latomic && ./a.out

But fails with libc++:

$ bin/clang++ /tmp/atomic.cc -std=c++11 -stdlib=libc++ -latomic && LD_LIBRARY_PATH=./lib/ ./a.out
36: bad atomic value 17

Metadata

Metadata

Assignees

Labels

bugzillaIssues migrated from bugzillac++11clang:codegenIR generation bugs: mangling, exceptions, etc.confirmedVerified by a second party

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions