public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "lhyatt at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/84920] Better handling of unmatched/ambiguous calls Date: Wed, 08 Jun 2022 22:04:08 +0000 [thread overview] Message-ID: <bug-84920-4-HKz1gjB5sh@http.gcc.gnu.org/bugzilla/> (raw) In-Reply-To: <bug-84920-4@http.gcc.gnu.org/bugzilla/> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920 Lewis Hyatt <lhyatt at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |lhyatt at gcc dot gnu.org --- Comment #8 from Lewis Hyatt <lhyatt at gcc dot gnu.org> --- Created attachment 53108 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53108&action=edit One possible approach Hello- What do you all think of this approach? The new options -foverload-candidates-reduce-level and -foverload-candidates-stop-level would configure the amount of information that is output regarding overload candidates. When the number of overloads exceeds -foverload-candidates-reduce-level (default 3), then the source lines are no longer printed for each candidate, cutting the output length in half. The source lines seem rarely useful anyway, since the diagnostic's first line already prints the overload being considered. When the number of overloads exceeds -foverload-candidates-stop-level (default 7), none of the overloads is printed, since this is presumably a case such as a heavily overloaded operator where the large number of candidates is less likely to be helpful in fixing the problem. For a testcase like this common (for me) typo: ============= #include <ostream> void f(std::ostream& o, int a) { o << a < '\n'; } ============= GCC then outputs: ============= iowarn.cpp: In function ‘void f(std::ostream&, int)’: iowarn.cpp:3:12: error: no match for ‘operator<’ (operand types are ‘std::basic_ostream<char>’ and ‘char’) 3 | o << a < '\n'; | ~~~~~~ ^ ~~~~ | | | | | char | std::basic_ostream<char> iowarn.cpp:3:12: note: declining to output 15 candidates (limit 7); compile with ‘-foverload-candidates-stop-level=15’ to see them ============= which at least for this specific case feels like an improvement to me... It's obvious what is wrong now. If you follow the suggestion and add the flag to the compile, then you see: ============= iowarn.cpp: In function ‘void f(std::ostream&, int)’: iowarn.cpp:3:12: error: no match for ‘operator<’ (operand types are ‘std::basic_ostream<char>’ and ‘char’) 3 | o << a < '\n'; | ~~~~~~ ^ ~~~~ | | | | | char | std::basic_ostream<char> iowarn.cpp:3:12: note: candidate: ‘operator<(int, int)’ (built-in) iowarn.cpp:3:12: note: no known conversion for argument 1 from ‘std::basic_ostream<char>’ to ‘int’ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/string:46, from /home/lewis/gccdev/release/include/c++/13.0.0/bits/locale_classes.h:40, from /home/lewis/gccdev/release/include/c++/13.0.0/bits/ios_base.h:41, from /home/lewis/gccdev/release/include/c++/13.0.0/ios:42, from /home/lewis/gccdev/release/include/c++/13.0.0/ostream:38, from iowarn.cpp:1: /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:451:5: note: candidate: ‘template<class _Iterator> constexpr bool std::operator<(const reverse_iterator<_Iterator>&, const reverse_iterator<_Iterator>&)’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:451:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::reverse_iterator<_Iterator>’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:496:5: note: candidate: ‘template<class _IteratorL, class _IteratorR> constexpr bool std::operator<(const reverse_iterator<_Iterator>&, const reverse_iterator<_IteratorR>&)’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:496:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::reverse_iterator<_Iterator>’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:1683:5: note: candidate: ‘template<class _IteratorL, class _IteratorR> constexpr bool std::operator<(const move_iterator<_IteratorL>&, const move_iterator<_IteratorR>&)’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:1683:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::move_iterator<_IteratorL>’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:1748:5: note: candidate: ‘template<class _Iterator> constexpr bool std::operator<(const move_iterator<_IteratorL>&, const move_iterator<_IteratorL>&)’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:1748:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::move_iterator<_IteratorL>’ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_algobase.h:64, from /home/lewis/gccdev/release/include/c++/13.0.0/string:49: /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_pair.h:665:5: note: candidate: ‘template<class _T1, class _T2> constexpr bool std::operator<(const pair<_T1, _T2>&, const pair<_T1, _T2>&)’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_pair.h:665:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::pair<_T1, _T2>’ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:47, from /home/lewis/gccdev/release/include/c++/13.0.0/string:52: /home/lewis/gccdev/release/include/c++/13.0.0/string_view:594:5: note: candidate: ‘template<class _CharT, class _Traits> constexpr bool std::operator<(basic_string_view<_CharT, _Traits>, basic_string_view<_CharT, _Traits>)’ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:594:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘std::basic_string_view<_CharT, _Traits>’ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:600:5: note: candidate: ‘template<class _CharT, class _Traits> constexpr bool std::operator<(basic_string_view<_CharT, _Traits>, __type_identity_t<basic_string_view<_CharT, _Traits> >)’ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:600:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘std::basic_string_view<_CharT, _Traits>’ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:607:5: note: candidate: ‘template<class _CharT, class _Traits> constexpr bool std::operator<(__type_identity_t<basic_string_view<_CharT, _Traits> >, basic_string_view<_CharT, _Traits>)’ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:607:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: mismatched types ‘std::basic_string_view<_CharT, _Traits>’ and ‘char’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3690:5: note: candidate: ‘template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3690:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3703:5: note: candidate: ‘template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const _CharT*)’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3703:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3715:5: note: candidate: ‘template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)’ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3715:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: mismatched types ‘const _CharT*’ and ‘std::basic_ostream<char>’ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/bits/memory_resource.h:47, from /home/lewis/gccdev/release/include/c++/13.0.0/string:56: /home/lewis/gccdev/release/include/c++/13.0.0/tuple:1538:5: note: candidate: ‘template<class ... _TElements, class ... _UElements> constexpr bool std::operator<(const tuple<_UTypes ...>&, const tuple<_UTypes ...>&)’ /home/lewis/gccdev/release/include/c++/13.0.0/tuple:1538:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::tuple<_UTypes ...>’ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/bits/ios_base.h:46: /home/lewis/gccdev/release/include/c++/13.0.0/system_error:314:3: note: candidate: ‘bool std::operator<(const error_code&, const error_code&)’ /home/lewis/gccdev/release/include/c++/13.0.0/system_error:314:31: note: no known conversion for argument 1 from ‘std::basic_ostream<char>’ to ‘const std::error_code&’ /home/lewis/gccdev/release/include/c++/13.0.0/system_error:495:3: note: candidate: ‘bool std::operator<(const error_condition&, const error_condition&)’ /home/lewis/gccdev/release/include/c++/13.0.0/system_error:495:36: note: no known conversion for argument 1 from ‘std::basic_ostream<char>’ to ‘const std::error_condition&’ ============= This is still half the length of the current output, because the source lines are not printed. The current output is: ============= iowarn.cpp: In function ‘void f(std::ostream&, int)’: iowarn.cpp:3:12: error: no match for ‘operator<’ (operand types are ‘std::basic_ostream<char>’ and ‘char’) 3 | o << a < '\n'; | ~~~~~~ ^ ~~~~ | | | | | char | std::basic_ostream<char> iowarn.cpp:3:12: note: candidate: ‘operator<(int, int)’ (built-in) 3 | o << a < '\n'; | ~~~~~~~^~~~~~ iowarn.cpp:3:12: note: no known conversion for argument 1 from ‘std::basic_ostream<char>’ to ‘int’ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/string:46, from /home/lewis/gccdev/release/include/c++/13.0.0/bits/locale_classes.h:40, from /home/lewis/gccdev/release/include/c++/13.0.0/bits/ios_base.h:41, from /home/lewis/gccdev/release/include/c++/13.0.0/ios:42, from /home/lewis/gccdev/release/include/c++/13.0.0/ostream:38, from iowarn.cpp:1: /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:451:5: note: candidate: ‘template<class _Iterator> constexpr bool std::operator<(const reverse_iterator<_Iterator>&, const reverse_iterator<_Iterator>&)’ 451 | operator<(const reverse_iterator<_Iterator>& __x, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:451:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::reverse_iterator<_Iterator>’ 3 | o << a < '\n'; | ^~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:496:5: note: candidate: ‘template<class _IteratorL, class _IteratorR> constexpr bool std::operator<(const reverse_iterator<_Iterator>&, const reverse_iterator<_IteratorR>&)’ 496 | operator<(const reverse_iterator<_IteratorL>& __x, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:496:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::reverse_iterator<_Iterator>’ 3 | o << a < '\n'; | ^~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:1683:5: note: candidate: ‘template<class _IteratorL, class _IteratorR> constexpr bool std::operator<(const move_iterator<_IteratorL>&, const move_iterator<_IteratorR>&)’ 1683 | operator<(const move_iterator<_IteratorL>& __x, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:1683:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::move_iterator<_IteratorL>’ 3 | o << a < '\n'; | ^~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:1748:5: note: candidate: ‘template<class _Iterator> constexpr bool std::operator<(const move_iterator<_IteratorL>&, const move_iterator<_IteratorL>&)’ 1748 | operator<(const move_iterator<_Iterator>& __x, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_iterator.h:1748:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::move_iterator<_IteratorL>’ 3 | o << a < '\n'; | ^~~~ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_algobase.h:64, from /home/lewis/gccdev/release/include/c++/13.0.0/string:49: /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_pair.h:665:5: note: candidate: ‘template<class _T1, class _T2> constexpr bool std::operator<(const pair<_T1, _T2>&, const pair<_T1, _T2>&)’ 665 | operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/stl_pair.h:665:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::pair<_T1, _T2>’ 3 | o << a < '\n'; | ^~~~ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:47, from /home/lewis/gccdev/release/include/c++/13.0.0/string:52: /home/lewis/gccdev/release/include/c++/13.0.0/string_view:594:5: note: candidate: ‘template<class _CharT, class _Traits> constexpr bool std::operator<(basic_string_view<_CharT, _Traits>, basic_string_view<_CharT, _Traits>)’ 594 | operator< (basic_string_view<_CharT, _Traits> __x, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:594:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘std::basic_string_view<_CharT, _Traits>’ 3 | o << a < '\n'; | ^~~~ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:600:5: note: candidate: ‘template<class _CharT, class _Traits> constexpr bool std::operator<(basic_string_view<_CharT, _Traits>, __type_identity_t<basic_string_view<_CharT, _Traits> >)’ 600 | operator< (basic_string_view<_CharT, _Traits> __x, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:600:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘std::basic_string_view<_CharT, _Traits>’ 3 | o << a < '\n'; | ^~~~ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:607:5: note: candidate: ‘template<class _CharT, class _Traits> constexpr bool std::operator<(__type_identity_t<basic_string_view<_CharT, _Traits> >, basic_string_view<_CharT, _Traits>)’ 607 | operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/string_view:607:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: mismatched types ‘std::basic_string_view<_CharT, _Traits>’ and ‘char’ 3 | o << a < '\n'; | ^~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3690:5: note: candidate: ‘template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)’ 3690 | operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3690:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>’ 3 | o << a < '\n'; | ^~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3703:5: note: candidate: ‘template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const _CharT*)’ 3703 | operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3703:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>’ 3 | o << a < '\n'; | ^~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3715:5: note: candidate: ‘template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)’ 3715 | operator<(const _CharT* __lhs, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/bits/basic_string.h:3715:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: mismatched types ‘const _CharT*’ and ‘std::basic_ostream<char>’ 3 | o << a < '\n'; | ^~~~ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/bits/memory_resource.h:47, from /home/lewis/gccdev/release/include/c++/13.0.0/string:56: /home/lewis/gccdev/release/include/c++/13.0.0/tuple:1538:5: note: candidate: ‘template<class ... _TElements, class ... _UElements> constexpr bool std::operator<(const tuple<_UTypes ...>&, const tuple<_UTypes ...>&)’ 1538 | operator<(const tuple<_TElements...>& __t, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/tuple:1538:5: note: template argument deduction/substitution failed: iowarn.cpp:3:14: note: ‘std::basic_ostream<char>’ is not derived from ‘const std::tuple<_UTypes ...>’ 3 | o << a < '\n'; | ^~~~ In file included from /home/lewis/gccdev/release/include/c++/13.0.0/bits/ios_base.h:46: /home/lewis/gccdev/release/include/c++/13.0.0/system_error:314:3: note: candidate: ‘bool std::operator<(const error_code&, const error_code&)’ 314 | operator<(const error_code& __lhs, const error_code& __rhs) noexcept | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/system_error:314:31: note: no known conversion for argument 1 from ‘std::basic_ostream<char>’ to ‘const std::error_code&’ 314 | operator<(const error_code& __lhs, const error_code& __rhs) noexcept | ~~~~~~~~~~~~~~~~~~^~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/system_error:495:3: note: candidate: ‘bool std::operator<(const error_condition&, const error_condition&)’ 495 | operator<(const error_condition& __lhs, | ^~~~~~~~ /home/lewis/gccdev/release/include/c++/13.0.0/system_error:495:36: note: no known conversion for argument 1 from ‘std::basic_ostream<char>’ to ‘const std::error_condition&’ 495 | operator<(const error_condition& __lhs, | ~~~~~~~~~~~~~~~~~~~~~~~^~~~~ ============= Perhaps the default thresholds of 3 and 7 could be tuned better based on experience, but I hope maybe it's at least a useful framework to set up? If so then the patch is ready to go and I could send it to gcc-patches. Thanks for taking a look! -Lewis
next prev parent reply other threads:[~2022-06-08 22:04 UTC|newest] Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <bug-84920-4@http.gcc.gnu.org/bugzilla/> 2020-03-12 11:58 ` jakub at gcc dot gnu.org 2021-06-01 8:10 ` rguenth at gcc dot gnu.org 2021-11-16 17:32 ` tdb at tdb dot fi 2022-01-02 11:59 ` redi at gcc dot gnu.org 2022-06-08 22:04 ` lhyatt at gcc dot gnu.org [this message] 2022-06-09 11:19 ` redi at gcc dot gnu.org 2022-06-09 13:37 ` lhyatt at gcc dot gnu.org
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-84920-4-HKz1gjB5sh@http.gcc.gnu.org/bugzilla/ \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).