std::unique_ptr<X> becomes copyable when std::unique_ptr<X> X::Y() exists and is defined inside precompiled header

Originator:planetbeing
Number:rdar://20571459 Date Originated:16-Apr-2015
Status:Open Resolved:
Product:OS X SDK Product Version:Xcode 6.3
Classification: Reproducible:Always
 
Summary:
unique_ptrs are not supposed to be copy-constructable. In a situation where precompiled headers are used and a class that has a method that returns a unique_ptr to itself is defined in the precompiled header, the unique_ptr to that class becomes copy-constructable. However, that copy constructor does not have safe semantics, leading to a future double-free situation.

Steps to Reproduce:
With included files x.hpp and x.cpp:

1. clang++ -std=c++11 -x c++-header x.hpp -o x.hpp.pch
2. clang++ -std=c++11 -include x.hpp x.cpp -o whatever

Expected Results:
Compile should fail with:

x.cpp:4:31: error: call to implicitly-deleted copy constructor of 'std::unique_ptr<TestCase>'
    std::unique_ptr<TestCase> y(x);
                              ^ ~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2515:31: note: copy constructor is implicitly deleted because 'unique_ptr<TestCase, std::__1::default_delete<TestCase> >' has a user-declared move constructor
    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
                              ^
1 error generated.

Actual Results:
Files compile and link without error.

Version:
Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix

OS X 10.10.2

Notes:
The same test works as expected (fails to compile) on "clang version 3.6.0 (tags/RELEASE_360/final)" and "Ubuntu clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)" on Linux, so it appears to be particular to the Apple version.

This problem was encountered while attempting to use folly::IOBuf from Facebook's folly library.

Configuration:


Attachments:

x.hpp:
#include <memory>
class TestCase {
  std::unique_ptr<TestCase> test() { return std::unique_ptr<TestCase>(); };
};

x.cpp:
int main()
{
    std::unique_ptr<TestCase> x;
    std::unique_ptr<TestCase> y(x);

    return 0;
}

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!