<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - atomic::compare_exchange returns wrong value"
   href="https://llvm.org/bugs/show_bug.cgi?id=30675">30675</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>atomic::compare_exchange returns wrong value
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>release blocker
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>dvyukov@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>