[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #15 from Jiang An --- (In reply to Arthur O'Dwyer from comment #11) > @jwakely, I propose that this issue should be recategorized as a compiler > bug. (And I'm also voting effectively "NAD" on LWG3967.) Hmm... IMO given the current specification seems to be ambiguous, the status quo of GCC's __is_nothrow_* can be considered conforming even though they're obviously buggy (inconsistent).
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 Andrew Pinski changed: What|Removed |Added Resolution|--- |DUPLICATE Status|UNCONFIRMED |RESOLVED --- Comment #14 from Andrew Pinski --- Since it was agreeded as a dup, let's mark it as such. *** This bug has been marked as a duplicate of bug 100470 ***
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #13 from Arthur O'Dwyer --- (In reply to Andrew Pinski from comment #12) > I suspect this is a dup of bug 100470 then. Yep, I agree. My previous comment was a longwinded version of jwakely's https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100470#c1 :)
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #12 from Andrew Pinski --- I suspect this is a dup of bug 100470 then.
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 Arthur O'Dwyer changed: What|Removed |Added CC||arthur.j.odwyer at gmail dot com --- Comment #11 from Arthur O'Dwyer --- Jiang An wrote: > I've mailed the LWG Chair to submit an LWG issue that requests clarification > of "is known not to throw any exceptions". > FYI, there's at least one library implementor holding the same opinion as > yours. > https://quuxplusone.github.io/blog/2023/04/17/noexcept-false-equals-default/ Quuxplusone here. :) I don't think this is LWG jurisdiction at all. This isn't even a bug in libstdc++'s . This is purely a GCC core-language bug. GCC's builtin __is_nothrow_constructible(T, T&&) simply returns the wrong answer when the selected constructor is "trivial, but noexcept(false)." // https://godbolt.org/z/5szW6KeWq struct C { C(C&&) noexcept(false) = default; }; static_assert(!__is_nothrow_constructible(C, C&&)); // GCC+EDG fail; Clang+MSVC succeed Notice that the builtin returns the correct answer when the selected constructor is "non-trivial, noexcept(false), but still defaulted so we know it can't throw." The problem is specifically with *trivial* ctors. @jwakely, I propose that this issue should be recategorized as a compiler bug. (And I'm also voting effectively "NAD" on LWG3967.)
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #10 from Jiang An --- https://cplusplus.github.io/LWG/issue3967
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #9 from Jiang An --- (In reply to Nikolas Klauser from comment #8) > I agree that the wording is a bit ambiguous, but GCC should decide on one > of them instead of returning different results between the type trait > builtins and the noexcept operator. The result of noexcept operator is unambiguously specified in the standard and GCC is already correct. So the suggestion is equivalent to detecting the exception specifications only. I've mailed the LWG Chair to submit an LWG issue that requests clarification of "is known not to throw any exceptions". FYI, there's at least one library implementor holding the same opinion as yours. https://quuxplusone.github.io/blog/2023/04/17/noexcept-false-equals-default/
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #8 from Nikolas Klauser --- I agree that the wording is a bit ambiguous, but GCC should decide on one of them instead of returning different results between the type trait builtins and the noexcept operator.
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #7 from Jiang An --- The standard wording says "... is known not to throw any exceptions ([expr.unary.noexcept])" for is_nothrow_* traits. It's arguably that the wording is ambiguous - when the defaulted function is marked `noexcept(false)` but the implicit exception specification would be `noexcept(true)`, it may still be possible to say the operation "is known not to throw any exceptions". But the reference to [expr.unary.noexcept] seemly suggests that the results consistent with noexcept operator should be used. This may deserve an LWG issue.
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #6 from Nikolas Klauser --- Is there any update on this?
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #5 from Nikolas Klauser --- (In reply to Jonathan Wakely from comment #4) > (In reply to Nikolas Klauser from comment #2) > > static_assert(!noexcept(std::declval(; > > > > is fine. > > It doesn't look fine to me! Is there a 'CopyConstructible(' missing? > > The reproducer for comment 3 would be helpful. Oops! Yes, there is a CopyConstructible() missing around the declval. Here is the reproducer for comment #3 (Godbolt: https://godbolt.org/z/fYEzME3b8): #include #include struct S { S() noexcept(false) = default; S(const S&) noexcept(false) = default; S(S&&) noexcept(false) = default; S& operator=(const S&) noexcept(false) = default; S& operator=(S&&) noexcept(false) = default; }; static_assert(!std::is_nothrow_default_constructible_v); static_assert(!std::is_nothrow_copy_constructible_v); static_assert(!std::is_nothrow_move_constructible_v); static_assert(!std::is_nothrow_copy_assignable_v); static_assert(!std::is_nothrow_move_assignable_v); static_assert(!noexcept(S())); static_assert(!noexcept(S(std::declval(; static_assert(!noexcept(S(std::declval(; static_assert(!noexcept(std::declval() = std::declval())); static_assert(!noexcept(std::declval() = std::declval())); I think the relevant part in the standard is https://eel.is/c++draft/except.spec, which states that anything marked noexcept(false) is potentially throwing.
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #4 from Jonathan Wakely --- (In reply to Nikolas Klauser from comment #2) > static_assert(!noexcept(std::declval(; > > is fine. It doesn't look fine to me! Is there a 'CopyConstructible(' missing? The reproducer for comment 3 would be helpful.
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #3 from Nikolas Klauser --- I did some more digging and it looks like nobody can agree on what the right result is. This is the result of the question whether the listed operation on struct S { noexcept(false) = default; } is noexcept: operation| is the type_trait used? | GCC | Clang | MSVC -+-+-+---+- default construction | yes | yes | no| no | no | yes | no| yes copy construction| yes | yes | no| no | no | no | no| yes move construction| yes | yes | no| no | no | no | no| yes copy assignment | yes | yes | no| yes | no | yes | no| yes move assignment | yes | yes | no| yes | no | yes | no| yes When the type trait is not used that means noexcept(operation) is used. So GCC and MSVC seem to agree on the assignments that they should always be noexcept, but disagree with themselves and each other on construction while clang always considers things marked noexcept(false) to not be noexcept. Do you have any suggestions how we should continue here? Clearly there is somewhere a bug; both in GCC and MSVC (since they disagree with themselves) and maybe clang.
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #2 from Nikolas Klauser --- (In reply to Jonathan Wakely from comment #1) > The noexcept specifier is wrong, but is ignored. The implicitly defined copy > constructor is noexcept, so the trait gives the right answer. static_assert(!noexcept(std::declval(; is fine. So one of them must be wrong.
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #1 from Jonathan Wakely --- The noexcept specifier is wrong, but is ignored. The implicitly defined copy constructor is noexcept, so the trait gives the right answer.