Bug 55992 - constexpr static member function not recognised in templated using statement
Summary: constexpr static member function not recognised in templated using statement
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.1
: P3 normal
Target Milestone: 7.0
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2013-01-15 16:01 UTC by Walter Dehnen
Modified: 2016-05-25 09:52 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.8.0, 4.9.3, 5.1.0, 6.0
Last reconfirmed: 2016-03-14 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Walter Dehnen 2013-01-15 16:01:50 UTC
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)
Comment 1 Daniel Krügler 2013-01-15 22:01:16 UTC
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)
Comment 2 Drea Pinski 2013-01-15 22:04:42 UTC
Confirmed, a work around is to do:
  using my_array = A<test::pole(P)>;
Comment 3 Paolo Carlini 2013-01-23 12:30:13 UTC
Let's add Dodji in CC.
Comment 4 Paolo Carlini 2014-09-26 16:42:11 UTC
An alias declaration seems necessary to trigger the bug, eg doesn't affect:

  template<unsigned P>
  struct my_array : A<pole(P)> { };
Comment 5 Jason Merrill 2014-11-17 21:39:35 UTC
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.
Comment 6 Paolo Carlini 2014-11-18 09:54:40 UTC
I see... So far I haven't been able to make much progress on c++/15272 itself, thus feel free to reassign.
Comment 7 Martin Sebor 2016-03-15 03:23:36 UTC
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
               ~~^~~
Comment 8 Paolo Carlini 2016-05-25 09:40:18 UTC
This is fixed in trunk. I'm adding a testcase or two and closing the bug.
Comment 9 paolo@gcc.gnu.org 2016-05-25 09:51:18 UTC
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
Comment 10 Paolo Carlini 2016-05-25 09:52:18 UTC
Fixed.