OSDN Git Service

PR c++/12762
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 14 Nov 2003 18:37:39 +0000 (18:37 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 14 Nov 2003 18:37:39 +0000 (18:37 +0000)
* parser.c (cp_parser_enclosed_template_argument_list): New
function.
(cp_parser_template_id): Use it.
(cp_parser_simple_type_specifier): Recognize invalid template
syntax.

PR c++/12762
* g++.dg/template/error3.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@73610 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 7e036b3..6540d4d 100644 (file)
@@ -1,3 +1,12 @@
+2003-11-14  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/12762
+       * parser.c (cp_parser_enclosed_template_argument_list): New
+       function.
+       (cp_parser_template_id): Use it.
+       (cp_parser_simple_type_specifier): Recognize invalid template
+       syntax.
+
 2003-11-14  Giovanni Bajo  <giovannibajo@libero.it>
 
         PR c++/2094
index 5e24fd5..dafb7d4 100644 (file)
@@ -1631,6 +1631,8 @@ static tree cp_parser_single_declaration
   (cp_parser *, bool, bool *);
 static tree cp_parser_functional_cast
   (cp_parser *, tree);
+static tree cp_parser_enclosed_template_argument_list
+  (cp_parser *);
 static void cp_parser_save_default_args
   (cp_parser *, tree);
 static void cp_parser_late_parsing_for_member
@@ -7509,11 +7511,7 @@ cp_parser_template_id (cp_parser *parser,
 {
   tree template;
   tree arguments;
-  tree saved_scope;
-  tree saved_qualifying_scope;
-  tree saved_object_scope;
   tree template_id;
-  bool saved_greater_than_is_operator_p;
   ptrdiff_t start_of_id;
   tree access_check = NULL_TREE;
   cp_token *next_token;
@@ -7576,33 +7574,8 @@ cp_parser_template_id (cp_parser *parser,
       return error_mark_node;
     }
 
-  /* [temp.names]
-
-     When parsing a template-id, the first non-nested `>' is taken as
-     the end of the template-argument-list rather than a greater-than
-     operator.  */
-  saved_greater_than_is_operator_p 
-    = parser->greater_than_is_operator_p;
-  parser->greater_than_is_operator_p = false;
-  /* Parsing the argument list may modify SCOPE, so we save it
-     here.  */
-  saved_scope = parser->scope;
-  saved_qualifying_scope = parser->qualifying_scope;
-  saved_object_scope = parser->object_scope;
-  /* Parse the template-argument-list itself.  */
-  if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
-    arguments = NULL_TREE;
-  else
-    arguments = cp_parser_template_argument_list (parser);
-  /* Look for the `>' that ends the template-argument-list.  */
-  cp_parser_require (parser, CPP_GREATER, "`>'");
-  /* The `>' token might be a greater-than operator again now.  */
-  parser->greater_than_is_operator_p 
-    = saved_greater_than_is_operator_p;
-  /* Restore the SAVED_SCOPE.  */
-  parser->scope = saved_scope;
-  parser->qualifying_scope = saved_qualifying_scope;
-  parser->object_scope = saved_object_scope;
+  /* Parse the arguments.  */
+  arguments = cp_parser_enclosed_template_argument_list (parser);
 
   /* Build a representation of the specialization.  */
   if (TREE_CODE (template) == IDENTIFIER_NODE)
@@ -8430,6 +8403,21 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags,
       return error_mark_node;
     }
 
+  /* There is no valid C++ program where a non-template type can never
+     be followed by a "<".  That usually indicates that the user
+     thought that the type was a template.  */
+  if (type && cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+    {
+      error ("`%T' is not a template", TREE_TYPE (type));
+      /* Consume the "<".  */
+      cp_lexer_consume_token (parser->lexer);
+      /* Parse the template arguments.  */
+      cp_parser_enclosed_template_argument_list (parser);
+      /* Attempt to recover by using the basic type, ignoring the
+        template arguments.  */
+      return type;
+    }
+
   return type;
 }
 
@@ -13857,6 +13845,51 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
   return build_functional_cast (type, expression_list);
 }
 
+/* Parse a template-argument-list, as well as the trailing ">" (but
+   not the opening ">").  See cp_parser_template_argument_list for the
+   return value.  */
+
+static tree
+cp_parser_enclosed_template_argument_list (cp_parser* parser)
+{
+  tree arguments;
+  tree saved_scope;
+  tree saved_qualifying_scope;
+  tree saved_object_scope;
+  bool saved_greater_than_is_operator_p;
+
+  /* [temp.names]
+
+     When parsing a template-id, the first non-nested `>' is taken as
+     the end of the template-argument-list rather than a greater-than
+     operator.  */
+  saved_greater_than_is_operator_p 
+    = parser->greater_than_is_operator_p;
+  parser->greater_than_is_operator_p = false;
+  /* Parsing the argument list may modify SCOPE, so we save it
+     here.  */
+  saved_scope = parser->scope;
+  saved_qualifying_scope = parser->qualifying_scope;
+  saved_object_scope = parser->object_scope;
+  /* Parse the template-argument-list itself.  */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
+    arguments = NULL_TREE;
+  else
+    arguments = cp_parser_template_argument_list (parser);
+  /* Look for the `>' that ends the template-argument-list.  */
+  cp_parser_require (parser, CPP_GREATER, "`>'");
+  /* The `>' token might be a greater-than operator again now.  */
+  parser->greater_than_is_operator_p 
+    = saved_greater_than_is_operator_p;
+  /* Restore the SAVED_SCOPE.  */
+  parser->scope = saved_scope;
+  parser->qualifying_scope = saved_qualifying_scope;
+  parser->object_scope = saved_object_scope;
+
+  return arguments;
+}
+
+
 /* MEMBER_FUNCTION is a member function, or a friend.  If default
    arguments, or the body of the function have not yet been parsed,
    parse them now.  */
index f5d577a..3e9f9fa 100644 (file)
@@ -1,3 +1,8 @@
+2003-11-14  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/12762
+       * g++.dg/template/error3.C: New test.
+
 2003-11-14  Arnaud Charlet  <charlet@act-europe.fr>
 
        PR ada/13035
diff --git a/gcc/testsuite/g++.dg/template/error3.C b/gcc/testsuite/g++.dg/template/error3.C
new file mode 100644 (file)
index 0000000..d3ee599
--- /dev/null
@@ -0,0 +1,5 @@
+// PR 12762
+
+template <typename> struct A { A() {}};
+typedef A<int> Ac;
+Ac<double> a; // { dg-error "template" }