public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/51277] New: Feature request: C++ diagnostic for ambiguous overloads
@ 2011-11-23  1:51 zeratul976 at hotmail dot com
  2011-11-23 12:34 ` [Bug c++/51277] " redi at gcc dot gnu.org
  2011-11-23 16:43 ` zeratul976 at hotmail dot com
  0 siblings, 2 replies; 3+ messages in thread
From: zeratul976 at hotmail dot com @ 2011-11-23  1:51 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51277

             Bug #: 51277
           Summary: Feature request: C++ diagnostic for ambiguous
                    overloads
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: zeratul976@hotmail.com


I have a feature request regarding a compiler diagnostic.

When a call of an overloaded function is ambiguous, and some of the candidates
are declared in namespaces other than the namespace of the call site (or one
of its parent namespaces), it would be helpful if the compiler helped us 
figure out why those candidates are visible in the namespace of the call site.

Specifically, it would be helpful if the compiler would say:

 - whether the candidate is visible 1) because it was imported into the 
   namespace of the call site (or one of its parent namespaces) via a
   using-declaration or a using-directive, OR 2) because it was found
   using argument-dependent lookup

 - in the first case, the location of the using-declaration or using-
   directive (if there are several, any one of them should suffice)

 - in the second case, the argument that triggered the argument-
   dependent lookup and why

Examples:

///////////////  EXAMPLE 1  ///////////////

namespace n1
{
    void foo(double);
}

using n1::foo;

void foo(float);

int main()
{
   foo(0);   
}

// Current diagnostic
test.cpp: In function 'int main()':
test.cpp:12:9: error: call of overloaded 'foo(int)' is ambiguous
test.cpp:12:9: note: candidates are:
test.cpp:3:10: note: void n1::foo(double)
test.cpp:8:6: note: void foo(float)

// What I would like to see
test.cpp: In function 'int main()':
test.cpp:12:9: error: call of overloaded 'foo(int)' is ambiguous
test.cpp:12:9: note: candidates are:
test.cpp:3:10: note: void n1::foo(double)
test.cpp:6:13: note: visible in global namespace because of using-declaration
located here
test.cpp:8:6: note: void foo(float)


///////////////  EXAMPLE 2  ///////////////

namespace n1
{
    struct Bar {};

    void foo(double, Bar);
}

void foo(float, n1::Bar);

int main()
{
   foo(n1::Bar());   
}

// Current diagnostic
test.cpp: In function 'int main()':
test.cpp:12:20: error: call of overloaded 'foo(int, n1::Bar)' is ambiguous
test.cpp:12:20: note: candidates are:
test.cpp:8:6: note: void foo(float, n1::Bar)
test.cpp:5:10: note: void n1::foo(double, n1::Bar)

// What I would like to see
test.cpp: In function 'int main()':
test.cpp:12:20: error: call of overloaded 'foo(int, n1::Bar)' is ambiguous
test.cpp:12:20: note: candidates are:
test.cpp:8:6: note: void foo(float, n1::Bar)
test.cpp:5:10: note: void n1::foo(double, n1::Bar)
test.cpp:3:14: note: found by argument-dependent lookup because second argument
is of type n1::Bar

//////////////////////////////////////////


Does this sound doable?


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/51277] Feature request: C++ diagnostic for ambiguous overloads
  2011-11-23  1:51 [Bug c++/51277] New: Feature request: C++ diagnostic for ambiguous overloads zeratul976 at hotmail dot com
@ 2011-11-23 12:34 ` redi at gcc dot gnu.org
  2011-11-23 16:43 ` zeratul976 at hotmail dot com
  1 sibling, 0 replies; 3+ messages in thread
From: redi at gcc dot gnu.org @ 2011-11-23 12:34 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51277

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-11-23 12:05:00 UTC ---
(In reply to comment #0)
>  - in the first case, the location of the using-declaration or using-
>    directive (if there are several, any one of them should suffice)



> // What I would like to see
> test.cpp: In function 'int main()':
> test.cpp:12:9: error: call of overloaded 'foo(int)' is ambiguous
> test.cpp:12:9: note: candidates are:
> test.cpp:3:10: note: void n1::foo(double)
> test.cpp:6:13: note: visible in global namespace because of using-declaration
> located here

Should 'global namespace' refer to the scope containing the using-declaration
or the scope containing the ambiguous call? (They're both the global namespace
in your example, but don't have to be.)
A using-directive can also appear at block scope and a using-declaration can
also appear at block scope and class scope, so the note would have to be able
to decide between printing "global namespace" vs "namespace X" vs "current
scope" vs ...?

A using-declaration /declares/ the name in that scope as a synonym for the
other entity, it doesn't just make it visible.  A using-directive just makes
the names visible.
To keep the diagnostics simpler maybe the note could just say:
  test.cpp:6:13: note: found due to using-declaration here
or
  test.cpp:6:13: note: found due to using-directive here
I think that still conveys enough information, without having to worry about
whether it's at namespace scope (and global vs named vs unnamed) or block scope
or class scope.

> // What I would like to see
> test.cpp: In function 'int main()':
> test.cpp:12:20: error: call of overloaded 'foo(int, n1::Bar)' is ambiguous
> test.cpp:12:20: note: candidates are:
> test.cpp:8:6: note: void foo(float, n1::Bar)
> test.cpp:5:10: note: void n1::foo(double, n1::Bar)
> test.cpp:3:14: note: found by argument-dependent lookup because second argument
> is of type n1::Bar

Printing "argument 2" is easier than "second argument" (or the diagnostic
machinery needs to be able to print ordinal numbers for any value in any
language!)

Would that note still be useful if it said "is of type X<Y<n1::Bar>>" ?
What about if it said "is of type Derived" where that type has n1::Bar as an
indirect base class?
Would it help to add "so n1 is an associated namespace" or would that make it
too long?

test.cpp:3:14: note: found by argument-dependent lookup because 'n1' is an
associated namespace of argument 2 of type 'n1::Bar'


> Does this sound doable?

I have no idea :)


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/51277] Feature request: C++ diagnostic for ambiguous overloads
  2011-11-23  1:51 [Bug c++/51277] New: Feature request: C++ diagnostic for ambiguous overloads zeratul976 at hotmail dot com
  2011-11-23 12:34 ` [Bug c++/51277] " redi at gcc dot gnu.org
@ 2011-11-23 16:43 ` zeratul976 at hotmail dot com
  1 sibling, 0 replies; 3+ messages in thread
