-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Open
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"
Description
Regression that bisects to #164703: the following fails to build, with the error message a parameter pack may not be accessed at an out of bounds index.
Live repro: https://compiler-explorer.com/z/9731oM5qn
Source:
#include <cstdint>
#include <tuple>
#include <type_traits>
#include <utility>
using npos = std::integral_constant<std::size_t, static_cast<std::size_t>(-1)>;
template <class Predicate, class T, std::size_t I, std::size_t N>
struct find_impl
: std::conditional<Predicate::template apply<
typename std::tuple_element<I, T>::type>::value,
std::integral_constant<std::size_t, I>,
find_impl<Predicate, T, I + 1, N - 1>>::type {};
template <class Predicate, class T, std::size_t I>
struct find_impl<Predicate, T, I, 0> : npos {};
template <class Predicate, class T>
struct find_index_if : find_impl<Predicate, T, 0, std::tuple_size<T>::value> {};
template <typename... Args>
struct IsInvocableOn {
template <typename Fn>
struct apply : std::is_invocable<Fn, Args...> {};
};
template <typename... Fns>
struct Overload {
template <int I>
using FnAt = typename std::tuple_element<I, std::tuple<Fns...>>::type;
template <typename... Args>
auto operator()(Args&&... args) const -> FnAt<
find_index_if<IsInvocableOn<Args...>, std::tuple<Fns...>>::value>;
};
template <typename Fn>
bool foo = std::is_invocable_v<Overload<Fn>>;
bool foo_v = foo<decltype([](int x) {})>;Repro just needs clang -std=c++20, and fails w/ either libc++ or libstdc++. gcc also accepts this.
Failure:
In file included from <source>:2:
In file included from /cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/tuple:228:
In file included from /cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/__fwd/get.h:15:
In file included from /cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/__fwd/pair.h:14:
/cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/__fwd/tuple.h:40:52: error: a parameter pack may not be accessed at an out of bounds index
40 | using type _LIBCPP_NODEBUG = __type_pack_element<_Ip, _Tp...>;
| ^
<source>:30:5: note: in instantiation of template class 'std::tuple_element<18446744073709551615, std::tuple<(lambda at <source>:40:27)>>' requested here
30 | using FnAt = typename std::tuple_element<I, std::tuple<Fns...>>::type;
| ^
<source>:33:46: note: in instantiation of template type alias 'FnAt' requested here
33 | auto operator()(Args&&... args) const -> FnAt<
| ^
/cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/__type_traits/invoke.h:77:47: note: while substituting deduced template arguments into function template 'operator()' [with Args = <>]
77 | struct __invoke_result_impl<__void_t<decltype(__builtin_invoke(std::declval<_Args>()...))>, _Args...> {
| ^
/cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/__type_traits/invoke.h:85:1: note: during template argument deduction for class template partial specialization '__invoke_result_impl<__void_t<decltype(__builtin_invoke(std::declval<_Args>()...))>, _Args...>' [with _Args = <Overload<(lambda at <source>:40:27)>>]
85 | using __invoke_result_t _LIBCPP_NODEBUG = typename __invoke_result<_Args...>::type;
| ^
/cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/__type_traits/invoke.h:85:1: note: in instantiation of template class 'std::__invoke_result_impl<void, Overload<(lambda at <source>:40:27)>>' requested here
/cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/__type_traits/invoke.h:97:48: note: in instantiation of template type alias '__invoke_result_t' requested here
97 | inline const bool __is_invocable_impl<__void_t<__invoke_result_t<_Args...> >, _Args...> = true;
| ^
/cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/__type_traits/invoke.h:100:38: note: during template argument deduction for variable template partial specialization '__is_invocable_impl<__void_t<__invoke_result_t<_Args...>>, _Args...>' [with _Args = <Overload<(lambda at <source>:40:27)>>]
100 | inline const bool __is_invocable_v = __is_invocable_impl<void, _Args...>;
| ^
/cefs/8d/8d2fd574113d33adba235562_clang-assertions-trunk-20251112/bin/../include/c++/v1/__type_traits/invoke.h:370:67: note: in instantiation of variable template specialization 'std::__is_invocable_v<Overload<(lambda at <source>:40:27)>>' requested here
370 | _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_invocable_v = __is_invocable_v<_Fn, _Args...>;
| ^
<source>:38:17: note: in instantiation of variable template specialization 'std::is_invocable_v<Overload<(lambda at <source>:40:27)>>' requested here
38 | bool foo = std::is_invocable_v<Overload<Fn>>;
| ^
<source>:40:14: note: in instantiation of variable template specialization 'foo<(lambda at <source>:40:27)>' requested here
40 | bool foo_v = foo<decltype([](int x) {})>;
| ^
1 error generated.
Compiler returned: 1
I also have a repro w/o any headers, although it is clang-specific since it was reduced w/ libc++ which uses the __type_pack_element clang builtin. It may be useful for a regression test but does not allow comparing conformance w/ gcc.
Live link: https://compiler-explorer.com/z/YEK8vsbK5
Source:
template <class>
using __void_t = void;
template <bool>
struct tuple_element;
template <decltype(sizeof(int)) _Ip>
struct tuple_element<_Ip> {
using type = __type_pack_element<_Ip>;
};
template <class...>
struct __invoke_result_impl;
template <class... _Args>
struct __invoke_result_impl<__void_t<decltype(__builtin_invoke(_Args()...))>,
_Args...>;
template <class... _Args>
using __invoke_result = __invoke_result_impl<void, _Args...>;
template <class... _Args>
using __invoke_result_t = __invoke_result<_Args...>::type;
template <class...>
bool __is_invocable_impl;
template <class... _Args>
bool __is_invocable_impl<__void_t<__invoke_result_t<_Args...>>, _Args...>;
template <class... _Args>
bool __is_invocable_v = __is_invocable_impl<void, _Args...>;
template <class _Fn>
bool is_invocable_v = __is_invocable_v<_Fn>;
template <class>
struct find_index_if {
static const int value = -1;
};
template <typename...>
struct IsInvocableOn;
template <int I>
using FnAt = tuple_element<I>::type;
struct Overload {
template <typename... Args>
auto operator()()
-> FnAt<find_index_if<IsInvocableOn<Args...>>::value>;
};
bool value = is_invocable_v<Overload>;Metadata
Metadata
Assignees
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"