diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2005-06-06 17:29:41 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2005-06-06 17:29:41 +0000 |
commit | 5e97d404553157c7d74c399907b60125111f130f (patch) | |
tree | d1edb6ce6bd660310edc4d54628d90e79e651a0b /gcc | |
parent | 2fecaef4af7206fbae14906000e8c81007514706 (diff) | |
download | gcc-5e97d404553157c7d74c399907b60125111f130f.zip gcc-5e97d404553157c7d74c399907b60125111f130f.tar.gz gcc-5e97d404553157c7d74c399907b60125111f130f.tar.bz2 |
re PR c++/21903 (Default argument of template function causes a compile-time error)
cp:
PR 21903
* cp-tree.def (DEFAULT_ARG): Document TREE_CHAIN use.
* parser.c (cp_parser_late_parsing_default_args): Propagate parsed
argument to any early instantiations.
* pt.c (tsubst_arg_types): Chain early instantiation of default arg.
testsuite:
PR 21903
* g++.dg/parse/defarg9.C: New.
From-SVN: r100669
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 22 | ||||
-rw-r--r-- | gcc/cp/pt.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/defarg9.C | 20 |
6 files changed, 69 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 758451c..e493e10 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2005-06-06 Nathan Sidwell <nathan@codesourcery.com> + PR 21903 + * cp-tree.def (DEFAULT_ARG): Document TREE_CHAIN use. + * parser.c (cp_parser_late_parsing_default_args): Propagate parsed + argument to any early instantiations. + * pt.c (tsubst_arg_types): Chain early instantiation of default arg. + PR c++/20637 * cp-tree.h (add_method): Add using_decl parameter. * class.c (add_method): Add using_decl parameter. Adjust error diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index c42dbfb..2728467 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -206,7 +206,9 @@ DEFTREECODE (USING_DECL, "using_decl", tcc_declaration, 0) /* A using directive. The operand is USING_STMT_NAMESPACE. */ DEFTREECODE (USING_STMT, "using_directive", tcc_statement, 1) -/* An un-parsed default argument. Looks like an IDENTIFIER_NODE. */ +/* An un-parsed default argument. Looks like an IDENTIFIER_NODE. + TREE_CHAIN is used to hold instantiations of functions that had to + be instantiated before the argument was parsed. */ DEFTREECODE (DEFAULT_ARG, "default_arg", tcc_exceptional, 0) /* A template-id, like foo<int>. The first operand is the template. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 65442c7..c0059d0 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15593,19 +15593,29 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) parm = TREE_CHAIN (parm)) { cp_token_cache *tokens; - - if (!TREE_PURPOSE (parm) - || TREE_CODE (TREE_PURPOSE (parm)) != DEFAULT_ARG) + tree default_arg = TREE_PURPOSE (parm); + tree parsed_arg; + + if (!default_arg) continue; + gcc_assert (TREE_CODE (default_arg) == DEFAULT_ARG); + /* Push the saved tokens for the default argument onto the parser's lexer stack. */ - tokens = DEFARG_TOKENS (TREE_PURPOSE (parm)); + tokens = DEFARG_TOKENS (default_arg); cp_parser_push_lexer_for_tokens (parser, tokens); /* Parse the assignment-expression. */ - TREE_PURPOSE (parm) = cp_parser_assignment_expression (parser, - /*cast_p=*/false); + parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false); + + TREE_PURPOSE (parm) = parsed_arg; + + /* Update any instantiations we've already created. */ + for (default_arg = TREE_CHAIN (default_arg); + default_arg; + default_arg = TREE_CHAIN (default_arg)) + TREE_PURPOSE (TREE_PURPOSE (default_arg)) = parsed_arg; /* If the token stream has not been completely used up, then there was extra junk after the end of the default diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ad1e5f3..7924bbe 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6704,6 +6704,8 @@ tsubst_arg_types (tree arg_types, { tree remaining_arg_types; tree type; + tree default_arg; + tree result = NULL_TREE; if (!arg_types || arg_types == void_list_node) return arg_types; @@ -6731,12 +6733,25 @@ tsubst_arg_types (tree arg_types, top-level qualifiers as required. */ type = TYPE_MAIN_VARIANT (type_decays_to (type)); - /* Note that we do not substitute into default arguments here. The - standard mandates that they be instantiated only when needed, - which is done in build_over_call. */ - return hash_tree_cons (TREE_PURPOSE (arg_types), type, - remaining_arg_types); - + /* We do not substitute into default arguments here. The standard + mandates that they be instantiated only when needed, which is + done in build_over_call. */ + default_arg = TREE_PURPOSE (arg_types); + + if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG) + { + /* We've instantiated a template before its default arguments + have been parsed. This can happen for a nested template + class, and is not an error unless we require the default + argument in a call of this function. */ + result = tree_cons (default_arg, type, remaining_arg_types); + TREE_CHAIN (default_arg) = tree_cons (result, NULL_TREE, + TREE_CHAIN (default_arg)); + } + else + result = hash_tree_cons (default_arg, type, remaining_arg_types); + + return result; } /* Substitute into a FUNCTION_TYPE or METHOD_TYPE. This routine does diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9061d5f..a89b7fe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2005-06-06 Nathan Sidwell <nathan@codesourcery.com> + PR 21903 + * g++.dg/parse/defarg9.C: New. + PR c++/20637 * g++.dg/inherit/using4.C: New. * g++.dg/overload/error1.C: Adjust expected errors. diff --git a/gcc/testsuite/g++.dg/parse/defarg9.C b/gcc/testsuite/g++.dg/parse/defarg9.C new file mode 100644 index 0000000..8496cfb --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/defarg9.C @@ -0,0 +1,20 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 6 Jun 2005 <nathan@codesourcery.com> + +// PR 21903:Reject legal with default arg confusion +// Origin: Wolfgang Bangerth <bangerth@dealii.org> + + +struct O { + template<typename T> struct B { + void set (T, bool=true); + }; + + struct D : public B<int> {}; +}; + +void x () +{ + O::D d; + d.set(1); +} |