From: zeratul976 at hotmail dot com @ 2011-11-23 16:43 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51277

--- Comment #2 from Nathan Ridge <zeratul976 at hotmail dot com> 2011-11-23 16:30:35 UTC ---
(In reply to comment #1)
> (In reply to comment #0)
> >  - in the first case, the location of the using-declaration or using-
> >    directive (if there are several, any one of them should suffice)
> 
> 
> 
> > // What I would like to see
> > test.cpp: In function 'int main()':
> > test.cpp:12:9: error: call of overloaded 'foo(int)' is ambiguous
> > test.cpp:12:9: note: candidates are:
> > test.cpp:3:10: note: void n1::foo(double)
> > test.cpp:6:13: note: visible in global namespace because of using-declaration
> > located here
> 
> Should 'global namespace' refer to the scope containing the using-declaration
> or the scope containing the ambiguous call? (They're both the global namespace
> in your example, but don't have to be.)
> A using-directive can also appear at block scope and a using-declaration can
> also appear at block scope and class scope, so the note would have to be able
> to decide between printing "global namespace" vs "namespace X" vs "current
> scope" vs ...?
> A using-declaration /declares/ the name in that scope as a synonym for the
> other entity, it doesn't just make it visible.  A using-directive just makes
> the names visible.
> To keep the diagnostics simpler maybe the note could just say:
>   test.cpp:6:13: note: found due to using-declaration here
> or
>   test.cpp:6:13: note: found due to using-directive here
> I think that still conveys enough information, without having to worry about
> whether it's at namespace scope (and global vs named vs unnamed) or block scope
> or class scope.

That would be fine. The key is that the compiler give me the line number where
the using declaration/directive is found. (More often than not, the using
declaration/directive shouldn't be there, and getting rid of it, or moving it
to an appropriate inner scope, resolves the ambiguity, but tracking down a
using declaration in a large codebase where a namespace can span hundreds or
thousands of files is a huge pain...)

> > // What I would like to see
> > test.cpp: In function 'int main()':
> > test.cpp:12:20: error: call of overloaded 'foo(int, n1::Bar)' is ambiguous
> > test.cpp:12:20: note: candidates are:
> > test.cpp:8:6: note: void foo(float, n1::Bar)
> > test.cpp:5:10: note: void n1::foo(double, n1::Bar)
> > test.cpp:3:14: note: found by argument-dependent lookup because second argument
> > is of type n1::Bar
> 
> Printing "argument 2" is easier than "second argument" (or the diagnostic
> machinery needs to be able to print ordinal numbers for any value in any
> language!)

You're absolutely right, my bad.

> Would that note still be useful if it said "is of type X<Y<n1::Bar>>" ?

Yes. The key here is to see the relationship between the argument type and the
associated namespace.

> What about if it said "is of type Derived" where that type has n1::Bar as an
> indirect base class?

By the above argument, no. The error should explain why n1 is an associated
namespace - in this case by mentioning that n1::Bar is a(n indirect) base class
of the argument type.

> Would it help to add "so n1 is an associated namespace" or would that make it
> too long?
> test.cpp:3:14: note: found by argument-dependent lookup because 'n1' is an
> associated namespace of argument 2 of type 'n1::Bar'

That looks fine, but again, in cases where the relationship is not obvious,
(e.g. because the name of the associated namespace does not appear anywhere in
the name of the argument type), a note that makes the relationship clear would
be helpful.

> > Does this sound doable?
> 
> I have no idea :)

I'm not familiar with GCC internals, but it seems to me that this is all
information the compiler should already have at overload resolution time... it
just needs to share it with us!


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-11-23 16:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-23  1:51 [Bug c++/51277] New: Feature request: C++ diagnostic for ambiguous overloads zeratul976 at hotmail dot com
2011-11-23 12:34 ` [Bug c++/51277] " redi at gcc dot gnu.org
2011-11-23 16:43 ` zeratul976 at hotmail dot com

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).