aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c121
1 files changed, 85 insertions, 36 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index da3cd23..1e6c044 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -152,7 +152,6 @@ static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
static bool check_specialization_scope (void);
static tree process_partial_specialization (tree);
static void set_current_access_from_decl (tree);
-static void check_default_tmpl_args (tree, tree, int, int);
static tree get_template_base (tree, tree, tree, tree);
static tree try_class_unification (tree, tree, tree, tree);
static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
@@ -3377,14 +3376,24 @@ process_partial_specialization (tree decl)
/* Check that a template declaration's use of default arguments is not
invalid. Here, PARMS are the template parameters. IS_PRIMARY is
nonzero if DECL is the thing declared by a primary template.
- IS_PARTIAL is nonzero if DECL is a partial specialization. */
+ IS_PARTIAL is nonzero if DECL is a partial specialization.
+
-static void
-check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
+ IS_FRIEND_DECL is nonzero if DECL is a friend function template
+ declaration (but not a definition); 1 indicates a declaration, 2
+ indicates a redeclaration. When IS_FRIEND_DECL=2, no errors are
+ emitted for extraneous default arguments.
+
+ Returns TRUE if there were no errors found, FALSE otherwise. */
+
+bool
+check_default_tmpl_args (tree decl, tree parms, int is_primary,
+ int is_partial, int is_friend_decl)
{
const char *msg;
int last_level_to_check;
tree parm_level;
+ bool no_errors = true;
/* [temp.param]
@@ -3397,7 +3406,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
/* You can't have a function template declaration in a local
scope, nor you can you define a member of a class template in a
local scope. */
- return;
+ return true;
if (current_class_type
&& !TYPE_BEING_DEFINED (current_class_type)
@@ -3417,40 +3426,49 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
declared, so there's no need to do it again now. This function
was defined in class scope, but we're processing it's body now
that the class is complete. */
- return;
-
- /* [temp.param]
+ return true;
- If a template-parameter has a default template-argument, all
- subsequent template-parameters shall have a default
- template-argument supplied. */
- for (parm_level = parms; parm_level; parm_level = TREE_CHAIN (parm_level))
+ /* Core issue 226 (C++0x only): the following only applies to class
+ templates. */
+ if (!flag_cpp0x || TREE_CODE (decl) != FUNCTION_DECL)
{
- tree inner_parms = TREE_VALUE (parm_level);
- int ntparms = TREE_VEC_LENGTH (inner_parms);
- int seen_def_arg_p = 0;
- int i;
+ /* [temp.param]
- for (i = 0; i < ntparms; ++i)
- {
- tree parm = TREE_VEC_ELT (inner_parms, i);
+ If a template-parameter has a default template-argument, all
+ subsequent template-parameters shall have a default
+ template-argument supplied. */
+ for (parm_level = parms; parm_level; parm_level = TREE_CHAIN (parm_level))
+ {
+ tree inner_parms = TREE_VALUE (parm_level);
+ int ntparms = TREE_VEC_LENGTH (inner_parms);
+ int seen_def_arg_p = 0;
+ int i;
- if (parm == error_mark_node)
- continue;
+ for (i = 0; i < ntparms; ++i)
+ {
+ tree parm = TREE_VEC_ELT (inner_parms, i);
- if (TREE_PURPOSE (parm))
- seen_def_arg_p = 1;
- else if (seen_def_arg_p)
- {
- error ("no default argument for %qD", TREE_VALUE (parm));
- /* For better subsequent error-recovery, we indicate that
- there should have been a default argument. */
- TREE_PURPOSE (parm) = error_mark_node;
- }
- }
+ if (parm == error_mark_node)
+ continue;
+
+ if (TREE_PURPOSE (parm))
+ seen_def_arg_p = 1;
+ else if (seen_def_arg_p)
+ {
+ error ("no default argument for %qD", TREE_VALUE (parm));
+ /* For better subsequent error-recovery, we indicate that
+ there should have been a default argument. */
+ TREE_PURPOSE (parm) = error_mark_node;
+ no_errors = false;
+ }
+ }
+ }
}
- if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary)
+ if ((!flag_cpp0x && TREE_CODE (decl) != TYPE_DECL)
+ || is_partial
+ || !is_primary
+ || is_friend_decl)
/* For an ordinary class template, default template arguments are
allowed at the innermost level, e.g.:
template <class T = int>
@@ -3461,8 +3479,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
The template parameter list of a specialization shall not
contain default template argument values.
- So, for a partial specialization, or for a function template,
- we look at all of them. */
+ So, for a partial specialization, or for a function template
+ (in C++98/C++03), we look at all of them. */
;
else
/* But, for a primary class template that is not a partial
@@ -3471,7 +3489,11 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
parms = TREE_CHAIN (parms);
/* Figure out what error message to issue. */
- if (TREE_CODE (decl) == FUNCTION_DECL)
+ if (is_friend_decl == 2)
+ msg = "default template arguments may not be used in function template friend re-declaration";
+ else if (is_friend_decl)
+ msg = "default template arguments may not be used in function template friend declarations";
+ else if (TREE_CODE (decl) == FUNCTION_DECL && !flag_cpp0x)
msg = "default template arguments may not be used in function templates";
else if (is_partial)
msg = "default template arguments may not be used in partial specializations";
@@ -3510,6 +3532,10 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
{
if (msg)
{
+ no_errors = false;
+ if (is_friend_decl == 2)
+ return no_errors;
+
error (msg, decl);
msg = 0;
}
@@ -3525,6 +3551,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
if (msg)
msg = "default argument for template parameter for class enclosing %qD";
}
+
+ return no_errors;
}
/* Worker for push_template_decl_real, called via
@@ -3652,7 +3680,7 @@ push_template_decl_real (tree decl, bool is_friend)
/* Check to see that the rules regarding the use of default
arguments are not being violated. */
check_default_tmpl_args (decl, current_template_parms,
- primary, is_partial);
+ primary, is_partial, /*is_friend_decl=*/0);
/* Ensure that there are no parameter packs in the type of this
declaration that have not been expanded. */
@@ -11346,6 +11374,27 @@ type_unification_real (tree tparms,
&& !saw_undeduced++)
goto again;
+ /* Core issue #226 (C++0x) [temp.deduct]:
+
+ If a template argument has not been deduced, its
+ default template argument, if any, is used.
+
+ When we are not in C++0x mode (i.e., !flag_cpp0x),
+ TREE_PURPOSE will either be NULL_TREE or ERROR_MARK_NODE,
+ so we do not need to explicitly check flag_cpp0x here. */
+ if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)))
+ {
+ tree arg = tsubst (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)),
+ targs, tf_none, NULL_TREE);
+ if (arg == error_mark_node)
+ return 1;
+ else
+ {
+ TREE_VEC_ELT (targs, i) = arg;
+ continue;
+ }
+ }
+
return 2;
}