[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 --- Comment #8 from Jonathan Wakely --- Author: redi Date: Fri Jan 22 21:15:41 2016 New Revision: 232748 URL: https://gcc.gnu.org/viewcvs?rev=232748=gcc=rev Log: Constrain std::valarray functions and operators PR libstdc++/69116 * include/bits/valarray_before.h (__fun, __fun_with_valarray): Only define result_type for types which can be safely used with valarrays. * testsuite/26_numerics/valarray/69116.cc: New. Added: trunk/libstdc++-v3/testsuite/26_numerics/valarray/69116.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/bits/valarray_before.h
[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 Jonathan Wakely changed: What|Removed |Added Component|c++ |libstdc++ --- Comment #6 from Jonathan Wakely --- OK thanks for looking, I'll try constraining the valarray operator overloads.
[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 --- Comment #7 from Jonathan Wakely --- The problem overload is this one: template inline _Expr<_BinClos<__shift_left, _Constant, _ValArray, _Tp, _Tp>, typename __fun<__shift_left, _Tp>::result_type> operator <<(const _Tp& __t, const valarray<_Tp>& __v) { typedef _BinClos<__shift_left, _Constant, _ValArray, _Tp, _Tp> _Closure; typedef typename __fun<__shift_left, _Tp>::result_type _Rt; return _Expr<_Closure, _Rt>(_Closure(__t, __v)); } That deduces _Tp as x and so tries to instantiate valarray to see if __v can be initialized from std::endl, which causes the "invalid abstract return type" outside the immediate context. It can be fixed using enable_if (or __gnu_cxx::__enable_if since this is C++98 code) to reject invalid types for valarray, maybe using __is_abstract. I just need to figure out the best place to put it, and how many of the other overloaded operators are affected. It might make sense to make the first argument a non-deduced context, so we only use this operator when the RHS is really a valarray, rather than matching for anything on the LHS and then trying to convert the RHS to a valarray. I don't know if that would break real code using valarray.
[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 Richard Biener changed: What|Removed |Added Priority|P3 |P2 Version|unknown |5.3.0
[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 Jonathan Wakely changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |redi at gcc dot gnu.org
[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 Andrew Pinski changed: What|Removed |Added Target Milestone|--- |4.9.4
[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 --- Comment #2 from TC --- I don't think this has anything to do with `end`. Consider the following code: #include template struct foo { T f(); void g(T); }; template void operator<<(const T&, const foo&) {} struct x : public std::ostream { virtual void flush() = 0; }; void bar(x& os) { os << std::endl; } I don't have access to 4.8.0, but this compiles on 4.7.3 and fails on 4.8.1+. (In the case, std::operator<<(const T&, const valarray&) is picked up by ADL.) Deduction for this operator<< function template succeeds: `T` is deduced to be `x` from the left operand; the right operand is a non-deduced context because the supplied argument names a function template. Then substitution takes place, and we instantiate valarray (whose definition is needed to decide if it can be constructed from std::endl), which triggers a hard error because you can't return or take an abstract type by value. This is not diagnosed in GCC 4.7.3, likely due to PR51184.
[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 --- Comment #3 from Andrew Pinski --- (In reply to TC from comment #2) > Deduction for this operator<< function template succeeds: `T` is deduced to > be `x` from the left operand; the right operand is a non-deduced context > because the supplied argument names a function template. Then substitution > takes place, and we instantiate valarray (whose definition is needed to > decide if it can be constructed from std::endl), which triggers a hard error > because you can't return or take an abstract type by value. This is not > diagnosed in GCC 4.7.3, likely due to PR51184. Hmm, there is a SFINAE issue here then. We should reduce this further. A simple reduction based on the description works still: template struct foo { T f(); void g(T); }; template void operator<<(const T&, const foo&) {} template void operator<<(const T&, void (*)(void)) {} void endl(int); void endl(void); struct x { virtual void flush() = 0; }; void bar(x& os) { os << endl; } --- CUT --- Also I had confused end and endl earlier which is why I had messed up.
[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 Jonathan Wakely changed: What|Removed |Added Keywords||rejects-valid Status|UNCONFIRMED |NEW Last reconfirmed||2016-01-05 Known to work||4.7.3 Summary|compile error when |[4.9/5/6 Regression] |including valarray |compile error when ||including valarray Ever confirmed|0 |1
[Bug libstdc++/69116] [4.9/5/6 Regression] compile error when including valarray
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69116 --- Comment #1 from Andrew Pinski --- It is trying to instantiate one of the std::end with valarray Like: template inline const _Tp* end(const valarray<_Tp>& __va) { return std::__addressof(__va[0]) + __va.size(); } This does not look right.