]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/21903 (Default argument of template function causes a compile-time error)
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 9 Jun 2005 07:46:23 +0000 (07:46 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 9 Jun 2005 07:46:23 +0000 (07:46 +0000)
cp:
PR c++/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++/19884
* pt.c (check_explicit_specialization): Make sure namespace
binding lookup found an overloaded function.
(lookup_template_function): Just assert FNS is an overloaded
function.
testsuite:
PR c++/19608
* parser.c (cp_parser_late_parsing_for_member): Use
current_function_decl as scope to push to and from.
testsuite:

PR 21903
* g++.dg/parse/defarg9.C: New.

PR c++/19884
* g++.old-deja/g++.oliva/template6.C: Add another case.
* g++.dg/template/explicit6.C: New.

PR c++/19608
* g++.dg/parse/local-class1.C: New.

From-SVN: r100794

gcc/cp/ChangeLog
gcc/cp/cp-tree.def
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.oliva/template6.C

index 6853265500a2ca7561aba30172d44f9bab00f21a..3197c669bfdd9ce9998709d2dca4ade39151ac00 100644 (file)
@@ -1,3 +1,23 @@
+2005-06-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/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++/19884
+       * pt.c (check_explicit_specialization): Make sure namespace
+       binding lookup found an overloaded function.
+       (lookup_template_function): Just assert FNS is an overloaded
+       function.
+
+       PR c++/19608
+       * parser.c (cp_parser_late_parsing_for_member): Use
+       current_function_decl as scope to push to and from.
+       testsuite:
+
 2005-06-08  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR c++/20563
index 36b7aaa85e83905ac6d36536e7966b89fc33551e..f6a2bee8d579bcca933e9c2f7b6a28d1cabe9245 100644 (file)
@@ -203,7 +203,9 @@ DEFTREECODE (USING_DECL, "using_decl", 'd', 0)
 /* A using directive. The operand is USING_STMT_NAMESPACE. */     
 DEFTREECODE (USING_STMT, "using_directive", 'e', 1)
 
-/* An un-parsed default argument.  Looks like an IDENTIFIER_NODE.  */
+/* An un-parsed default argument.
+   TREE_CHAIN is used to hold instantiations of functions that had to
+   be instantiated before the argument was parsed.  */
 DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 0)
 
 /* A template-id, like foo<int>.  The first operand is the template.
index 8765ff10e69eec4514a81778af2317dab6f2ff0c..d4ca762aba74b1544ab730eed6792269a1763f40 100644 (file)
@@ -14771,9 +14771,10 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
       tokens = DECL_PENDING_INLINE_INFO (member_function);
       DECL_PENDING_INLINE_INFO (member_function) = NULL;
       DECL_PENDING_INLINE_P (member_function) = 0;
-      /* If this was an inline function in a local class, enter the scope
-        of the containing function.  */
-      function_scope = decl_function_context (member_function);
+      
+      /* If this is a local class, enter the scope of the containing
+        function.  */
+      function_scope = current_function_decl;
       if (function_scope)
        push_function_context_to (function_scope);
       
