On Thu, Feb 08, 2024 at 04:53:45PM -0500, Jason Merrill wrote: > On 2/8/24 11:51, Marek Polacek wrote: > > On Thu, Feb 08, 2024 at 08:49:28AM -0500, Patrick Palka wrote: > > > On Wed, 7 Feb 2024, Marek Polacek wrote: > > > > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > > > > > > > -- >8 -- > > > > Here the problem is that we give hard errors while substituting > > > > template parameters during overload resolution of is_throwable > > > > which has an invalid throw in decltype. > > > > > > > > The backtrace shows that fn_type_unification -> instantiate_template > > > > -> tsubst* passes complain=0 as expected, but build_throw doesn't > > > > have a complain parameter. So let's add one. Also remove a redundant > > > > local variable which I should have removed in my P2266 patch. > > > > > > > > But there's still something not quite clear to me. I claim that 'b' > > > > in the testcase should evaluate to false since the first overload ought > > > > to have been discarded. EDG 6.6 agrees, but clang++, msvc, and icx > > > > evaluate > > > > it to true. Who's right? > > I think it should be true since P1155, which we implement in C++20 mode and > above (or rather, we implement the sequel P2266); since then we implicitly > move from the function parameter. > > The patch looks good except that we should test this expected value.
I could add #if __cplusplus >= 202002L static_assert (b, "move from the function parameter"); #else static_assert (!b, "no move from the function parameter"); #endif but that's going to fail for C++20 and above. I wonder if this is the second half of the problem in 113789? I could comment the first static_assert and add a FIXME if that sounds good? > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae69.C > > @@ -0,0 +1,16 @@ > > +// PR c++/98388 > > +// { dg-do compile { target c++11 } } > > + > > +struct moveonly { > > + moveonly() = default; > > + moveonly(moveonly&&) = default; > > +}; > > + > > +template<class T> > > +constexpr auto is_throwable(T t) -> decltype(throw t, true) { > > + return true; > > +} > > +template<class T> > > +constexpr bool is_throwable(...) { return false; } > > + > > +constexpr bool b = is_throwable<moveonly>(moveonly{}); Marek