Bug 79064 - Cannot overload member function templates on type of literal
Summary: Cannot overload member function templates on type of literal
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: 8.0
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
: 84465 (view as bug list)
Depends on:
Blocks:
 
Reported: 2017-01-11 19:11 UTC by Hubert Tong
Modified: 2021-08-12 02:10 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-02-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hubert Tong 2017-01-11 19:11:15 UTC
In the case below, the signatures of the two member templates are distinct.
GCC appears to have a problem recognizing that the types of 1 and 1ll differ.
Neither Clang nor MSVC appears to have this issue.

### Source (<stdin>):
struct A {
  template <unsigned M>
  void f(char (*)[0u - 1 > (M - M) ? 42 : 47]);
  template <unsigned M>
  void f(char (*)[0u - 1ll > (M - M) ? 42 : 47]);
};

void f(A a) {
  char x[42], y[47];
  a.f<0>(&x);
  a.f<0>(&y);
}


### Compile command:
g++ -c -o a.o -x c++ -


### Actual output:
<stdin>:5:8: error: 'template<unsigned int M> void A::f(char (*)[(((0 - 1) > (M - M)) ? 42 : 47)])' cannot be overloaded
<stdin>:3:8: error: with 'template<unsigned int M> void A::f(char (*)[(((0 - 1) > (M - M)) ? 42 : 47)])'
<stdin>: In function 'void f(A)':
<stdin>:11:12: error: no matching function for call to 'A::f<0>(char (*)[47])'
<stdin>:3:8: note: candidate: template<unsigned int M> void A::f(char (*)[(((0 - 1) > (M - M)) ? 42 : 47)])
<stdin>:3:8: note:   template argument deduction/substitution failed:
<stdin>:11:10: note:   cannot convert '& y' (type 'char (*)[47]') to type 'char (*)[42]'


### Expected output:
(Clean compile)


### g++ -v:
Using built-in specs.
COLLECT_GCC=/usr/local/gcc-head/bin/g++
COLLECT_LTO_WRAPPER=/usr/local/gcc-head/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /home/heads/gcc/gcc-source/configure --prefix=/usr/local/gcc-head --enable-languages=c,c++ --enable-lto --disable-multilib --without-ppl --without-cloog-ppl --enable-checking=release --disable-nls
Thread model: posix
gcc version 7.0.0 20161219 (experimental) (GCC)
Comment 1 Hubert Tong 2018-02-16 15:52:39 UTC
This appears to have been fixed on trunk.
Comment 2 Martin Sebor 2018-02-16 22:37:05 UTC
r254843 appears to have fixed this:

r254843 | jason | 2017-11-16 15:13:48 -0500 (Thu, 16 Nov 2017) | 15 lines

	PR c++/79092 - non-type args of different types are different
Comment 3 Martin Sebor 2018-02-16 22:37:25 UTC
Author: msebor
Date: Fri Feb 16 22:36:53 2018
New Revision: 257769

URL: https://gcc.gnu.org/viewcvs?rev=257769&root=gcc&view=rev
Log:
gcc/testsuite/ChangeLog:

	PR c++/79064
	* g++.dg/overload15.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/template/overload15.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 4 Andreas Schwab 2018-02-17 16:02:52 UTC
FAIL: g++.dg/template/overload15.C  -std=c++11 (test for excess errors)
Excess errors:
/daten/aranym/gcc/gcc-20180217/gcc/testsuite/g++.dg/template/overload15.C:14:10: error: call of overloaded 'f<0>(char (*)[1])' is ambiguous
/daten/aranym/gcc/gcc-20180217/gcc/testsuite/g++.dg/template/overload15.C:15:10: error: no matching function for call to 'f<0>(char (*)[7])'
Comment 5 Martin Sebor 2018-02-18 22:37:01 UTC
The failure only appears only on some targets (it would be helpful if you mentioned the target where you see a test fail when posting test results).

The test doesn't fail in my local build on x86_64.

There also is no failure in the results for

hppa-unknown-linux-gnu
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01199.html   <<<

hppa2.0w-hp-hpux11.11:
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01220.html

ia64-suse-linux-gnu:
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01211.html

powerpc64le-unknown-linux-gnu:
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01224.html

x86_64-pc-linux-gnu:
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01202.html


I do see failures on the following targets:

