<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>