<html>
    <head>
      <base href="http://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 --- - Strong enums not shareable between C++ / ObjC++"
   href="http://llvm.org/bugs/show_bug.cgi?id=22423">22423</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Strong enums not shareable between C++ / ObjC++
          </td>
        </tr>

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

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

        <tr>
          <th>Hardware</th>
          <td>Other
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>normal
          </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>pgriess@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu, mclow.lists@gmail.com
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In __config, we have the following

#if !(__has_feature(cxx_strong_enums))
#define _LIBCPP_HAS_NO_STRONG_ENUMS
#endif

...

#if __has_feature(objc_arc_weak)
#define _LIBCPP_HAS_OBJC_ARC_WEAK
#define _LIBCPP_HAS_NO_STRONG_ENUMS
#endif

As a result, C++ code will have strong enums enabled, while ObjC++ code will
not. This causes problems with classes like std::cv_status which are used as
return values, as they become composite types. The ARM calling conventions
(see:
<a href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf">http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf</a>
section 5.4) mandates different calling conventions for such return types. As a
result, if caller and callee have different values for
_LIBCPP_HAS_NO_STRONG_ENUMS, registers are allocated differently (e.g. r0 is
used to specify the address of the return value in one, where as r0 is the
value of 'this' in the other).

Practically, this occurs when instantiating templates in different compilation
units, as the definitions are different, but are coalesced in linking due to
ODR. Linking the two files into a single binary will result in a crash:

  Foo.cpp
    void foo() {
      std::mutex m;
      std::unique_lock<std::mutex> lk(m);
      std::condition_variable cv;
      std::chrono::seconds dur(3);
      cv.wait_for(lk, dur);
    }

  Bar.mm:
    void bar() {
      std::mutex m;
      std::unique_lock<std::mutex> lk(m);
      std::condition_variable cv;
      std::chrono::seconds dur(3);
      cv.wait_for(lk, dur);
    }

  main.c:
    foo();
    bar();

Application developers can work around this by building mixed C++/ObjC++ apps
with _LIBCPP_HAS_NO_STRONG_ENUMS=1.</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>