llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.36k stars 12.14k forks source link

Wrong return type for operator() of "diamond functors" #22974

Closed 7318a870-54d1-4d9b-a5cf-8ce660251251 closed 9 years ago

7318a870-54d1-4d9b-a5cf-8ce660251251 commented 9 years ago
Bugzilla Link 22600
Resolution FIXED
Resolved on Feb 25, 2015 06:21
Version unspecified
OS All
CC @mclow

Extended Description

Currently, all of the transparent operator functors in returns auto. For example:

template <> struct _LIBCPP_TYPE_VIS_ONLY plus { template <class _T1, class _T2> _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& u) const { return _VSTD::forward<_T1>(t) + _VSTD::forward<_T2>(__u); } typedef void is_transparent; };

The standard depicts them as having a trailing return type of decltype(/ the returned expression /), which is equivalent to returning decltype(auto) except for SFINAE considerations.

mclow commented 9 years ago

Fixed in revision 230484.

mclow commented 9 years ago

Proposed fix up at: http://reviews.llvm.org/D7862

7318a870-54d1-4d9b-a5cf-8ce660251251 commented 9 years ago

The follow code compiles using libstdc++ but not libc++:

include

include

struct A { A() {} A(const A&) = delete; const A& operator+(const A&) const { return *this; } };

int main() { A() + A(); // ok std::plus<>()(A(), A()); // 1 std::result_of<std::plus<>(int, int)> bar; // 2 }

Line #​1 fails to compile because auto deduces a return type of A, but A is not copyable or movable. Using decltype here would have deduced const A&.

Line #​2 compiles in libstdc++ - as adding two pointers is ill-formed, the operator() is SFINAE'd out, causing std::result_of<std::plus<>(int, int)> to be an empty struct. It causes a hard error in libc++.

mclow commented 9 years ago

Do you have a sample that demonstrates the difference?

7318a870-54d1-4d9b-a5cf-8ce660251251 commented 9 years ago

assigned to @mclow