Created attachment 48006 [details] distilled from ranges We accept the attached test case, which should be rejected. It comes from these two fragments of the ranges header: lines ~1595 static constexpr decltype(auto) __iter_move(const _Iterator& __i = {}) noexcept(noexcept(std::__invoke(*__i._M_parent->_M_fun, *__i._M_current))) { if constexpr (is_lvalue_reference_v<decltype(*__i)>) return std::move(*__i); else return *__i; } lines ~1752 friend constexpr decltype(auto) iter_move(const _Iterator& __i) noexcept(noexcept(__iter_move())) { return __iter_move(__i); } If we change __iter_move's argument type to int, we reject complaining that the call in iter_move's noexcept spec requires the default argument before it's been parsed. Clang rejects either way. the '__iter_move ()' call is not dependent because it has no arguments. Addition of the default argument does not make it dependent. filing a separate issue to fix libstdc++
Related or dup of PR93901 ? Guess I'll bisect to see if it is the same commit.
Maybe not, as it doesn't seem to be a regression, it has never been rejected (at least not in anything since r200000 I've tried). clang++ rejects with exception specification is not available until end of class definition
This is the error that should be emitted (modulo the argument type being _Iterator) devvm2772:6>./cc1plus -fmodule-header -quiet b_a.H In file included from b_a.H:1: b.h:10:69: error: call to 'static void _Iterator<_Const>::mover(const int&)' uses the default argument for parameter 1, which is not yet defined 10 | friend void move (const _Iterator &arg) noexcept (noexcept (mover ()))
(In reply to Nathan Sidwell from comment #0) > filing a separate issue to fix libstdc++ Fixed in r10-7103-gc222eabcf8be0e3f644e4bd4c3316b40dba4b514 libstdc++: Fix invalid noexcept-specifier (PR 94117) G++ fails to diagnose this non-dependent expression, but Clang doesn't like it. PR c++/94117 * include/std/ranges (ranges::transform_view::_Iterator::iter_move): Change expression in noexcept-specifier to match function body.
Oh we have more occurrences of it in libstdc++, e.g. in split_view friend constexpr decltype(auto) iter_move(const _InnerIter& __i) noexcept(noexcept(__iter_move())) { return __iter_move(__i); } friend constexpr void iter_swap(const _InnerIter& __x, const _InnerIter& __y) noexcept(noexcept(__iter_swap())) requires indirectly_swappable<iterator_t<_Base>> { __iter_swap(__x, __y); }
Ah, I understand what is happening. We don't defer parsing of the noexcept specified of friend functions. That leads us to construct a base-link expr whose type contains the deferred parse exception specification of the *static* member function -- there being only one, it doesn't get unknown type. In processing the deferred exception specification of that fn, we don't fixup all the type variants that might have been created. There's a restriction on friend declarations that contain default args. This is the same problem that is trying to avoid.
Yes, it was a conscious decision not to defer parsing of noexcept-spec of friend functions. The standard currently doesn't say we shouldn't defer, but no compiler implements it. The problem was that friend declarations can be redeclared and it would be tricky to see if their noexcept-specs match.
(In reply to Jonathan Wakely from comment #5) > Oh we have more occurrences of it in libstdc++, e.g. in split_view Fixed in r10-7108-gcf0c3a457319df1e8dc9321227162a7c57169a39
Discussing on the core list https://lists.isocpp.org/core/2020/03/8632.php (password required) I have a fix the the problem I encountered on the modules branch. Not suitable at this stage for trunk, and there's probably a better solution out there. As Marek says 'nobody implements this'
commit r10-7103-gc222eabcf8be0e3f644e4bd4c3316b40dba4b514 Author: Jonathan Wakely <jwakely@redhat.com> Date: Tue Mar 10 10:50:40 2020 +0000 libstdc++: Fix invalid noexcept-specifier (PR 94117) G++ fails to diagnose this non-dependent expression, but Clang doesn't like it. PR c++/94117 * include/std/ranges (ranges::transform_view::_Iterator::iter_move): Change expression in noexcept-specifier to match function body.