Bug 64514

Summary: [4.9/5 Regression] Error in template instantiation in GCC 4.9, works fine in GCC 4.8
Product: gcc Reporter: Freddie Chopin <freddie.chopin>
Component: c++Assignee: Jason Merrill <jason>
Status: RESOLVED FIXED    
Severity: normal CC: jason, ville.voutilainen
Priority: P3 Keywords: rejects-valid
Version: 4.9.2   
Target Milestone: 4.9.3   
Host: Target:
Build: Known to work: 4.8.2
Known to fail: 4.9.1, 5.0 Last reconfirmed: 2015-01-12 00:00:00

Description Freddie Chopin 2015-01-06 20:37:39 UTC
The test code below works perfectly fine with GCC 4.8 (and 4.7):

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

#include <type_traits>

template<typename T, T &object, typename... Args>
struct Functor
{
	template<float (T::*function)(Args...), Args... args>
	struct Inner
	{
		float operator()() const
		{
			return (object.*function)(args...);
		}
	};
};

class Object
{
public:

	float someFunction()
	{
		return {};
	}

	float someFunctionWithArgument(int)
	{
		return {};
	}
};

Object object;

Functor<Object, object>::Inner<&Object::someFunction> functor1;
Functor<Object, object, int>::Inner<&Object::someFunctionWithArgument, 1> functor2;

int main()
{

}

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

However with GCC 4.9 it fails with a rather unhelpful message at the point of instantiation of functor1:

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

$ g++ -std=c++11 test.cpp 
test.cpp: In instantiation of ‘struct Functor<Object, (* & object)>’:
test.cpp:33:24:   required from here
test.cpp:7:9: error: wrong number of template arguments (2, should be 1)
  struct Inner
         ^
test.cpp:7:9: error: provided for ‘template<class T, T& object, class ... Args> template<float (T::* function)(Args ...), Args ...args> struct Functor<T, object, Args>::Inner’
test.cpp:7:9: error: wrong number of template arguments (2, should be 1)
test.cpp:7:9: error: provided for ‘template<class T, T& object, class ... Args> template<float (T::* function)(Args ...), Args ...args> struct Functor<T, object, Args>::Inner’
test.cpp:33:26: error: ‘Inner’ in ‘struct Functor<Object, (* & object)>’ does not name a template type
 Functor<Object, object>::Inner<&Object::someFunction> functor1;
                          ^

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

If I comment the line with functor1 instantiation, everything else (functor2) works fine.

At the stackoverflow question I asked ( http://stackoverflow.com/questions/27802404/error-in-template-instantiation-in-gcc-4-9-works-fine-in-gcc-4-8?noredirect=1#comment44015634_27802404 ) it was reported that clang 3.5 and Visual Studio 2015 Preview accept this code, while intel 14 errors out (with an unreported message) and solaris studio 12.4 crashes.

Is there something wrong with this code (which was working for me for over 2 years with older versions) or maybe this is a regression?
Comment 1 Freddie Chopin 2015-01-12 20:54:11 UTC
The question at stackoverflow has an answer with much simpler test-case which also shows the problem. http://stackoverflow.com/a/27810002/157344

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

template<typename... T>
struct Functor
{
    template <T...>
    struct Inner
    {};
};

template struct Functor<>::Inner<>;

int main()
{

}

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

Compiled with GCC 4.9.2:

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

$ g++ -std=c++11 test.cpp 
test.cpp: In instantiation of ‘struct Functor<>’:
test.cpp:9:26:   required from here
test.cpp:5:12: error: wrong number of template arguments (1, should be 0)
     struct Inner
            ^
test.cpp:5:12: error: provided for ‘template<class ... T> template<T ...<anonymous> > struct Functor<T>::Inner’
test.cpp:5:12: error: wrong number of template arguments (1, should be 0)
test.cpp:5:12: error: provided for ‘template<class ... T> template<T ...<anonymous> > struct Functor<T>::Inner’
test.cpp:9:28: error: ‘Inner’ is not a class template
 template struct Functor<>::Inner<>;
                            ^
test.cpp:9:28: error: ‘Inner’ in ‘struct Functor<>’ does not name a type

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

Works fine with GCC 4.8.

The answer also suggests there might be another similar bug, possibly related to the first one.
Comment 2 Jason Merrill 2015-01-13 21:05:08 UTC
Author: jason
Date: Tue Jan 13 21:04:35 2015
New Revision: 219558

URL: https://gcc.gnu.org/viewcvs?rev=219558&root=gcc&view=rev
Log:
	PR c++/64514
	* pt.c (coerce_template_parameter_pack): Return NULL for a
	zero-length fixed parameter pack with a pack expansion arg.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/variadic165.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
Comment 3 Jason Merrill 2015-01-28 17:21:41 UTC
Author: jason
Date: Wed Jan 28 17:21:06 2015
New Revision: 220210

URL: https://gcc.gnu.org/viewcvs?rev=220210&root=gcc&view=rev
Log:
	PR c++/64514
	* pt.c (coerce_template_parameter_pack): Return NULL for a
	zero-length fixed parameter pack with a pack expansion arg.

Added:
    branches/gcc-4_9-branch/gcc/testsuite/g++.dg/cpp0x/variadic165.C
Modified:
    branches/gcc-4_9-branch/gcc/cp/ChangeLog
    branches/gcc-4_9-branch/gcc/cp/pt.c
Comment 4 Jason Merrill 2015-01-28 17:21:56 UTC
Fixed for 4.9.3/5