https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114138
Bug ID: 114138 Summary: [c++2b] ICE on valid code using `auto(expr)` DECAY-COPY Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: eric.niebler at gmail dot com Target Milestone: --- Compile the following with -c++=2b: ``` namespace std { template <class T> T&& declval() noexcept requires true; template <class> void declval() noexcept; namespace detail { struct none_such; template <class> using none_such_t = none_such; template <class T> extern const none_such_t<T> _getter_for; template <class T> using _decay_t = decltype(auto(declval<T>())); static_assert(__is_same_as(_decay_t<void>, void)); } template <const auto& Fn, class... Args> using _result_of_t = decltype(Fn(declval<Args>()...)); template <unsigned I, class Tuple> using tuple_element_t = _result_of_t<detail::_getter_for<detail::_decay_t<Tuple>>, char(*)[I+1], Tuple>; template <class First, class Second> struct pair { First first; Second second; }; template <class> inline constexpr bool _is_pair = false; template <class First, class Second> inline constexpr bool _is_pair<pair<First, Second>> = true; template <class T> concept Pair = _is_pair<decltype(auto(std::declval<T>()))>; template <unsigned I, Pair P> requires (I <= 1) decltype(auto) get(P&& p) noexcept { if constexpr (I == 0) { return (static_cast<P&&>(p).first); } else { return (static_cast<P&&>(p).second); } } namespace detail { inline constexpr auto _pair_getter = []<unsigned J, class Pair>(char(*)[J], Pair&& p) noexcept -> decltype(auto) { return std::get<J-1>(static_cast<Pair&&>(p)); }; template <class First, class Second> inline constexpr auto _getter_for<pair<First, Second>> = _pair_getter; } } int main() { static_assert(__is_same_as(int&, std::tuple_element_t<0, std::pair<int, float>&>)); static_assert(__is_same_as(float&&, std::tuple_element_t<1, std::pair<int, float>&&>)); } ``` Result: ``` <source>: In substitution of 'template<unsigned int I, class Tuple> using std::tuple_element_t = std::_result_of_t<_getter_for<decltype ((auto)(declval<Tuple>()))>, char (*)[(I + 1)], Tuple> [with unsigned int I = 0; Tuple = std::pair<int, float>&]': <source>:71:82: required from here 71 | static_assert(__is_same_as(int&, std::tuple_element_t<0, std::pair<int, float>&>)); | ^ <source>:21:31: internal compiler error: in tsubst, at cp/pt.cc:16367 21 | using _decay_t = decltype(auto(declval<T>())); | ^~~~~~~~~~~~~~~~~~ 0x265412c internal_error(char const*, ...) ???:0 0xa548c3 fancy_abort(char const*, int, char const*) ???:0 0xc99307 tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0xc9f3c9 tsubst_template_args(tree_node*, tree_node*, int, tree_node*) ???:0 0xc9f3c9 tsubst_template_args(tree_node*, tree_node*, int, tree_node*) ???:0 0xc98a19 tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0xc80873 instantiate_template(tree_node*, tree_node*, int) ???:0 0xc9a0fc tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0xc973cc lookup_template_class(tree_node*, tree_node*, tree_node*, tree_node*, int, int) ???:0 0xcd370f finish_template_type(tree_node*, tree_node*, int) ???:0 0xc577da c_parse_file() ???:0 0xdaba19 c_common_parse_file() ???:0 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. Compiler returned: 1 ``` See https://godbolt.org/z/r13Yff5bM