[Bug c++/84920] Better handling of unmatched/ambiguous calls

2022-06-09 Thread lhyatt at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

--- Comment #10 from Lewis Hyatt  ---
(In reply to Jonathan Wakely from comment #9)
> That looks pretty good to me. What does it produce for the operator<<
> example in comment 1?

With the default options:
=
iowarn2.cpp: In function ‘void f(std::ostream&, const A&)’:
iowarn2.cpp:13:5: error: no match for ‘operator<<’ (operand types are
‘std::ostream’ {aka ‘std::basic_ostream’} and ‘const A’)
   13 |   o << a;
  |   ~ ^~ ~
  |   ||
  |   |const A
  |   std::ostream {aka std::basic_ostream}
iowarn2.cpp:13:5: note: declining to output 34 candidates (limit 7); compile
with ‘-foverload-candidates-stop-level=34’ to see them
=

With the suggestion from the diagnostic -foverload-candidates-stop-level=34, so
this is the ~50% abbreviated mode:
=
iowarn2.cpp: In function ‘void f(std::ostream&, const A&)’:
iowarn2.cpp:13:5: error: no match for ‘operator<<’ (operand types are
‘std::ostream’ {aka ‘std::basic_ostream’} and ‘const A’)
   13 |   o << a;
  |   ~ ^~ ~
  |   ||
  |   |const A
  |   std::ostream {aka std::basic_ostream}
In file included from iowarn2.cpp:1:
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:7: note: candidate:
‘std::basic_ostream<_CharT, _Traits>::__ostream_type&
std::basic_ostream<_CharT, _Traits>::operator<<(__ostream_type&
(*)(__ostream_type&)) [with _CharT = char; _Traits = std::char_traits;
__ostream_type = std::basic_ostream]’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:36: note:   no known
conversion for argument 1 from ‘const A’ to
‘std::basic_ostream::__ostream_type&
(*)(std::basic_ostream::__ostream_type&)’ {aka ‘std::basic_ostream&
(*)(std::basic_ostream&)’}
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:7: note: candidate:
‘std::basic_ostream<_CharT, _Traits>::__ostream_type&
std::basic_ostream<_CharT, _Traits>::operator<<(__ios_type& (*)(__ios_type&))
[with _CharT = char; _Traits = std::char_traits; __ostream_type =
std::basic_ostream; __ios_type = std::basic_ios]’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:32: note:   no known
conversion for argument 1 from ‘const A’ to
‘std::basic_ostream::__ios_type&
(*)(std::basic_ostream::__ios_type&)’ {aka ‘std::basic_ios&
(*)(std::basic_ios&)’}
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:7: note: candidate:
‘std::basic_ostream<_CharT, _Traits>::__ostream_type&
std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base&
(*)(std::ios_base&)) [with _CharT = char; _Traits = std::char_traits;
__ostream_type = std::basic_ostream]’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:30: note:   no known
conversion for argument 1 from ‘const A’ to ‘std::ios_base&
(*)(std::ios_base&)’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:7: note: candidate:
‘std::basic_ostream<_CharT, _Traits>::__ostream_type&
std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char;
_Traits = std::char_traits; __ostream_type = std::basic_ostream]’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:23: note:   no known
conversion for argument 1 from ‘const A’ to ‘long int’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:7: note: candidate:
‘std::basic_ostream<_CharT, _Traits>::__ostream_type&
std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT
= char; _Traits = std::char_traits; __ostream_type =
std::basic_ostream]’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:32: note:   no known
conversion for argument 1 from ‘const A’ to ‘long unsigned int’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:7: note: candidate:
‘std::basic_ostream<_CharT, _Traits>::__ostream_type&
std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char;
_Traits = std::char_traits; __ostream_type = std::basic_ostream]’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:23: note:   no known
conversion for argument 1 from ‘const A’ to ‘bool’
In file included from
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:833:
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:91:5: note:
candidate: ‘std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
_Traits>::operator<<(short int) [with _CharT = char; _Traits =
std::char_traits]’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:92:22: note:  
no known conversion for argument 1 from ‘const A’ to ‘short int’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:7: note: candidate:
‘std::basic_ostream<_CharT, _Traits>::__ostream_type&
std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with
_CharT = char; _Traits = std::char_traits; __ostream_type =
std::basic_ostream]’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:33: note:   no known
conversion for argument 1 from ‘const A’ to ‘short unsigned int’
/home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:105:5: 

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2022-06-09 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

--- Comment #9 from Jonathan Wakely  ---
That looks pretty good to me. What does it produce for the operator<< example
in comment 1?

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2022-06-08 Thread lhyatt at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

Lewis Hyatt  changed:

   What|Removed |Added

 CC||lhyatt at gcc dot gnu.org

--- Comment #8 from Lewis Hyatt  ---
Created attachment 53108
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53108=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 
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’ and ‘char’)
3 | o << a < '\n';
  | ~~ ^ 
  |   |  |
  |   |  char
  |   std::basic_ostream
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’ and ‘char’)
3 | o << a < '\n';
  | ~~ ^ 
  |   |  |
  |   |  char
  |   std::basic_ostream
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’ 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 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’ 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 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’ 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 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’ 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 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’ 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 constexpr bool 

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2022-01-02 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

