Bug 100666 - [9/10 Regression] warning: ignoring return value of 'constexpr _Tp&& std::forward(typename std::remove_reference<_Tp>::type&) [with _Tp = std::nullptr_t; ...]', declared with attribute 'nodiscard' [-Wunused-result]
Summary: [9/10 Regression] warning: ignoring return value of 'constexpr _Tp&& std::for...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.1.0
: P3 normal
Target Milestone: 9.5
Assignee: Jakub Jelinek
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2021-05-19 07:45 UTC by Mike Hommey
Modified: 2022-05-11 06:34 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 11.1.1, 12.0, 7.5.0, 8.3.0, 9.2.0
Known to fail: 10.1.0, 11.1.0, 8.4.0, 9.3.0
Last reconfirmed: 2021-05-19 00:00:00


Attachments
gcc12-pr100666.patch (679 bytes, patch)
2021-05-24 17:37 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mike Hommey 2021-05-19 07:45:04 UTC
(Note I'm not entirely sure this is a GCC bug, but it doesn't happen with GCC < 11 and with clang)

Reduced testcase:
```
#include <utility>

extern void foo(...);

template <typename... Ts>
void bar(Ts&&... aArgs) {
    foo(std::forward<Ts>(aArgs)...);
}

void qux() {
    bar(nullptr);
}
```

