As we go through each of the template parameters, substituting it with corresponding template arguments, an incorrect argument list might cause us to index argument vectors past their length (or fail in the preceding tree checks). Avoid such dereferences and instead issue an error (if requested) if we find the argument index to be past the parameter vector length.
Regstrapped on i686- and x86_64-linux-gnu. Ok to install? for gcc/cp/ChangeLog PR c++/71251 * pt.c (tsubst): Test for and report out-of-range template parms. for gcc/testsuite/ChangeLog PR c++/71251 * g++.dg/cpp0x/pr71251.C: New. --- gcc/cp/pt.c | 27 +++++++++++++++++++++++---- gcc/testsuite/g++.dg/cpp0x/pr71251.C | 9 +++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr71251.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fa9bfb12c297..4cc18d0abe78 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13976,11 +13976,30 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (level <= levels && TREE_VEC_LENGTH (TMPL_ARGS_LEVEL (args, level)) > 0) { - arg = TMPL_ARG (args, level, idx); + if (TREE_VEC_LENGTH (TMPL_ARGS_LEVEL (args, level)) > idx) + { + arg = TMPL_ARG (args, level, idx); - /* See through ARGUMENT_PACK_SELECT arguments. */ - if (arg && TREE_CODE (arg) == ARGUMENT_PACK_SELECT) - arg = argument_pack_select_arg (arg); + /* See through ARGUMENT_PACK_SELECT arguments. */ + if (arg && TREE_CODE (arg) == ARGUMENT_PACK_SELECT) + arg = argument_pack_select_arg (arg); + } + else + { + if (complain & tf_error) + { + /* ??? We could use a better location for this + message. It takes the context of the closing + bracket of the innermost template we're + substituting, but the error may very well be + related with some enclosing context. */ + error ("missing template argument at this" + " or enclosing context"); + error_at (DECL_SOURCE_LOCATION (TEMPLATE_PARM_DECL (t)), + "for substitution of template parameter"); + } + arg = error_mark_node; + } } if (arg == error_mark_node) diff --git a/gcc/testsuite/g++.dg/cpp0x/pr71251.C b/gcc/testsuite/g++.dg/cpp0x/pr71251.C new file mode 100644 index 000000000000..f16fb13cccc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr71251.C @@ -0,0 +1,9 @@ +// { dg-do compile { target c++11 } } + +template<int,int> template<typename> using U=void; // { dg-error "parameter" } + +template<typename,typename> struct S1; + +template<typename T> struct S1<T,U< + T>>{ template<typename> struct S2:S2<T>{}; }; // { dg-error "missing" } +//^ the error should be here, but it is^here, thus the weird line break -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer