The compiler fails to resolve a static constexpr member function which is used in a templated using directive. For example, the following valid code --------------------------------------------------------------------------------- #include <array> template<unsigned MaxP, typename Type> struct test { static constexpr unsigned pole(unsigned P) { return P>MaxP? MaxP:P; } template<unsigned P> using my_array = std::array<Type,pole(P)>; // causing error template<unsigned P> void do_something(my_array<P> const&, my_array<P>); }; --------------------------------------------------------------------------------- produces (when compiling via g++ -c -std=c++11 test.cc using gcc 4.7.1 or 4.7.2) --------------------------------------------------------------------------------- test.cc:10:42: error: ‘pole’ was not declared in this scope --------------------------------------------------------------------------------- The compiler can be made happy by explicitly resolving ("test::pole" in line 10) or by not using my_array<> (ie. without the do_something() member)
Reduced example (free of library stuff): template<unsigned N> struct A {}; template<unsigned MaxP> struct test { static constexpr unsigned pole(unsigned P) { return P>MaxP? MaxP:P; } template<unsigned P> using my_array = A<pole(P)>; template<unsigned P> void do_something(my_array<P> const&, my_array<P>); }; The problem also occurs in gcc 4.8.0 20130113 (experimental)
Confirmed, a work around is to do: using my_array = A<test::pole(P)>;
Let's add Dodji in CC.
An alias declaration seems necessary to trigger the bug, eg doesn't affect: template<unsigned P> struct my_array : A<pole(P)> { };
This is actually related to bug 15272, it's another case where treating a member function found in phase 1 lookup the same as an unbound name causes problems.
I see... So far I haven't been able to make much progress on c++/15272 itself, thus feel free to reassign.
Reconfirmed with today's top of trunk of 6.0 and with all prior supported versions. Below is an ever-so-slightly simpler test case: $ cat v.c && /home/msebor/build/gcc-trunk-svn/gcc/xgcc -B/home/msebor/build/gcc-trunk-svn/gcc -S -Wall -Wextra -Wpedantic -xc++ v.c template <int> struct A { }; template <int I> struct B { static constexpr int f (int i) { return i; } template <int J> using C = A<f (J)>; // error C<I> c; }; v.c: In substitution of ‘template<int I> template<int J> using C = A<f(J)> [with int J = I; int I = I]’: v.c:11:6: required from here v.c:9:17: error: ‘f’ was not declared in this scope using C = A<f (J)>; // error ~~^~~
This is fixed in trunk. I'm adding a testcase or two and closing the bug.
Author: paolo Date: Wed May 25 09:50:46 2016 New Revision: 236698 URL: https://gcc.gnu.org/viewcvs?rev=236698&root=gcc&view=rev Log: 2016-05-25 Paolo Carlini <paolo.carlini@oracle.com> PR c++/55992 * g++.dg/cpp0x/alias-decl-53.C: New. * g++.dg/cpp0x/alias-decl-54.C: Likewise. Added: trunk/gcc/testsuite/g++.dg/cpp0x/alias-decl-53.C trunk/gcc/testsuite/g++.dg/cpp0x/alias-decl-54.C Modified: trunk/gcc/testsuite/ChangeLog
Fixed.