Jonathan Wakely  changed:

   What|Removed |Added

   Target Milestone|9.5 |---

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2021-11-16 Thread tdb at tdb dot fi via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

Mikko Rasa  changed:

   What|Removed |Added

 CC||tdb at tdb dot fi

--- Comment #7 from Mikko Rasa  ---
Is this still being worked on?  I regularly run into spammy output, especially
with the == and != operators.  Just now I accidentally used std::find on an
std::map, which obviously didn't work - but spewed nearly 500 lines of notes
about all the operator== overloads it considered from several stdlib headers. 
At that point the notes cease to be useful and just make it harder to find out
where the actual error was.  This occurs with both g++-10 and g++-11.

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2021-06-01 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

Richard Biener  changed:

   What|Removed |Added

   Target Milestone|9.4 |9.5

--- Comment #6 from Richard Biener  ---
GCC 9.4 is being released, retargeting bugs to GCC 9.5.

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2020-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|9.3 |9.4

--- Comment #5 from Jakub Jelinek  ---
GCC 9.3.0 has been released, adjusting target milestone.

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2019-08-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|9.2 |9.3

--- Comment #4 from Jakub Jelinek  ---
GCC 9.2 has been released.

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2019-05-03 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|9.0 |9.2

--- Comment #3 from Jakub Jelinek  ---
GCC 9.1 has been released.

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2018-06-18 Thread egallager at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

Eric Gallager  changed:

   What|Removed |Added

 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2018-06-18
 CC||egallager at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #2 from Eric Gallager  ---
(In reply to David Malcolm from comment #0)
> As reported by user "jcoffland" on Hacker News:
> https://news.ycombinator.com/item?id=16598071
> 
> > One improvement I'd like to see is a simplified error message
> > for mismatched overloaded calls. If you make an overloaded call
> > for which the is no matching conversion or if the conversation is
> > ambiguous the compiler will "helpfully" dump a list of possibly
> > matching overloaded function signatures. The list can be hundreds
> > of lines long.
> >
> > For example, when you try to pipe a class to std::cout that
> > doesn't have an std::ostream <<(std::ostream &, const X &).
> > Perhaps instead of dumping the complete function signatures it
> > could show one function signature followed by a list of types
> > accepted as the second parameter. Since the signatures are
> > otherwise the same. Such improvements could also reduce
> > template error spew.
> 
> I hope to have a look at this in the GCC 9 timeframe, so filing this here.

OK, changing status to ASSIGNED then

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2018-03-19 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

--- Comment #1 from Jonathan Wakely  ---
(In reply to David Malcolm from comment #0)
> As reported by user "jcoffland" on Hacker News:
> https://news.ycombinator.com/item?id=16598071
> 
> > One improvement I'd like to see is a simplified error message
> > for mismatched overloaded calls. If you make an overloaded call
> > for which the is no matching conversion or if the conversation is
> > ambiguous the compiler will "helpfully" dump a list of possibly
> > matching overloaded function signatures. The list can be hundreds
> > of lines long.

It's rare to get hundreds of lines in general. That usually only happens for
iostream operator<< and operator>>, because not many operators have as many
overloads all in the same namespace. But a general solution wouldn't hurt. 


> > For example, when you try to pipe a class to std::cout that
> > doesn't have an std::ostream <<(std::ostream &, const X &).
> > Perhaps instead of dumping the complete function signatures it
> > could show one function signature followed by a list of types
> > accepted as the second parameter. Since the signatures are
> > otherwise the same.

I like the idea, but this isn't *strictly* true, as there's a function template
taking an rvalue stream as the first parameter, but that should accept all the
same types as the version for lvalue streams, so showing it doesn't add much
value.

The other advantages of the signatures is that they include the location info,
so if an overload doesn't match because of a SFINAE constraint you can go and
check the source, e.g. given

#include 
template struct A { T value; };

template
auto operator<<(std::ostream& o, const A& a)
-> decltype(o << a.value)
{ return o << a.value; }

struct Y { };

void f(std::ostream& o, const A& a)
{
  o << a;
}

Included in the output is:

a.cc:5:6: note: candidate: template decltype ((o << a.value))
operator<<(std::ostream&, const A&)
 auto operator<<(std::ostream& o, const A& a)
  ^~~~
a.cc:5:6: note:   template argument deduction/substitution failed:
a.cc: In substitution of ‘template decltype ((o << a.value))
operator<<(std::ostream&, const A&) [with T = Y]’:
a.cc:13:8:   required from here
a.cc:6:15: error: no match for ‘operator<<’ (operand types are ‘std::ostream
{aka std::basic_ostream}’ and ‘const Y’)
 -> decltype(o << a.value)
 ~~^~

which points to a.cc:5:6 as the location of the overload, and the expression at
a.cc:6:15 is potentially useful infomration.

Maybe we could special-case the overloads from namespace std, since they are
usually less interesting. Usually.


More generally, maybe add -foverload-candidates-limit=N so if the overload set
is above the limit don't show the notes with the reasons overload resolution
failed, just show the candidates.

[Bug c++/84920] Better handling of unmatched/ambiguous calls

2018-03-16 Thread dmalcolm at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920

David Malcolm  changed:

   What|Removed |Added

   Assignee|unassigned at gcc dot gnu.org  |dmalcolm at gcc dot 
gnu.org
   Target Milestone|--- |9.0