public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result
@ 2022-08-13 21:02 nikolasklauser at berlin dot de
  2022-08-13 21:14 ` [Bug libstdc++/106611] " redi at gcc dot gnu.org
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: nikolasklauser at berlin dot de @ 2022-08-13 21:02 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

            Bug ID: 106611
           Summary: std::is_nothrow_copy_constructible returns wrong
                    result
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nikolasklauser at berlin dot de
  Target Milestone: ---

'std::nothrow_copy_constructible' returns the wrong result with a defaulted
copy constructor makred `noexcept(false)`.

Reproducer: (Godbolt: https://godbolt.org/z/3qdf87vd3)

#include <type_traits>

struct CopyConstructible {
  constexpr CopyConstructible() = default;
  constexpr explicit CopyConstructible(int x) : value(x) {}
  CopyConstructible(CopyConstructible const&) noexcept(false) = default;
  CopyConstructible& operator=(CopyConstructible const&) = delete;

  int value = -1;
};

static_assert(!std::is_nothrow_copy_constructible_v<CopyConstructible>); //
static assert fails

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
@ 2022-08-13 21:14 ` redi at gcc dot gnu.org
  2022-08-13 21:23 ` nikolasklauser at berlin dot de
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2022-08-13 21:14 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The noexcept specifier is wrong, but is ignored. The implicitly defined copy
constructor is noexcept, so the trait gives the right answer.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
  2022-08-13 21:14 ` [Bug libstdc++/106611] " redi at gcc dot gnu.org
@ 2022-08-13 21:23 ` nikolasklauser at berlin dot de
  2022-08-14  0:57 ` nikolasklauser at berlin dot de
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: nikolasklauser at berlin dot de @ 2022-08-13 21:23 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #2 from Nikolas Klauser <nikolasklauser at berlin dot de> ---
(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<const CopyConstructible&>())));

is fine. So one of them must be wrong.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
  2022-08-13 21:14 ` [Bug libstdc++/106611] " redi at gcc dot gnu.org
  2022-08-13 21:23 ` nikolasklauser at berlin dot de
@ 2022-08-14  0:57 ` nikolasklauser at berlin dot de
  2022-12-07  0:25 ` nikolasklauser at berlin dot de
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: nikolasklauser at berlin dot de @ 2022-08-14  0:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #3 from Nikolas Klauser <nikolasklauser at berlin dot de> ---
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 {
<operation> 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.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (2 preceding siblings ...)
  2022-08-14  0:57 ` nikolasklauser at berlin dot de
@ 2022-12-07  0:25 ` nikolasklauser at berlin dot de
  2023-01-06 11:10 ` de34 at live dot cn
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: nikolasklauser at berlin dot de @ 2022-12-07  0:25 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #6 from Nikolas Klauser <nikolasklauser at berlin dot de> ---
Is there any update on this?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (3 preceding siblings ...)
  2022-12-07  0:25 ` nikolasklauser at berlin dot de
@ 2023-01-06 11:10 ` de34 at live dot cn
  2023-08-03 23:29 ` nikolasklauser at berlin dot de
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: de34 at live dot cn @ 2023-01-06 11:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

Jiang An <de34 at live dot cn> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |de34 at live dot cn

--- Comment #7 from Jiang An <de34 at live dot cn> ---
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.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (4 preceding siblings ...)
  2023-01-06 11:10 ` de34 at live dot cn
@ 2023-08-03 23:29 ` nikolasklauser at berlin dot de
  2023-08-04  2:28 ` de34 at live dot cn
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: nikolasklauser at berlin dot de @ 2023-08-03 23:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #8 from Nikolas Klauser <nikolasklauser at berlin dot de> ---
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.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (5 preceding siblings ...)
  2023-08-03 23:29 ` nikolasklauser at berlin dot de
@ 2023-08-04  2:28 ` de34 at live dot cn
  2023-08-07  1:07 ` de34 at live dot cn
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: de34 at live dot cn @ 2023-08-04  2:28 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #9 from Jiang An <de34 at live dot cn> ---
(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/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (6 preceding siblings ...)
  2023-08-04  2:28 ` de34 at live dot cn
@ 2023-08-07  1:07 ` de34 at live dot cn
  2023-08-08 21:19 ` arthur.j.odwyer at gmail dot com
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: de34 at live dot cn @ 2023-08-07  1:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #10 from Jiang An <de34 at live dot cn> ---
https://cplusplus.github.io/LWG/issue3967

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (7 preceding siblings ...)
  2023-08-07  1:07 ` de34 at live dot cn
@ 2023-08-08 21:19 ` arthur.j.odwyer at gmail dot com
  2023-08-08 21:24 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: arthur.j.odwyer at gmail dot com @ 2023-08-08 21:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |arthur.j.odwyer at gmail dot com

--- Comment #11 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> ---
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 <type_traits>. 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.)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (8 preceding siblings ...)
  2023-08-08 21:19 ` arthur.j.odwyer at gmail dot com
@ 2023-08-08 21:24 ` pinskia at gcc dot gnu.org
  2023-08-08 21:44 ` arthur.j.odwyer at gmail dot com
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-08-08 21:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #12 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I suspect this is a dup of bug 100470 then.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (9 preceding siblings ...)
  2023-08-08 21:24 ` pinskia at gcc dot gnu.org
@ 2023-08-08 21:44 ` arthur.j.odwyer at gmail dot com
  2023-08-08 21:45 ` pinskia at gcc dot gnu.org
  2023-08-09  2:52 ` de34 at live dot cn
  12 siblings, 0 replies; 14+ messages in thread
From: arthur.j.odwyer at gmail dot com @ 2023-08-08 21:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #13 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> ---
(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 :)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (10 preceding siblings ...)
  2023-08-08 21:44 ` arthur.j.odwyer at gmail dot com
@ 2023-08-08 21:45 ` pinskia at gcc dot gnu.org
  2023-08-09  2:52 ` de34 at live dot cn
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-08-08 21:45 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |DUPLICATE
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #14 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Since it was agreeded as a dup, let's mark it as such.

*** This bug has been marked as a duplicate of bug 100470 ***

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
  2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
                   ` (11 preceding siblings ...)
  2023-08-08 21:45 ` pinskia at gcc dot gnu.org
@ 2023-08-09  2:52 ` de34 at live dot cn
  12 siblings, 0 replies; 14+ messages in thread
From: de34 at live dot cn @ 2023-08-09  2:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611

--- Comment #15 from Jiang An <de34 at live dot cn> ---
(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).

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-08-09  2:52 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-13 21:02 [Bug libstdc++/106611] New: std::is_nothrow_copy_constructible returns wrong result nikolasklauser at berlin dot de
2022-08-13 21:14 ` [Bug libstdc++/106611] " redi at gcc dot gnu.org
2022-08-13 21:23 ` nikolasklauser at berlin dot de
2022-08-14  0:57 ` nikolasklauser at berlin dot de
2022-12-07  0:25 ` nikolasklauser at berlin dot de
2023-01-06 11:10 ` de34 at live dot cn
2023-08-03 23:29 ` nikolasklauser at berlin dot de
2023-08-04  2:28 ` de34 at live dot cn
2023-08-07  1:07 ` de34 at live dot cn
2023-08-08 21:19 ` arthur.j.odwyer at gmail dot com
2023-08-08 21:24 ` pinskia at gcc dot gnu.org
2023-08-08 21:44 ` arthur.j.odwyer at gmail dot com
2023-08-08 21:45 ` pinskia at gcc dot gnu.org
2023-08-09  2:52 ` de34 at live dot cn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).