https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120717
Bug ID: 120717
Summary: Passing reference to incomplete type to
std::move_only_function emits false-positive
'-Wsfinae-incomplete' warning
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: ykakeyama3014 at gmail dot com
Target Milestone: ---
When compiling the following code with GCC trunk:
#include <functional>
struct S;
std::move_only_function<void(const S&)> callback;
struct S {};
which can be reduced to:
#include <type_traits>
template <class T>
struct accepts_complete_type {
static_assert(std::__is_complete_or_unbounded(std::__type_identity<T>{}));
};
struct S;
accepts_complete_type<const S&> value;
struct S {};
the compiler emits the following warning:
source.cpp:8:8: warning: defining āSā, which previously failed to be complete
in a SFINAE context [-Wsfinae-incomplete=]
8 | struct S {
| ^
In file included from source.cpp:1:
/opt/gcc-trunk/include/c++/16.0.0/type_traits:300:36: note: here. Use
ā-Wsfinae-incomplete=2ā for a diagnostic at that point
300 | template <typename _Tp, size_t = sizeof(_Tp)>
| ^~~~~~~~~~~
This warning, introduced in commit 117782e0c2a81a4b8170f87f0fe7190ee22548e2,
appears to be a false-positive.
It seems to me that there are two options to fix this issue:
1. Refine the implementation-detail metafunction
std::__is_complete_or_unbounded so that it correctly handles such reference to
incomplete types.
2. Retire std::__is_complete_or_unbounded, then introduce a builtin that
detects complete types correctly. This is similar to Clang's
__is_complete_type.
Option 1 appears to be unimplementable because such metafunction can be called
several times in different contexts, which can result in ODR-violation.
related issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71579