[llvm-bugs] [Bug 38729] New: std::make_shared will fail to compile for class of type T which overloads operator& and returns something other than T*

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Aug 27 14:53:37 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=38729

            Bug ID: 38729
           Summary: std::make_shared will fail to compile for class of
                    type T which overloads operator& and returns something
                    other than T*
           Product: libc++
           Version: unspecified
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: All Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: jsmrcina at microsoft.com
                CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com

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>
>::get' requested here
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:

https://github.com/llvm-mirror/libcxx/blob/e45e0640b647ce475f7a1592b16a5b876b4740f1/include/memory#L3685

_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&.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180827/229700bc/attachment.html>


More information about the llvm-bugs mailing list