<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - std::make_shared will fail to compile for class of type T which overloads operator& and returns something other than T*"
   href="https://bugs.llvm.org/show_bug.cgi?id=38729">38729</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::make_shared will fail to compile for class of type T which overloads operator& and returns something other than T*
          </td>
        </tr>

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

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

        <tr>
          <th>Hardware</th>
          <td>All
          </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>jsmrcina@microsoft.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Tested using Clang 5.0 with C++17 and libstdc++. Also verified that issue is
still in master.

The following minimal example fails to compile due to the operator& overload
inside TestBugB returning something other than the address of TestBugB.

class TestBugA
{
    int x;
};

class TestBugB
{
public:
    TestBugA *operator&()
    {
        return &_a;
    }

private:
    TestBugA _a;
};

class TestBugC
{
    TestBugC()
    {
        std::shared_ptr<TestBugB> b = std::make_shared<TestBugB>(TestBugB());
    }
};

Compiler error emitted:

1>C:\android\android-ndk-r16b\sources\cxx-stl\llvm-libc++\include\memory(3597,34):
error : cannot initialize return object of type 'TestBugB *' with an rvalue of
type 'TestBugA *'
1>    _Tp* get() _NOEXCEPT {return &__data_.second();}
1>                                 ^~~~~~~~~~~~~~~~~

1>C:\android\android-ndk-r16b\sources\cxx-stl\llvm-libc++\include\memory(4226,33):
 note: in instantiation of member function
'std::__ndk1::__shared_ptr_emplace<TestBugB, std::__ndk1::allocator<TestBugB>
<span class="quote">>::get' requested here</span >
1>    __r.__ptr_ = __hold2.get()->get();
1>                                ^

1>C:\android\android-ndk-r16b\sources\cxx-stl\llvm-libc++\include\memory(4594,29):
 note: in instantiation of function template specialization
'std::__ndk1::shared_ptr<TestBugB>::make_shared<TestBugB>' requested here
1>    return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
1>                            ^

1> note: in instantiation of function template specialization
'std::__ndk1::make_shared<TestBugB, TestBugB>' requested here
1>        std::shared_ptr<TestBugB> b = std::make_shared<TestBugB>(TestBugB());

This appears to be because std::make_shared inside class
__shared_ptr_emplace::get() uses operator& instead of _VSTD::addressof(). Issue
appears to be here:

<a href="https://github.com/llvm-mirror/libcxx/blob/e45e0640b647ce475f7a1592b16a5b876b4740f1/include/memory#L3685">https://github.com/llvm-mirror/libcxx/blob/e45e0640b647ce475f7a1592b16a5b876b4740f1/include/memory#L3685</a>

_Tp* get() _NOEXCEPT {return &__data_.second();}

Changing this as such resolves the problem:

_Tp* get() _NOEXCEPT {return _VSTD::addressof(__data_.second());}

Our real-world example of this is an RAII type which returns a pointer to the
handle memory underlying the resource via operator&.</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>