https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85765

            Bug ID: 85765
           Summary: Missing SFINAE in default template argument
           Product: gcc
           Version: 8.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ensadc at mailnesia dot com
  Target Milestone: ---

https://wandbox.org/permlink/lxHtJOjvghJiLiIO

----
struct il { il(); il(const il&); };

int* begin(il);

template<class T> T&& declval();

template<class T, class U = decltype(begin(declval<T&>())), decltype(*U(),0) =
0>
U g(T& t, long) { return begin(t); } // #1

template<class T>
int g(T& t, ...); // #2

volatile il a;

auto n = g(a, 0); // calls #1 and ends with a hard error, should call #2

----
prog.cc: In instantiation of 'U g(T&, long int) [with T = volatile il; U =
int*; decltype (((* U()), 0)) <anonymous> = 0]':
prog.cc:15:16:   required from here
prog.cc:8:31: error: binding reference of type 'const il&' to 'volatile il'
discards qualifiers
 U g(T& t, long) { return begin(t); } // #1
                          ~~~~~^~~
prog.cc:1:19: note:   initializing argument 1 of 'il::il(const il&)'
 struct il { il(); il(const il&); };
                   ^~
prog.cc:3:6: note:   initializing argument 1 of 'int* begin(il)'
 int* begin(il);
      ^~~~~

----
#1 should be SFINAE'ed out because `declval<T&>()` (of type `volatile il&`) is
not convertible to the parameter of `begin` (of type `il`), so #2 should called
without causing an error. But instead g++ 8.1 selects #1 and emits a hard
error.

g++ 7.3 and before calls #2, as do Clang and MSVC. g++ 8 and later will call #2
if ", decltype(*U(),0) = 0" is removed.

Reply via email to