powerpc-ibm-aix7.2.0.0
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01225.html

aarch64-suse-linux-gnu:
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01218.html

hppa-unknown-linux-gnu
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01228.html   <<<

m68k-unknown-linux-gnu
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01215.html

powerpc64-unknown-linux-gnu:
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01229.html

s390x-ibm-linux-gnu zEC12:
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01217.html

s390x-ibm-linux-gnu default
https://gcc.gnu.org/ml/gcc-testresults/2018-02/msg01212.html


What's interesting is that between two recent hppa-unknown-linux-gnu builds the test is reported to fail in one but not the other (see <<< above).
Comment 6 Christophe Lyon 2018-02-19 08:54:08 UTC
Also seen on arm* targets:
/gcc/testsuite/g++.dg/template/overload15.C:14:10: error: call of overloaded 'f<0>(char (*)[1])' is ambiguous
/gcc/testsuite/g++.dg/template/overload15.C:15:10: error: no matching function for call to 'f<0>(char (*)[7])'


Unlike you, I do see the new test pass on aarch64, except if I also use -mabi=ilp32. Is your aarch64-suse-linux-gnu configured with ilp32 by default?
Comment 7 nsz 2018-02-19 15:38:23 UTC
*** Bug 84465 has been marked as a duplicate of this bug. ***
Comment 8 Jakub Jelinek 2018-02-19 18:48:25 UTC
It fails on i686-linux too, I bet pretty much all ILP32 targets.
So, either we can go for something like:
--- gcc/testsuite/g++.dg/template/overload15.C.jj	2018-02-16 23:37:28.682364104 +0100
+++ gcc/testsuite/g++.dg/template/overload15.C	2018-02-19 19:42:39.408037955 +0100
@@ -1,11 +1,17 @@
 // PR c++79064 - Cannot overload member function templates on type of literal
 // { dg-do compile }
 
+#if __SIZEOF_LONG_LONG__ > __SIZEOF_INT__
 template <unsigned N>
 void f (char (*)[0u - 1 > N ? 1 : 7]);
 
+#if __SIZEOF_LONG__ > __SIZEOF_INT__
 template <unsigned N>
 void f (char (*)[0u - 1l > N ? 1 : 7]);
+#else
+template <unsigned N>
+void f (char (*)[0u - 1ll > N ? 1 : 7]);
+#endif
 
 void f ()
 {
@@ -14,3 +20,6 @@ void f ()
   f<0>(&x);
   f<0>(&y);
 }
+#else
+int i;
+#endif

or, assuming on all targets we support long long is wider than int (I think that is the case on all current targets) just a simple:
2018-02-19  Jakub Jelinek  <jakub@redhat.com>

	PR c++/79064
	* g++.dg/template/overload15.C (f): Use 0u - 1ll instead of 0u - 1l.

--- gcc/testsuite/g++.dg/template/overload15.C.jj	2018-02-16 23:37:28.682364104 +0100
+++ gcc/testsuite/g++.dg/template/overload15.C	2018-02-19 19:45:48.771094113 +0100
@@ -5,7 +5,7 @@ template <unsigned N>
 void f (char (*)[0u - 1 > N ? 1 : 7]);
 
 template <unsigned N>
-void f (char (*)[0u - 1l > N ? 1 : 7]);
+void f (char (*)[0u - 1ll > N ? 1 : 7]);
 
 void f ()
 {

which I'll commit momentarily.
Even on x86_64-linux, you should have spotted when adding the testcase,
make check-c++-all RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} dg.exp=overload15.C'
reproduces the problem and is something people should do to catch issues like this.
Comment 9 Jakub Jelinek 2018-02-19 18:49:53 UTC
Author: jakub
Date: Mon Feb 19 18:49:21 2018
New Revision: 257818

URL: https://gcc.gnu.org/viewcvs?rev=257818&root=gcc&view=rev
Log:
	PR c++/79064
	* g++.dg/template/overload15.C (f): Use 0u - 1ll instead of 0u - 1l.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/template/overload15.C
Comment 10 Martin Liška 2018-11-19 14:45:34 UTC
Jakub: Can the bug be marked as resolved?
Comment 11 Jakub Jelinek 2018-11-19 14:51:37 UTC
The fix has been committed by Jason.  I'd say it is fixed though.