diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Support/ErrorOr.h | 40 | ||||
-rw-r--r-- | llvm/lib/Object/Binary.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Object/SymbolicFile.cpp | 3 | ||||
-rw-r--r-- | llvm/unittests/Support/ErrorOrTest.cpp | 31 |
4 files changed, 61 insertions, 16 deletions
diff --git a/llvm/include/llvm/Support/ErrorOr.h b/llvm/include/llvm/Support/ErrorOr.h index 6f164805b5c..68ab94609c1 100644 --- a/llvm/include/llvm/Support/ErrorOr.h +++ b/llvm/include/llvm/Support/ErrorOr.h @@ -115,19 +115,19 @@ public: } template <class OtherT> - ErrorOr(const ErrorOr<OtherT> &Other) { + ErrorOr( + const ErrorOr<OtherT> &Other, + typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * = + nullptr) { copyConstruct(Other); } - ErrorOr &operator =(const ErrorOr &Other) { - copyAssign(Other); - return *this; - } - template <class OtherT> - ErrorOr &operator =(const ErrorOr<OtherT> &Other) { - copyAssign(Other); - return *this; + explicit ErrorOr( + const ErrorOr<OtherT> &Other, + typename std::enable_if< + !std::is_convertible<OtherT, const T &>::value>::type * = nullptr) { + copyConstruct(Other); } ErrorOr(ErrorOr &&Other) { @@ -135,17 +135,29 @@ public: } template <class OtherT> - ErrorOr(ErrorOr<OtherT> &&Other) { + ErrorOr( + ErrorOr<OtherT> &&Other, + typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * = + nullptr) { moveConstruct(std::move(Other)); } - ErrorOr &operator =(ErrorOr &&Other) { - moveAssign(std::move(Other)); + // This might eventually need SFINAE but it's more complex than is_convertible + // & I'm too lazy to write it right now. + template <class OtherT> + explicit ErrorOr( + ErrorOr<OtherT> &&Other, + typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * = + nullptr) { + moveConstruct(std::move(Other)); + } + + ErrorOr &operator=(const ErrorOr &Other) { + copyAssign(Other); return *this; } - template <class OtherT> - ErrorOr &operator =(ErrorOr<OtherT> &&Other) { + ErrorOr &operator=(ErrorOr &&Other) { moveAssign(std::move(Other)); return *this; } diff --git a/llvm/lib/Object/Binary.cpp b/llvm/lib/Object/Binary.cpp index d23ee590569..d9fef8be8e1 100644 --- a/llvm/lib/Object/Binary.cpp +++ b/llvm/lib/Object/Binary.cpp @@ -63,7 +63,8 @@ ErrorOr<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer, case sys::fs::file_magic::bitcode: return ObjectFile::createSymbolicFile(Buffer, Type, Context); case sys::fs::file_magic::macho_universal_binary: - return MachOUniversalBinary::create(Buffer); + return ErrorOr<std::unique_ptr<Binary>>( + MachOUniversalBinary::create(Buffer)); case sys::fs::file_magic::unknown: case sys::fs::file_magic::windows_resource: // Unrecognized object file format. diff --git a/llvm/lib/Object/SymbolicFile.cpp b/llvm/lib/Object/SymbolicFile.cpp index f8dd4b33a39..17624a307ec 100644 --- a/llvm/lib/Object/SymbolicFile.cpp +++ b/llvm/lib/Object/SymbolicFile.cpp @@ -33,7 +33,8 @@ ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile( switch (Type) { case sys::fs::file_magic::bitcode: if (Context) - return IRObjectFile::createIRObjectFile(Object, *Context); + return ErrorOr<std::unique_ptr<SymbolicFile>>( + IRObjectFile::createIRObjectFile(Object, *Context)); // Fallthrough case sys::fs::file_magic::unknown: case sys::fs::file_magic::archive: diff --git a/llvm/unittests/Support/ErrorOrTest.cpp b/llvm/unittests/Support/ErrorOrTest.cpp index d76e7d62421..82bbe090960 100644 --- a/llvm/unittests/Support/ErrorOrTest.cpp +++ b/llvm/unittests/Support/ErrorOrTest.cpp @@ -60,5 +60,36 @@ TEST(ErrorOr, Covariant) { ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(nullptr)); b1 = ErrorOr<std::unique_ptr<D> >(nullptr); + + ErrorOr<std::unique_ptr<int>> b2(ErrorOr<int *>(nullptr)); + ErrorOr<int *> b3(nullptr); + ErrorOr<std::unique_ptr<int>> b4(b3); } + +// ErrorOr<int*> x(nullptr); +// ErrorOr<std::unique_ptr<int>> y = x; // invalid conversion +static_assert( + !std::is_convertible<const ErrorOr<int *> &, + ErrorOr<std::unique_ptr<int>>>::value, + "do not invoke explicit ctors in implicit conversion from lvalue"); + +// ErrorOr<std::unique_ptr<int>> y = ErrorOr<int*>(nullptr); // invalid +// // conversion +static_assert( + !std::is_convertible<ErrorOr<int *> &&, + ErrorOr<std::unique_ptr<int>>>::value, + "do not invoke explicit ctors in implicit conversion from rvalue"); + +// ErrorOr<int*> x(nullptr); +// ErrorOr<std::unique_ptr<int>> y; +// y = x; // invalid conversion +static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>, + const ErrorOr<int *> &>::value, + "do not invoke explicit ctors in assignment"); + +// ErrorOr<std::unique_ptr<int>> x; +// x = ErrorOr<int*>(nullptr); // invalid conversion +static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>, + ErrorOr<int *> &&>::value, + "do not invoke explicit ctors in assignment"); } // end anon namespace |