public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/103663] New: Diagnostic is missing multiple instantiation frames to help point to where the problem happens
@ 2021-12-11 19:56 barry.revzin at gmail dot com
2023-04-03 2:39 ` [Bug c++/103663] " pinskia at gcc dot gnu.org
0 siblings, 1 reply; 2+ messages in thread
From: barry.revzin at gmail dot com @ 2021-12-11 19:56 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103663
Bug ID: 103663
Summary: Diagnostic is missing multiple instantiation frames to
help point to where the problem happens
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: barry.revzin at gmail dot com
Target Milestone: ---
I'm sorry for how not-remotely-reduced these examples are, but I'm not sure how
to do better.
=======================================================
Consider this bug in range-v3 that we're trying to figure out how to solve
(this is a range-v3 library issue, not a gcc or libstdc++ issue):
#include <range/v3/view/zip.hpp>
struct Abstract {
virtual auto f() -> int = 0;
};
struct V {
auto begin() -> Abstract*;
auto end() -> Abstract*;
};
void use(V v) {
auto z = ranges::views::zip(v);
z.begin();
}
This code doesn't compile. With gcc 11.2 -std=c++20
(https://godbolt.org/z/h4d14jeMa), the diagnostics I get on compiler explorer
are:
In file included from
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/view/zip.hpp:17,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple: In instantiation of
'struct std::_Head_base<0, Abstract, false>':
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple:407:12: required
from 'struct std::_Tuple_impl<0, Abstract>'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple:599:11: required
from 'class std::tuple<Abstract>'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/functional/invoke.hpp:138:40:
required from 'constexpr decltype
((F&&)(f)((Args&&(ranges::invoke_fn::operator()::args))...))
ranges::invoke_fn::operator()(F&&, Args&& ...) const [with F =
ranges::detail::indirect_zip_fn_&; Args = {ranges::copy_tag, Abstract*};
decltype ((F&&)(f)((Args&&(ranges::invoke_fn::operator()::args))...)) =
std::tuple<Abstract>]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/functional/concepts.hpp:36:5:
required by substitution of 'template<bool Const> requires Const &&
(and_v<range<const Rngs>...>) && (zippable_with<Fun, typename
meta::detail::_if_<std::integral_constant<bool, Const>, const Rngs>::type ...>)
ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_,
ranges::ref_view<V> >::cursor<Const>
ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_,
ranges::ref_view<V> >::begin_cursor<Const>() const [with bool Const =
ranges::detail::indirect_zip_fn_]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/detail/range_access.hpp:85:31:
required by substitution of 'template<class Rng> static constexpr decltype
(rng.begin_cursor()) ranges::range_access::begin_cursor(Rng&) [with Rng = const
ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_,
ranges::ref_view<V> >]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/view/facade.hpp:39:39:
required by substitution of 'template<class Derived> using facade_iterator_t
= ranges::basic_iterator<typename std::decay<decltype
(ranges::range_access::begin_cursor(declval<Derived&>()))>::type> [with Derived
= const ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_,
ranges::ref_view<V> >]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/view/facade.hpp:106:24:
required by substitution of 'template<class D> requires same_as<D, Derived>
constexpr ranges::detail::facade_iterator_t<const D>
ranges::view_facade<ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_,
ranges::ref_view<V> >, ranges::finite>::begin<D>() const [with D =
ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_,
ranges::ref_view<V> >]'
<source>:14:12: required from here
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple:224:13: error:
cannot declare field 'std::_Head_base<0, Abstract, false>::_M_head_impl' to be
of abstract type 'Abstract'
224 | _Head _M_head_impl;
| ^~~~~~~~~~~~
<source>:3:8: note: because the following virtual functions are pure within
'Abstract':
3 | struct Abstract {
| ^~~~~~~~
<source>:4:18: note: 'virtual int Abstract::f()'
4 | virtual auto f() -> int = 0;
| ^
The instantiation stack points to tuple, invoke.hpp, concepts.hpp,
range_access.hpp, facade.hpp. But the problem comes from zip_with.hpp. This is
not really possible to track down from the diagnostic.
To help illustrate what I mean, this line:
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/detail/range_access.hpp:85:31:
required by substitution of 'template<class Rng> static constexpr decltype
(rng.begin_cursor()) ranges::range_access::begin_cursor(Rng&) [with Rng = const
ranges::iter_zip_with_view<ranges::detail::indirect_zip_fn_,
ranges::ref_view<V> >]'
points us to here:
template<typename Rng>
static constexpr auto CPP_auto_fun(begin_cursor)(Rng &rng)
(
return rng.begin_cursor()
)
Which is a macro that expands to:
template<typename Rng>
static constexpr auto begin_cursor (Rng &rng)
noexcept(noexcept(rng.begin_cursor())) -> decltype(rng.begin_cursor()) { return
(rng.begin_cursor()); }
The next instantiation stack frame points us to here:
template<typename Fun, typename... Args>
CPP_requires(invocable_,
requires(Fun && fn) //
(
invoke((Fun &&) fn, std::declval<Args>()...)
));
Which is a macro that expands to:
template<typename Fun, typename... Args>
concept invocable__requires_ = requires(Fun && fn) { invoke((Fun &&) fn,
std::declval<Args>()...); }
;
template<typename Fun, typename... Args>
concept invocable =
ranges::invocable__requires_<Fun, Args...>;
But... how did we get from the begin_cursor call (which doesn't use concepts
anywhere) to this concept? The clue is kind of in the text afterwards. We try
to call this particular begin_cursor() (this is zip_with.hpp:329-336):
template(bool Const = true)(
/// \pre
requires Const AND and_v<range<Rngs const>...> AND
views::zippable_with<Fun, meta::if_c<Const, Rngs const>...>)
cursor<Const> begin_cursor() const
{
return {fun_, tuple_transform(rngs_, ranges::begin)};
}
And in that zip_with, we check zippable_with preprocesses out into:
template<typename Fun, typename... Rngs > concept
zippable_with__concept_ = invocable<Fun&, iterator_t<Rngs>...> &&
invocable<Fun&, copy_tag, iterator_t<Rngs>...> && invocable<Fun&, move_tag,
iterator_t<Rngs>...>
;
template<typename Fun, typename ...Rngs>
concept zippable_with =
and_v<input_range<Rngs>...> &&
copy_constructible<Fun> &&
views::zippable_with__concept_<Fun, Rngs...>;
And there now is the invocable check.
But this would've been a lot easier to track down if these two zip_with.hpp
frames were present.
==============================
A similar, shorter example of disappearing frames:
#include <range/v3/view/zip.hpp>
struct Abstract {
virtual void f() = 0;
};
using T = ranges::common_reference_t<ranges::common_tuple<Abstract&>,
std::tuple<Abstract>&>;
which gives me (https://godbolt.org/z/MdvrYGxYr):
/opt/compiler-explorer/gcc-trunk-20211211/include/c++/12.0.0/tuple:416:12:
required from 'struct std::_Tuple_impl<0, Abstract>'
/opt/compiler-explorer/gcc-trunk-20211211/include/c++/12.0.0/tuple:609:11:
required from 'class std::tuple<Abstract>'
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:92:41:
required by substitution of 'template<class T, class U> struct
concepts::detail::_builtin_common_2<T, U, meta::void_<decltype ((true ?
declval<T>() : declval<U>()))> > [with T = ranges::common_tuple<Abstract&>; U =
std::tuple<Abstract>&]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:365:12:
recursively required by substitution of 'template<class T, class U> struct
concepts::detail::_common_reference2<T, U, typename
concepts::detail::if_<std::is_reference<typename
concepts::detail::_builtin_common<T, U>::type>::value>::invoke<void> > [with T
= ranges::common_tuple<Abstract&>; U = std::tuple<Abstract>&]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:365:12:
required from 'struct
concepts::common_reference<ranges::common_tuple<Abstract&>,
std::tuple<Abstract>&>'
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:370:11:
required by substitution of 'template<class ... Ts> using common_reference_t
= typename concepts::common_reference::type [with Ts =
{ranges::common_tuple<Abstract&>, std::tuple<Abstract>&}]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/utility/common_type.hpp:47:11:
required by substitution of 'template<class ... Ts> using common_reference_t
= concepts::common_reference_t<Ts ...> [with Ts =
{ranges::common_tuple<Abstract&>, std::tuple<Abstract>&}]'
<source>:7:92: required from here
But there are a lot of steps from type_traits.hpp:365 to type_traits.hpp:92.
Clang hides them by default, but let's me expose them
(https://godbolt.org/z/b6dne6c85):
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:92:41:
note: in instantiation of template class 'std::tuple<Abstract>' requested here
using _cond_res = decltype(true ? std::declval<T>() :
std::declval<U>());
^
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:146:52:
note: in instantiation of template type alias '_cond_res' requested here
struct _builtin_common_2<T, U, meta::void_<_cond_res<T, U>>>
^
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:151:15:
note: during template argument deduction for class template partial
specialization '_builtin_common_2<T, U>' [with T =
ranges::common_tuple<Abstract &>, U = std::tuple<Abstract> &]
: _builtin_common_2<T, U>
^
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:151:15:
note: in instantiation of template class
'concepts::detail::_builtin_common_2<ranges::common_tuple<Abstract &>,
std::tuple<Abstract> &>' requested here
/opt/compiler-explorer/libs/rangesv3/trunk/include/meta/meta_fwd.hpp:298:18:
note: in instantiation of template class
'concepts::detail::_builtin_common<ranges::common_tuple<Abstract &>,
std::tuple<Abstract> &>' requested here
typename T::type;
^
/opt/compiler-explorer/libs/rangesv3/trunk/include/meta/meta_fwd.hpp:298:9:
note: in instantiation of requirement here
typename T::type;
^~~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/rangesv3/trunk/include/meta/meta_fwd.hpp:296:26:
note: while substituting template arguments into constraint expression here
META_CONCEPT trait = requires
^~~~~~~~
/opt/compiler-explorer/libs/rangesv3/trunk/include/meta/meta.hpp:140:36: note:
while checking the satisfaction of concept
'trait<concepts::detail::_builtin_common<ranges::common_tuple<Abstract &>,
std::tuple<Abstract> &>>' requested here
template <META_TYPE_CONSTRAINT(trait) T>
^
/opt/compiler-explorer/libs/rangesv3/trunk/include/meta/meta.hpp:140:36: note:
while substituting template arguments into constraint expression here
template <META_TYPE_CONSTRAINT(trait) T>
^~~~~
/opt/compiler-explorer/libs/rangesv3/trunk/include/meta/meta_fwd.hpp:155:35:
note: expanded from macro 'META_TYPE_CONSTRAINT'
#define META_TYPE_CONSTRAINT(...) __VA_ARGS__
^~~~~~~~~~~
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:89:9:
note: while checking constraint satisfaction for template
'_t<concepts::detail::_builtin_common<ranges::common_tuple<Abstract &>,
std::tuple<Abstract> &>>' required here
using _builtin_common_t = meta::_t<_builtin_common<T, U>>;
^~~~~
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:346:64:
note: in instantiation of template type alias '_builtin_common_t' requested
here
struct _common_reference2<T, U,
if_t<std::is_reference<_builtin_common_t<T, U>>::value>>
^
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:366:11:
note: during template argument deduction for class template partial
specialization '_common_reference2<T, U,
if_t<std::is_reference<_builtin_common_t<T, U>>::value>>' [with T =
ranges::common_tuple<Abstract &>, U = std::tuple<Abstract> &]
: detail::_common_reference2<T, U>
^
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:366:11:
note: in instantiation of template class
'concepts::detail::_common_reference2<ranges::common_tuple<Abstract &>,
std::tuple<Abstract> &>' requested here
/opt/compiler-explorer/libs/rangesv3/trunk/include/concepts/type_traits.hpp:370:5:
note: in instantiation of template class
'concepts::common_reference<ranges::common_tuple<Abstract &>,
std::tuple<Abstract> &>' requested here
using common_reference_t = typename common_reference<Ts...>::type;
^
Which is also a lot more helpful.
^ permalink raw reply [flat|nested] 2+ messages in thread
* [Bug c++/103663] Diagnostic is missing multiple instantiation frames to help point to where the problem happens
2021-12-11 19:56 [Bug c++/103663] New: Diagnostic is missing multiple instantiation frames to help point to where the problem happens barry.revzin at gmail dot com
@ 2023-04-03 2:39 ` pinskia at gcc dot gnu.org
0 siblings, 0 replies; 2+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-04-03 2:39 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103663
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
See Also| |https://gcc.gnu.org/bugzill
| |a/show_bug.cgi?id=90508
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Maybe similar to PR 90508.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-04-03 2:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-11 19:56 [Bug c++/103663] New: Diagnostic is missing multiple instantiation frames to help point to where the problem happens barry.revzin at gmail dot com
2023-04-03 2:39 ` [Bug c++/103663] " pinskia at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).