re PR c++/14912 (Do not print default template arguments in error messages)
authorJason Merrill <jason@redhat.com>
Sun, 5 Apr 2009 19:29:02 +0000 (15:29 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 5 Apr 2009 19:29:02 +0000 (15:29 -0400)
        PR c++/14912
        * error.c (count_non_default_template_args): New fn.
        (dump_template_parms): Call it.
        (dump_template_argument_list): Call it.  Add parms parm.
        (dump_template_argument): Adjust call to dump_template_argument_list.
        (dump_type, dump_decl): Likewise.
        (dump_template_bindings): Refactor logic.

From-SVN: r145566

gcc/cp/ChangeLog
gcc/cp/error.c
gcc/testsuite/g++.dg/template/error39.C [new file with mode: 0644]

index 688b1a8441e5504244038fd6d04b0609603ba596..8def05c08dc4e4e9b734de61b7312c7f22fba98a 100644 (file)
@@ -1,3 +1,13 @@
+2009-04-05  Jason Merrill  <jason@redhat.com>
+
+       PR c++/14912
+       * error.c (count_non_default_template_args): New fn.
+       (dump_template_parms): Call it.
+       (dump_template_argument_list): Call it.  Add parms parm.
+       (dump_template_argument): Adjust call to dump_template_argument_list.
+       (dump_type, dump_decl): Likewise.
+       (dump_template_bindings): Refactor logic.
+
 2009-04-03  Jason Merrill  <jason@redhat.com>
 
        PR c++/25185
index 8b31980331f1987199194905c6f9b8c11cf796b6..a97017a9794e5ee6bc9806c4601a373cb5a30806 100644 (file)
@@ -73,12 +73,14 @@ static void dump_global_iord (tree);
 static void dump_parameters (tree, int);
 static void dump_exception_spec (tree, int);
 static void dump_template_argument (tree, int);
-static void dump_template_argument_list (tree, int);
+static void dump_template_argument_list (tree, tree, int);
 static void dump_template_parameter (tree, int);
 static void dump_template_bindings (tree, tree, VEC(tree,gc) *);
 static void dump_scope (tree, int);
 static void dump_template_parms (tree, int, int);
 
+static int count_non_default_template_args (tree, tree);
+
 static const char *function_category (tree);
 static void maybe_print_instantiation_context (diagnostic_context *);
 static void print_instantiation_full_context (diagnostic_context *);
@@ -140,7 +142,7 @@ static void
 dump_template_argument (tree arg, int flags)
 {
   if (ARGUMENT_PACK_P (arg))
-    dump_template_argument_list (ARGUMENT_PACK_ARGS (arg), flags);
+    dump_template_argument_list (ARGUMENT_PACK_ARGS (arg), NULL_TREE, flags);
   else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
     dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
   else
@@ -152,17 +154,49 @@ dump_template_argument (tree arg, int flags)
     }
 }
 
+/* Count the number of template arguments ARGS whose value does not
+   match the (optional) default template parameter in PARAMS  */
+
+static int
+count_non_default_template_args (tree args, tree params)
+{
+  int n = TREE_VEC_LENGTH (args);
+  int last;
+
+  if (params == NULL_TREE)
+    return n;
+
+  for (last = n - 1; last >= 0; --last)
+    {
+      tree param = TREE_VEC_ELT (params, last);
+      tree def = TREE_PURPOSE (param);
+
+      if (!def)
+        break;
+      if (uses_template_parms (def))
+       {
+         ++processing_template_decl;
+         def = tsubst_copy_and_build (def, args, tf_none, NULL_TREE, false, true);
+         --processing_template_decl;
+       }
+      if (!cp_tree_equal (TREE_VEC_ELT (args, last), def))
+        break;
+    }
+
+  return last + 1;
+}
+
 /* Dump a template-argument-list ARGS (always a TREE_VEC) under control
    of FLAGS.  */
 
 static void
-dump_template_argument_list (tree args, int flags)
+dump_template_argument_list (tree args, tree parms, int flags)
 {
-  int n = TREE_VEC_LENGTH (args);
+  int n = count_non_default_template_args (args, parms);
   int need_comma = 0;
   int i;
 
-  for (i = 0; i< n; ++i)
+  for (i = 0; i < n; ++i)
     {
       tree arg = TREE_VEC_ELT (args, i);
 
@@ -240,18 +274,19 @@ dump_template_bindings (tree parms, tree args, VEC(tree,gc)* typenames)
       int lvl = TMPL_PARMS_DEPTH (parms);
       int arg_idx = 0;
       int i;
+      tree lvl_args = NULL_TREE;
+
+      /* Don't crash if we had an invalid argument list.  */
+      if (TMPL_ARGS_DEPTH (args) >= lvl)
+       lvl_args = TMPL_ARGS_LEVEL (args, lvl);
 
       for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
        {
          tree arg = NULL_TREE;
 
          /* Don't crash if we had an invalid argument list.  */
-         if (TMPL_ARGS_DEPTH (args) >= lvl)
-           {
-             tree lvl_args = TMPL_ARGS_LEVEL (args, lvl);
-             if (NUM_TMPL_ARGS (lvl_args) > arg_idx)
-               arg = TREE_VEC_ELT (lvl_args, arg_idx);
-           }
+         if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
+           arg = TREE_VEC_ELT (lvl_args, arg_idx);
 
          if (need_comma)
            pp_separate_with_comma (cxx_pp);
@@ -365,7 +400,7 @@ dump_type (tree t, int flags)
        pp_cxx_cv_qualifier_seq (cxx_pp, t);
        pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
        pp_cxx_begin_template_argument_list (cxx_pp);
-       dump_template_argument_list (args, flags);
+       dump_template_argument_list (args, NULL_TREE, flags);
        pp_cxx_end_template_argument_list (cxx_pp);
       }
       break;
@@ -959,7 +994,7 @@ dump_decl (tree t, int flags)
        dump_decl (name, flags);
        pp_cxx_begin_template_argument_list (cxx_pp);
        if (TREE_OPERAND (t, 1))
-         dump_template_argument_list (TREE_OPERAND (t, 1), flags);
+         dump_template_argument_list (TREE_OPERAND (t, 1), NULL_TREE, flags);
        pp_cxx_end_template_argument_list (cxx_pp);
       }
       break;
@@ -1389,11 +1424,15 @@ dump_template_parms (tree info, int primary, int flags)
   if (args && !primary)
     {
       int len, ix;
+      /* We don't know the parms for a friend template specialization.  */
+      tree params = (TREE_CODE (TI_TEMPLATE (info)) == TEMPLATE_DECL
+                    ? DECL_INNERMOST_TEMPLATE_PARMS (TI_TEMPLATE (info))
+                    : NULL_TREE);
 
       if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
        args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
 
-      len = TREE_VEC_LENGTH (args);
+      len = count_non_default_template_args (args, params);
 
       for (ix = 0; ix != len; ix++)
        {
diff --git a/gcc/testsuite/g++.dg/template/error39.C b/gcc/testsuite/g++.dg/template/error39.C
new file mode 100644 (file)
index 0000000..ef0bda2
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/14912
+
+template <class T, int N=0, int X=1>
+struct A
+{
+};
+
+void foo(void)
+{
+  A<void> a = 0;               // dg-error { "A<void"> }
+}