@@ -14854,33 +14855,49 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
        parameters;
        parameters = TREE_CHAIN (parameters))
     {
-      if (!TREE_PURPOSE (parameters)
-         || TREE_CODE (TREE_PURPOSE (parameters)) != DEFAULT_ARG)
+      tree default_arg = TREE_PURPOSE (parameters);
+      tree parsed_arg;
+
+      if (!default_arg)
+       continue;
+
+      if (TREE_CODE (default_arg) != DEFAULT_ARG)
+       /* This can happen for a friend declaration for a function
+          already declared with default arguments.  */
        continue;
   
-       /* Save away the current lexer.  */
+      /* Save away the current lexer.  */
       saved_lexer = parser->lexer;
-       /* Create a new one, using the tokens we have saved.  */
-      tokens =  DEFARG_TOKENS (TREE_PURPOSE (parameters));
+      /* Create a new one, using the tokens we have saved.  */
+      tokens =  DEFARG_TOKENS (default_arg);
       parser->lexer = cp_lexer_new_from_tokens (tokens);
 
-       /* Set the current source position to be the location of the
-         first token in the default argument.  */
+      /* Set the current source position to be the location of the
+         first token in the default argument.  */
       cp_lexer_peek_token (parser->lexer);
 
-       /* Local variable names (and the `this' keyword) may not appear
-         in a default argument.  */
+      /* Local variable names (and the `this' keyword) may not appear
+        in a default argument.  */
       saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
       parser->local_variables_forbidden_p = true;
-       /* Parse the assignment-expression.  */
+      
+      /* Parse the assignment-expression.  */
       if (DECL_FRIEND_CONTEXT (fn))
        push_nested_class (DECL_FRIEND_CONTEXT (fn));
       else if (DECL_CLASS_SCOPE_P (fn))
        push_nested_class (DECL_CONTEXT (fn));
-      TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser);
+      parsed_arg = cp_parser_assignment_expression (parser);
       if (DECL_FRIEND_CONTEXT (fn) || DECL_CLASS_SCOPE_P (fn))
        pop_nested_class ();
-
+      
+      TREE_PURPOSE (parameters) = 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
         argument.  */
index d3cc61e9d2775861b1c9b41cc696001f42feda93..ac0f8ceae28879fe715da53abc8f6fdb22225417 100644 (file)
@@ -1779,6 +1779,11 @@ check_explicit_specialization (tree declarator,
              /* Find the namespace binding, using the declaration
                  context.  */
              fns = namespace_binding (dname, CP_DECL_CONTEXT (decl));
+             if (!fns || !is_overloaded_fn (fns))
+               {
+                 error ("`%D' is not a template function", dname);
+                 fns = error_mark_node;
+               }
            }
 
          declarator = lookup_template_function (fns, NULL_TREE);
@@ -4066,18 +4071,9 @@ lookup_template_function (tree fns, tree arglist)
     return error_mark_node;
 
   my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726);
-  if (fns == NULL_TREE 
-      || TREE_CODE (fns) == FUNCTION_DECL)
-    {
-      error ("non-template used as template");
-      return error_mark_node;
-    }
-
-  my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
-                     || TREE_CODE (fns) == OVERLOAD
-                     || BASELINK_P (fns)
-                     || TREE_CODE (fns) == IDENTIFIER_NODE,
-                     20020730);
+  my_friendly_assert (fns && (is_overloaded_fn (fns)
+                             || TREE_CODE (fns) == IDENTIFIER_NODE),
+                     20050608);
 
   if (BASELINK_P (fns))
     {
@@ -6484,6 +6480,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;
@@ -6511,12 +6509,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
index d357b42bad5003832305f5f2bf79f7321823c0df..95284782d31ce1070752693c1747efb781b757c4 100644 (file)
@@ -1,3 +1,15 @@
+2005-06-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/21903
+       * g++.dg/parse/defarg9.C: New.
+
+       PR c++/19884
+       * g++.old-deja/g++.oliva/template6.C: Add another case.
+       * g++.dg/template/explicit6.C: New.
+
+       PR c++/19608
+       * g++.dg/parse/local-class1.C: New.
+
 2005-06-08  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
        * gcc.dg/tls/debug-1.c: New test.
index f31d677afb0f06773c36950eef3f7eabb36fe8a9..270d67695f64670db04c8d274e226834bc9497c6 100644 (file)
@@ -6,4 +6,7 @@
 // simplified from bug report by Meenaradchagan Vishnu <mvishnu@fore.com>
 
 template <typename> struct foo {};
-template <> void foo(); // { dg-error "" } bad specialization
+template <> void foo(); // { dg-error "not a template function" } bad specialization
+
+struct baz {};
+template <> void baz (); // { dg-error "not a template function" } bad specialization