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

            Bug ID: 70505
           Summary: Constexpr failure when template type specified
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vince.rev at gmail dot com
  Target Milestone: ---

This bug seems to affect g++ 4.9, 5.1, 5.2, 5.3 and 6.0 (tested on
gcc.godbolt.org), while the same code compiles under g++ 4.7.3, 4.8.1 and 4.8.2
as well as under clang. 

The code is the following:
=============================================
#include <iostream>

template <class X> 
struct s
{
        template <class T> 
        static constexpr T f1(const T x) {return x;}
        template <class T, T = f1<T>(sizeof(T))> 
        static constexpr T f2(const T x) {return x;} 
        static void f() {s<int>::f2(42);}
};

int main()
{
    s<int>::f();
}
=============================================

and the error is:

=============================================
main.cpp:10:39: error: no matching function for call to ‘s<int>::f2(int)’
         static void f() {s<int>::f2(42);}
                                       ^
main.cpp:9:28: note: candidate: template<class T, T <anonymous> > static
constexpr T s<X>::f2(T) [with T = T; T <anonymous> = <enumerator>; X = int]
         static constexpr T f2(const T x) {return x;} 
                            ^
main.cpp:9:28: note:   template argument deduction/substitution failed:
main.cpp:8:47: error: expression ‘f1<int>’ is not a constant-expression
         template <class T, T = f1<T>(sizeof(T))> 
                                               ^
main.cpp:8:47: note: in template argument for type ‘int’ 
=============================================

The bug does not show up when the line n°8 is modified to:

=============================================
#include <iostream>

template <class X> 
struct s
{
        template <class T> 
        static constexpr T f1(const T x) {return x;}
        template <class T, T = f1(sizeof(T))> 
        static constexpr T f2(const T x) {return x;} 
        static void f() {s<int>::f2(42);}
};

int main()
{
    s<int>::f();
}
=============================================

Reply via email to