union A {}; struct B { template <class T> struct C {}; }; template <class F, template <class T> class D = B::template C> struct E; template <typename R, template <class T> class D> struct E <R (), D> { void (*f) (A &); template <class I, template <class T> class J> struct G { static void d (A &); }; template <class H> inline E (H &fn) { f = &(G <H, D>::d); } }; template <typename R, template <class T> class D> struct E <R (), D>::G <R (*) (), D> { }; struct Z { int z; }; int main () { Z t = {}; E <int ()> f (t); } ICEs in tsubst_template_parms, because parms is NULL. The ICE started in between r128000 and r128500.
H.J. can you help finding the offending commit?
It is caused by revision 128076: http://gcc.gnu.org/ml/gcc-cvs/2007-09/msg00070.html
Thanks H.J. let's add Jason in CC.
This code is actually ill-formed; the specialization template <typename R, template <class T> class D> struct E <R (), D>::G <R (*) (), D> { }; only has one template-header, and should have two. Furthermore, this is a full specialization of a member of a partial specialization, which is not allowed. 14.8/16: "the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well."
Perhaps errors introduced during my testcase reduction. The original bugreport is https://bugzilla.redhat.com/show_bug.cgi?id=858351
Author: jason Date: Thu Dec 6 14:37:04 2012 New Revision: 194249 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194249 Log: PR c++/54653 * parser.c (cp_parser_class_head): A partial specialization scope counts as a template. * pt.c (tsubst_template_parms): Handle template template parm parms. (tsubst_decl) [TEMPLATE_DECL]: Handle getting a template template argument back. Added: trunk/gcc/testsuite/g++.dg/template/partial-specialization2.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/parser.c trunk/gcc/cp/pt.c
Fixed for 4.8, not backporting fixes for invalid code bugs.