| Issue |
61443
|
| Summary |
Issue with clang compilation of code using std::function and std::variant
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
DD-L
|
Hello, can someone explain this?
```
#include <functional>
#include <variant>
struct P;
struct A : std::function<P(void)> {
using std::function<P(void)>::function;
// ...
};
struct P {
std::variant<int, A> m_member;
};
int main() {
// ...
return 0;
}
```
The above code can be compiled successfully on all gcc/MSVC versions that support `std::function` and `std::variant`: [`https://godbolt.org/z/jb9TzsGeG`](https://godbolt.org/z/jb9TzsGeG).
However, all versions of clang (`<= ver 15.0.0`) report the following error:
```
In file included from <source>:4:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/functional:49:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_function.h:60:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/move.h:57:
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:2936:63: error: calling '_S_get' with incomplete return type 'typename __invoke_result<A &>::type' (aka 'P')
template<typename _Tp, typename = decltype(_S_conv<_Tp>(_S_get()))>
^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:349:4: note: in instantiation of template class 'std::__is_invocable_impl<std::__invoke_result<A &>, P, false>' requested here
: __is_invocable_impl<_Res2, _Res>::type
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:353:34: note: in instantiation of template class 'std::function<P ()>::_Callable<A, A>' requested here
using _Requires = __enable_if_t<_Cond::value, _Tp>;
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:434:33: note: in instantiation of template type alias '_Requires' requested here
typename _Constraints = _Requires<_Callable<_Functor>>>
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:435:2: note: in instantiation of default argument for 'function<A>' required here
function(_Functor&& __f)
^~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:1297:4: note: while substituting deduced template arguments into function template 'function' [with _Functor = A, _Constraints = (no value)]
__is_trivially_constructible(_Tp, _Tp&&)>>
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:1303:14: note: (skipping 3 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
: public __is_trivially_move_constructible_impl<_Tp>
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:350:23: note: in instantiation of static data member 'std::__detail::__variant::_Traits<int, A>::_S_trivial_move_ctor' requested here
_S_trivial_dtor && _S_trivial_move_ctor
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:732:45: note: in instantiation of static data member 'std::__detail::__variant::_Traits<int, A>::_S_trivial_move_assign' requested here
_Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:735:28: note: in instantiation of template type alias '_Move_assign_alias' requested here
struct _Variant_base : _Move_assign_alias<_Types...>
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:1337:15: note: in instantiation of template class 'std::__detail::__variant::_Variant_base<int, A>' requested here
: private __detail::__variant::_Variant_base<_Types...>,
^
<source>:16:26: note: in instantiation of template class 'std::variant<int, A>' requested here
std::variant<int, A> m_member;
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:2930:37: note: '_S_get' declared here
static typename _Result::type _S_get();
^
<source>:15:8: note: definition of 'P' is not complete until the closing '}'
struct P {
^
1 error generated.
ASM generation compiler returned: 1
In file included from <source>:4:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/functional:49:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_function.h:60:
In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/move.h:57:
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:2936:63: error: calling '_S_get' with incomplete return type 'typename __invoke_result<A &>::type' (aka 'P')
template<typename _Tp, typename = decltype(_S_conv<_Tp>(_S_get()))>
^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:349:4: note: in instantiation of template class 'std::__is_invocable_impl<std::__invoke_result<A &>, P, false>' requested here
: __is_invocable_impl<_Res2, _Res>::type
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:353:34: note: in instantiation of template class 'std::function<P ()>::_Callable<A, A>' requested here
using _Requires = __enable_if_t<_Cond::value, _Tp>;
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:434:33: note: in instantiation of template type alias '_Requires' requested here
typename _Constraints = _Requires<_Callable<_Functor>>>
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/std_function.h:435:2: note: in instantiation of default argument for 'function<A>' required here
function(_Functor&& __f)
^~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:1297:4: note: while substituting deduced template arguments into function template 'function' [with _Functor = A, _Constraints = (no value)]
__is_trivially_constructible(_Tp, _Tp&&)>>
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:1303:14: note: (skipping 3 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
: public __is_trivially_move_constructible_impl<_Tp>
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:350:23: note: in instantiation of static data member 'std::__detail::__variant::_Traits<int, A>::_S_trivial_move_ctor' requested here
_S_trivial_dtor && _S_trivial_move_ctor
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:732:45: note: in instantiation of static data member 'std::__detail::__variant::_Traits<int, A>::_S_trivial_move_assign' requested here
_Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:735:28: note: in instantiation of template type alias '_Move_assign_alias' requested here
struct _Variant_base : _Move_assign_alias<_Types...>
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/variant:1337:15: note: in instantiation of template class 'std::__detail::__variant::_Variant_base<int, A>' requested here
: private __detail::__variant::_Variant_base<_Types...>,
^
<source>:16:26: note: in instantiation of template class 'std::variant<int, A>' requested here
std::variant<int, A> m_member;
^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/type_traits:2930:37: note: '_S_get' declared here
static typename _Result::type _S_get();
^
<source>:15:8: note: definition of 'P' is not complete until the closing '}'
struct P {
^
1 error generated.
Execution build compiler returned: 1
```
If I replace the implementation of `struct A` with the following implementation, clang can work properly:
```
struct A : std::function<P(void)> {
// using std::function<P(void)>::function; // bad code
A() = default;
A(const A&) = default;
A(A&&) = default;
A(std::function<P(void)> f) : std::function<P(void)>(std::move(f)) {}
// ...
};
```
Is this considered a bug in clang?
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs