[Bug c++/91466] New: [concepts] indicates "used in its own initializer" when not, constraint order change passes compilation.
frederik.engels24 at gmail dot com
gcc-bugzilla@gcc.gnu.org
Thu Aug 15 23:39:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91466
Bug ID: 91466
Summary: [concepts] indicates "used in its own initializer"
when not, constraint order change passes compilation.
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: frederik.engels24 at gmail dot com
Target Milestone: ---
Run using "g++ (Compiler-Explorer-Build) 10.0.0 20190814 (experimental)" with
options "-std=c++2a -fconcepts"
and source code: https://godbolt.org/z/aGw2d0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
#include <type_traits>
#include <array>
template<typename T>
concept integral_constant_ = std::is_empty_v<T> && std::is_trivial_v<T> &&
requires
{
typename T::value_type;
requires std::is_integral_v<typename T::value_type>;
{ T::value } -> typename T::value_type;
};
struct sz_fn
{
template<typename R> requires requires(R&& r) { {static_cast<R&&>(r).size()} ->
integral_constant_; }
constexpr auto operator()(R&& r) {
return static_cast<R&&>(r).size();
}
};
constexpr auto sz = sz_fn{};
int main()
{
auto arr = std::array<int, 5>{1, 2, 3, 4, 5};
return !std::is_invocable_v<decltype(sz), decltype(arr)>;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
results in:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from <source>:1:
/opt/compiler-explorer/gcc-trunk-20190815/include/c++/10.0.0/type_traits: In
substitution of 'template<class _Fn, class ... _Args> static
std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)),
std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn =
const sz_fn; _Args = {std::array<int, 5>}]':
/opt/compiler-explorer/gcc-trunk-20190815/include/c++/10.0.0/type_traits:2563:55:
required from 'struct std::__result_of_impl<false, false, const sz_fn,
std::array<int, 5> >'
/opt/compiler-explorer/gcc-trunk-20190815/include/c++/10.0.0/type_traits:2976:12:
recursively required by substitution of 'template<class _Result, class _Ret>
struct std::__is_invocable_impl<_Result, _Ret, std::__void_t<typename
_CTp::type> > [with _Result = std::__invoke_result<const sz_fn, std::array<int,
5> >; _Ret = void]'
/opt/compiler-explorer/gcc-trunk-20190815/include/c++/10.0.0/type_traits:2976:12:
required from 'struct std::is_invocable<const sz_fn, std::array<int, 5> >'
/opt/compiler-explorer/gcc-trunk-20190815/include/c++/10.0.0/type_traits:3021:27:
required from 'constexpr const bool std::is_invocable_v<const sz_fn,
std::array<int, 5> >'
<source>:28:18: required from here
/opt/compiler-explorer/gcc-trunk-20190815/include/c++/10.0.0/type_traits:2552:26:
error: the value of 'std::is_empty_v<integral_constant_>' is not usable in a
constant expression
2552 | std::declval<_Fn>()(std::declval<_Args>()...)
| ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20190815/include/c++/10.0.0/type_traits:3103:25:
note: 'std::is_empty_v<integral_constant_>' used in its own initializer
3103 | inline constexpr bool is_empty_v = is_empty<_Tp>::value;
| ^~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20190815/include/c++/10.0.0/type_traits:2552:26:
error: the value of 'std::is_trivial_v<integral_constant_>' is not usable in a
constant expression
2552 | std::declval<_Fn>()(std::declval<_Args>()...)
| ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20190815/include/c++/10.0.0/type_traits:3092:25:
note: 'std::is_trivial_v<integral_constant_>' used in its own initializer
3092 | inline constexpr bool is_trivial_v = is_trivial<_Tp>::value;
| ^~~~~~~~~~~~
Compiler returned: 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Changing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template<typename T>
concept integral_constant_ = std::is_empty_v<T> && std::is_trivial_v<T> &&
requires
{
typename T::value_type;
requires std::is_integral_v<typename T::value_type>;
{ T::value } -> typename T::value_type;
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
to
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template<typename T>
concept integral_constant_ =
requires
{
typename T::value_type;
requires std::is_integral_v<typename T::value_type>;
{ T::value } -> typename T::value_type;
} && std::is_empty_v<T> && std::is_trivial_v<T>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allows the program to compile successfully.
More information about the Gcc-bugs
mailing list