This emits the following warning:
```
<source>: In instantiation of 'void bar(Ts&& ...) [with Ts = {std::nullptr_t}]':
<source>:11:8:   required from here
<source>:7:25: warning: ignoring return value of 'constexpr _Tp&& std::forward(typename std::remove_reference<_Tp>::type&) [with _Tp = std::nullptr_t; typename std::remove_reference<_Tp>::type = std::nullptr_t]', declared with attribute 'nodiscard' [-Wunused-result]
    7 |     foo(std::forward<Ts>(aArgs)...);
      |         ~~~~~~~~~~~~~~~~^~~~~~~
In file included from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_pair.h:59,
                 from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/utility:70,
                 from <source>:1:
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/move.h:77:5: note: declared here
   77 |     forward(typename std::remove_reference<_Tp>::type& __t) noexcept
      |     ^~~~~~~
```
(https://godbolt.org/z/GW3xf71n3)

Incidentally, using the x86-64 gcc (static analysis) on compiler explorer fails with:
```
during IPA pass: analyzer
<source>: In function 'void qux()':
<source>:11:9: internal compiler error: in make_region_for_type, at analyzer/region-model.cc:5973
   11 |     bar(nullptr);
      |         ^~~~~~~
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
```
Comment 1 Jonathan Wakely 2021-05-19 08:55:40 UTC
(In reply to Mike Hommey from comment #0)
> (Note I'm not entirely sure this is a GCC bug, but it doesn't happen with
> GCC < 11 and with clang)

Yeah, this shouldn't warn.

Reduced:

[[nodiscard]] decltype(nullptr) null();

extern void foo(...);

void qux() {
    foo(null());
}


GCC 10 has the same warning, it's just that std::forward didn't have the [[nodiscard]] attribute.

It only happens when a nodiscard function returns std::nullptr_t and it's passed to an ellipsis. GCC 7 was OK, and 8.3 and 9.2

It started with r279680:

    re PR c++/92992 (Side-effects dropped when decltype(nullptr) typed expression is passed to ellipsis)
    
            PR c++/92992
            * call.c (convert_arg_to_ellipsis): For decltype(nullptr) arguments
            that have side-effects use cp_build_compound_expr.
    
            * g++.dg/cpp0x/nullptr45.C: New test.
Comment 2 Jakub Jelinek 2021-05-24 17:37:36 UTC
Created attachment 50862 [details]
gcc12-pr100666.patch

Untested fix.
Comment 3 GCC Commits 2021-05-25 15:25:42 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:ad52d89808a947264397e920d7483090d4108f7b

commit r12-1043-gad52d89808a947264397e920d7483090d4108f7b
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue May 25 17:24:38 2021 +0200

    c++: Avoid -Wunused-value false positives on nullptr passed to ellipsis [PR100666]
    
    When passing expressions with decltype(nullptr) type with side-effects to
    ellipsis, we pass (void *)0 instead, but for the side-effects evaluate them
    on the lhs of a COMPOUND_EXPR.  Unfortunately that means we warn about it
    if the expression is a call to nodiscard marked function, even when the
    result is really used, just needs to be transformed.
    
    Fixed by adding a warning_sentinel.
    
    2021-05-25  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/100666
            * call.c (convert_arg_to_ellipsis): For expressions with NULLPTR_TYPE
            and side-effects, temporarily disable -Wunused-result warning when
            building COMPOUND_EXPR.
    
            * g++.dg/cpp1z/nodiscard8.C: New test.
            * g++.dg/cpp1z/nodiscard9.C: New test.
Comment 4 GCC Commits 2021-05-31 14:08:55 UTC
The releases/gcc-11 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:718a78fcfb03ca3c552800b510ef3eb085bcbb76

commit r11-8492-g718a78fcfb03ca3c552800b510ef3eb085bcbb76
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue May 25 17:24:38 2021 +0200

    c++: Avoid -Wunused-value false positives on nullptr passed to ellipsis [PR100666]
    
    When passing expressions with decltype(nullptr) type with side-effects to
    ellipsis, we pass (void *)0 instead, but for the side-effects evaluate them
    on the lhs of a COMPOUND_EXPR.  Unfortunately that means we warn about it
    if the expression is a call to nodiscard marked function, even when the
    result is really used, just needs to be transformed.
    
    Fixed by adding a warning_sentinel.
    
    2021-05-25  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/100666
            * call.c (convert_arg_to_ellipsis): For expressions with NULLPTR_TYPE
            and side-effects, temporarily disable -Wunused-result warning when
            building COMPOUND_EXPR.
    
            * g++.dg/cpp1z/nodiscard8.C: New test.
            * g++.dg/cpp1z/nodiscard9.C: New test.
    
    (cherry picked from commit ad52d89808a947264397e920d7483090d4108f7b)
Comment 5 Jakub Jelinek 2021-05-31 14:59:05 UTC
Fixed on the trunk and for 11.2 so far.
Comment 6 GCC Commits 2022-05-10 08:18:13 UTC
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:589a0f34b1d176b62b064c9815c341b6abf48a2b

commit r10-10614-g589a0f34b1d176b62b064c9815c341b6abf48a2b
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue May 25 17:24:38 2021 +0200

    c++: Avoid -Wunused-value false positives on nullptr passed to ellipsis [PR100666]
    
    When passing expressions with decltype(nullptr) type with side-effects to
    ellipsis, we pass (void *)0 instead, but for the side-effects evaluate them
    on the lhs of a COMPOUND_EXPR.  Unfortunately that means we warn about it
    if the expression is a call to nodiscard marked function, even when the
    result is really used, just needs to be transformed.
    
    Fixed by adding a warning_sentinel.
    
    2021-05-25  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/100666
            * call.c (convert_arg_to_ellipsis): For expressions with NULLPTR_TYPE
            and side-effects, temporarily disable -Wunused-result warning when
            building COMPOUND_EXPR.
    
            * g++.dg/cpp1z/nodiscard8.C: New test.
            * g++.dg/cpp1z/nodiscard9.C: New test.
    
    (cherry picked from commit ad52d89808a947264397e920d7483090d4108f7b)
Comment 7 GCC Commits 2022-05-11 06:20:02 UTC
The releases/gcc-9 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:6a05023c8739f2848778074e1ea9311cf6825a0f

commit r9-10073-g6a05023c8739f2848778074e1ea9311cf6825a0f
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue May 25 17:24:38 2021 +0200

    c++: Avoid -Wunused-value false positives on nullptr passed to ellipsis [PR100666]
    
    When passing expressions with decltype(nullptr) type with side-effects to
    ellipsis, we pass (void *)0 instead, but for the side-effects evaluate them
    on the lhs of a COMPOUND_EXPR.  Unfortunately that means we warn about it
    if the expression is a call to nodiscard marked function, even when the
    result is really used, just needs to be transformed.
    
    Fixed by adding a warning_sentinel.
    
    2021-05-25  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/100666
            * call.c (convert_arg_to_ellipsis): For expressions with NULLPTR_TYPE
            and side-effects, temporarily disable -Wunused-result warning when
            building COMPOUND_EXPR.
    
            * g++.dg/cpp1z/nodiscard8.C: New test.
            * g++.dg/cpp1z/nodiscard9.C: New test.
    
    (cherry picked from commit ad52d89808a947264397e920d7483090d4108f7b)
Comment 8 Jakub Jelinek 2022-05-11 06:34:19 UTC
Fixed.