Index: cp/pt.c =================================================================== --- cp/pt.c (revision 130268) +++ cp/pt.c (working copy) @@ -8653,7 +8653,24 @@ tsubst_exception_specification (tree fnt expanded_specs = tsubst_pack_expansion (TREE_VALUE (specs), args, complain, in_decl); - len = TREE_VEC_LENGTH (expanded_specs); + + if (expanded_specs == error_mark_node) + return error_mark_node; + else if (TREE_CODE (expanded_specs) == TREE_VEC) + len = TREE_VEC_LENGTH (expanded_specs); + else + { + /* We're substituting into a member template, so + we got a TYPE_PACK_EXPANSION back. Add that + expansion and move on. */ + gcc_assert (TREE_CODE (expanded_specs) + == TYPE_PACK_EXPANSION); + new_specs = add_exception_specifier (new_specs, + expanded_specs, + complain); + specs = TREE_CHAIN (specs); + continue; + } } for (i = 0; i < len; ++i) Index: testsuite/g++.dg/cpp0x/variadic-throw.C =================================================================== --- testsuite/g++.dg/cpp0x/variadic-throw.C (revision 0) +++ testsuite/g++.dg/cpp0x/variadic-throw.C (revision 0) @@ -0,0 +1,20 @@ +// { dg-options -std=c++0x } +// PR c++/33509 +template struct pair +{ + int i, j; + pair() : i(M), j(N) {} +}; + +template struct S +{ + template static int foo() throw (pair ...) + { + return 1; + } +}; + +int bar () +{ + return S<0, 1, 2>::foo<0, 1, 3> (); +}