aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-04-05 15:29:02 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-04-05 15:29:02 -0400
commit53b39fe5dc093b8ff51bd95940dd6cc3404b585c (patch)
tree58c5580fb0ac381c8d134e5f6b5a55f0922a8817 /gcc
parent12633413c6a0c00e21075294205cd432daa4461b (diff)
downloadgcc-53b39fe5dc093b8ff51bd95940dd6cc3404b585c.zip
gcc-53b39fe5dc093b8ff51bd95940dd6cc3404b585c.tar.gz
gcc-53b39fe5dc093b8ff51bd95940dd6cc3404b585c.tar.bz2
re PR c++/14912 (Do not print default template arguments in error messages)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/error.c67
-rw-r--r--gcc/testsuite/g++.dg/template/error39.C11
3 files changed, 74 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 688b1a8..8def05c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 8b31980..a97017a 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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
index 0000000..ef0bda2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error39.C
@@ -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"> }
+}