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

Reply via email to