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

             Bug #: 53606
           Summary: Invalid candidate chosen; warning message claims to
                    know better than the Standard
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: hst...@ca.ibm.com
              Host: powerpc64-unknown-linux-gnu
            Target: powerpc64-unknown-linux-gnu


GCC emits a warning stating that the template-dependent call in the type of
a parameter of a function template instantiation is ambiguous according to the
Standard.

It then fails to remove the candidate despite what should then be substitution
failure.

I am not quite sure how GCC found one of the operator+ overloads to be better
than the other, but whatever mechanism is being used, it should not interfere
with the translation of a well-formed program.


### Self-contained source (op_overload_sfinae.cpp):> cat op_overload_sfinae.cpp
template <typename T>
struct false_ { enum : bool { value = false }; };

struct A {
template <typename T>
int operator +(const T &) const;
};

template <typename T>
int operator +(const A &, const T &);

const int &lv_const_int();

template <typename T>
T &lv_T();

template <typename T>
void foo(void *, char * = 0) { }

template <typename T>
void foo(int, char (*)[sizeof (lv_T<T>() + lv_const_int(), 0)] = 0) {
   static_assert(false_<T>::value,
"If the warning is correct, then the Standard says I should not see this.");
}

int main() {
   foo<A>(0);
}


### Compiler invocation:
g++-4.7.0 -c op_overload_sfinae.cpp -std=c++11


### Compiler output:
op_overload_sfinae.cpp: In instantiation of 'void foo(int, char (*)[sizeof
(((lv_T<T>() + lv_const_int()), 0))]) [with T = A]':
op_overload_sfinae.cpp:27:12:   required from here
op_overload_sfinae.cpp:21:66: warning: ISO C++ says that these are ambiguous,
even though the worst conversion for the first is better than the worst
conversion for the second: [enabled by default]
op_overload_sfinae.cpp:10:5: note: candidate 1: int operator+(const A&, const
T&) [with T = int]
op_overload_sfinae.cpp:6:5: note: candidate 2: int A::operator+(const T&) const
[with T = int]
op_overload_sfinae.cpp:22:4: error: static assertion failed: If the warning is
correct, then the Standard says I should not see this.


### g++ -v output:> g++-4.7.0 -v
Using built-in specs.
COLLECT_GCC=g++-4.7.0
COLLECT_LTO_WRAPPER=/data/gcc/libexec/gcc/powerpc64-unknown-linux-gnu/4.7.0/lto-wrapper
Target: powerpc64-unknown-linux-gnu
Configured with: ../gcc-4.7.0/configure --prefix=/data/gcc
--program-suffix=-4.7.0 --disable-libssp --disable-libgcj
--enable-version-specific-runtime-libs --with-cpu=default32 --enable-secureplt
--with-long-double-128 --

enable-shared --enable-__cxa_atexit --enable-threads=posix
--enable-languages=c,c++,fortran --with-mpfr=/usr/local/ --with-mpc=/usr/local/
--with-gmp=/usr/local/
Thread model: posix
gcc version 4.7.0 (GCC)

Reply via email to