[llvm] r174357 - [Support][ErrorOr] Add support for convertable types.

David Blaikie dblaikie at gmail.com
Wed Feb 6 10:49:32 PST 2013


On Tue, Feb 5, 2013 at 11:11 PM, Andrew Trick <atrick at apple.com> wrote:
> Michael,
>
> -  ErrorOr(const ErrorOr &Other) : IsValid(false) {
> +  template <class OtherT>
> +  ErrorOr(ErrorOr<OtherT> &Other) : IsValid(false) {
>
> I'm not a language guy, but this change prevents clang from using the method as a copy ctor. Hence we fail to acquire the ErrorHolderBase and free it early.
>
> Actually, this change alone hides the copy ctor.
>
> +  template <class OtherT>
> ErrorOr(const ErrorOr &Other) : IsValid(false) {
>
> I'm not sure how to do this the right way, but there should be plenty of other people on the list who can advise.
>
> Note, this is a problem with the non-cxx11 build.

Yep, templated ctors are not copy ctors. You can just provide a normal
non-templated copy ctor alongside the template.

>
> -Andy
>
> On Feb 5, 2013, at 2:53 PM, Andrew Trick <atrick at apple.com> wrote:
>
>> On Feb 5, 2013, at 12:22 AM, Michael J. Spencer <bigcheesegs at gmail.com> wrote:
>>
>>> Author: mspencer
>>> Date: Tue Feb  5 02:22:27 2013
>>> New Revision: 174357
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=174357&view=rev
>>> Log:
>>> [Support][ErrorOr] Add support for convertable types.
>>>
>>> Modified:
>>>   llvm/trunk/include/llvm/Support/ErrorOr.h
>>>   llvm/trunk/unittests/Support/ErrorOrTest.cpp
>>
>> I temporarily reverted this because it's crashing a unit test and blocking the buildbots. I'm not sure yet what the proper workaround should be.
>>
>> -Andy
>>
>> ErrorOr.SimpleValue
>> [       OK ] ErrorOr.SimpleValueSupportTests(65303) malloc: *** error for object 0x100416988: incorrect checksum for freed object - object was probably modified after being freed.
>> *** set a breakpoint in malloc_error_break to debug
>> 0  SupportTests      0x0000000100253195 llvm::sys::PrintStackTrace(__sFILE*) + 37
>> 1  SupportTests      0x0000000100253754 SignalHandler(int) + 676
>> 2  libSystem.B.dylib 0x00007fff870631ba _sigtramp + 26
>> 3  libSystem.B.dylib 0x0000000000004000 _sigtramp + 2029653600
>> 4  libSystem.B.dylib 0x00007fff870e062d szone_error + 519
>> 5  libSystem.B.dylib 0x00007fff87007a46 tiny_malloc_from_free_list + 715
>> 6  libSystem.B.dylib 0x00007fff87006abd szone_malloc_should_clear + 242
>> 7  libSystem.B.dylib 0x00007fff8700698a malloc_zone_malloc + 82
>> 8  libSystem.B.dylib 0x00007fff87004c88 malloc + 44
>> 9  libstdc++.6.dylib 0x00007fff84046f05 operator new(unsigned long) + 97
>> 10 libstdc++.6.dylib 0x00007fff8402c4d1 std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) + 121
>> 11 libstdc++.6.dylib 0x00007fff8402d052 std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) + 44
>> 12 libstdc++.6.dylib 0x00007fff8402d1d5 std::string::reserve(unsigned long) + 71
>> 13 libstdc++.6.dylib 0x00007fff8402ae56 std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int) + 188
>> 14 libstdc++.6.dylib 0x00007fff84025a19 std::ostream::put(char) + 97
>> 15 SupportTests      0x0000000100132104 testing::internal::StringStreamToString(std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >*) + 500
>> 16 SupportTests      0x0000000100145b9a testing::internal::String testing::internal::StreamableToString<long long>(long long const&) + 698
>> 17 SupportTests      0x000000010013bf0f testing::internal::PrettyUnitTestResultPrinter::OnTestEnd(testing::TestInfo const&) + 383
>> 18 SupportTests      0x000000010013d294 testing::internal::TestEventRepeater::OnTestEnd(testing::TestInfo const&) + 84
>>
>> -Andy
>>
>>>
>>> Modified: llvm/trunk/include/llvm/Support/ErrorOr.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ErrorOr.h?rev=174357&r1=174356&r2=174357&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Support/ErrorOr.h (original)
>>> +++ llvm/trunk/include/llvm/Support/ErrorOr.h Tue Feb  5 02:22:27 2013
>>> @@ -162,6 +162,7 @@ public:
>>> /// T cannot be a rvalue reference.
>>> template<class T>
>>> class ErrorOr {
>>> +  template <class OtherT> friend class ErrorOr;
>>>  static const bool isRef = is_reference<T>::value;
>>>  typedef ReferenceStorage<typename remove_reference<T>::type> wrap;
>>>
>>> @@ -198,7 +199,8 @@ public:
>>>    new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val));
>>>  }
>>>
>>> -  ErrorOr(const ErrorOr &Other) : IsValid(false) {
>>> +  template <class OtherT>
>>> +  ErrorOr(ErrorOr<OtherT> &Other) : IsValid(false) {
>>>    // Construct an invalid ErrorOr if other is invalid.
>>>    if (!Other.IsValid)
>>>      return;
>>> @@ -227,7 +229,8 @@ public:
>>>  }
>>>
>>> #if LLVM_HAS_RVALUE_REFERENCES
>>> -  ErrorOr(ErrorOr &&Other) : IsValid(false) {
>>> +  template <class OtherT>
>>> +  ErrorOr(ErrorOr<OtherT> &&Other) : IsValid(false) {
>>>    // Construct an invalid ErrorOr if other is invalid.
>>>    if (!Other.IsValid)
>>>      return;
>>> @@ -311,7 +314,6 @@ private:
>>>    return &Val->get();
>>>  }
>>>
>>> -protected:
>>>  storage_type *get() {
>>>    assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
>>>    assert(!HasError && "Cannot get value when an error exists!");
>>>
>>> Modified: llvm/trunk/unittests/Support/ErrorOrTest.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ErrorOrTest.cpp?rev=174357&r1=174356&r2=174357&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/unittests/Support/ErrorOrTest.cpp (original)
>>> +++ llvm/trunk/unittests/Support/ErrorOrTest.cpp Tue Feb  5 02:22:27 2013
>>> @@ -53,6 +53,17 @@ TEST(ErrorOr, Types) {
>>>  EXPECT_EQ(3, **t3());
>>> #endif
>>> }
>>> +
>>> +struct B {};
>>> +struct D : B {};
>>> +
>>> +TEST(ErrorOr, Covariant) {
>>> +  ErrorOr<B*> b(ErrorOr<D*>(0));
>>> +
>>> +#if LLVM_HAS_CXX11_STDLIB
>>> +  ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(0));
>>> +#endif
>>> +}
>>> } // end anon namespace
>>>
>>> struct InvalidArgError {
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list