Bug 88655

Summary: Different overloaded function being called depending on which compiler is used
Product: gcc Reporter: Dominique Pelle <dominique.pelle>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: webrown.cpp
Priority: P3 Keywords: wrong-code
Version: unknown   
Target Milestone: ---   
See Also: https://bugs.llvm.org/show_bug.cgi?id=40193
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77712
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description Dominique Pelle 2019-01-02 09:46:10 UTC
The following program behaves differently
between gcc and clang. Overloaded function
foo(...) gets resolved differently depending
on which compiler is used. It outputs
3 different kinds of outputs depending on
which compiler or compiler version is used:

$ cat foo.cpp

#include <cstdio>
#include <cstdint>

struct Foo
{
  Foo(std::int64_t)
  {
  }
};

void foo(const char*)
{
  std::puts("In foo(const char*)");
}

void foo(const Foo&)
{
  std::puts("In foo(const Foo&)");
}

int main()
{
  foo((int)0);
  foo((unsigned)0);
  foo((short)0);
  foo((unsigned short)0);
  foo((std::int64_t)0);
  foo((std::uint64_t)0);
  foo(0);
  foo(NULL);
  foo(nullptr);
}


With g++-8 (Ubuntu 8.1.0-5ubuntu1~16.04) 8.1.0
or   g++-7 (Ubuntu 7.4.0-1ubuntu1~16.04~ppa1) 7.4.0
or   g++-6 (Ubuntu 6.5.0-2ubuntu1~16.04) 6.5.0 20181026

$ g++-8 -std=c++11 foo.cpp
$ ./a.out 
In foo(const Foo&)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)

With g++-5 (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609:

$ g++-5 -std=c++11 foo.cpp
$ ./a.out
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)

Notice that the first call results in a different overload being called.


With clang version 7.0.0-svn338141-1~exp1+0~20180727181251.1677~1.gbpcccb1b (trunk)
or clang version 6.0.1-svn334776-1~exp1~20181018153226.114 (branches/release_60)
or clang version 5.0.2 (tags/RELEASE_502/final)
or clang version 4.0.0-1ubuntu1~16.04.2 (tags/RELEASE_400/rc1)
or clang version 3.9.1-4ubuntu3~16.04.2 (tags/RELEASE_391/rc2)

$ clang++-7 -std=c++11 foo.cpp
$ ./a.out
In foo(const Foo&)
In foo(const Foo&)
In foo(const Foo&)
In foo(const Foo&)
In foo(const Foo&)
In foo(const Foo&)
In foo(const char*)
In foo(const char*)
In foo(const char*)

Notice that clang resolve overload completely differently
than any version of gcc!?

I initially reported this as a clang bug in
https://bugs.llvm.org/show_bug.cgi?id=40193
albeit with a different program, which I decided
to simplify here to avoid a boost dependency.
According to comments in the clang ticket, it's
a gcc bug. Hence this bug report.
Comment 1 Andrew Pinski 2019-01-02 10:17:46 UTC
Using C++98 (on a LP64 target) and:
typedef unsigned long uint64_t;
typedef long int64_t;

struct Foo { Foo(int64_t) { } };

void foo(const char*)
{
  std::puts("In foo(const char*)");
}

void foo(const Foo&)
{
  std::puts("In foo(const Foo&)");
}

int main()
{
  foo((int)0);
  foo((unsigned)0);
  foo((short)0);
  foo((unsigned short)0);
  foo((int64_t)0);
  foo((uint64_t)0);
  foo(0);
  foo(NULL);
}
--- CUT ---
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)

As you can see that is the "old" behavior.
With -std=c++11, I get:
In foo(const Foo&)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
In foo(const char*)
Comment 2 Andrew Pinski 2019-01-02 10:20:28 UTC
Most likely a dup of bug 52145 and related to PR 77712.
Comment 3 Andrew Pinski 2021-12-04 06:43:46 UTC
Dup of bug 52145.

*** This bug has been marked as a duplicate of bug 52145 ***