This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 19253


This PR is about an ice-on-invalid; we crashed on "typename N::X x" as
a template argument, where "N" is a namespace.  We were parsing this
as a possible functional cast, (e.g. "typename N::X(3)").  It turns
out that we had a lot of logic duplicated between this case and the
elaborated-type-specifier case; I just arranged for the parser to use
the elaborated-type-specifier code to handle the functional cast as
well.  This also fixed an accepts-valid bug concerning a use of the
typename keyword outside of a template.  (I know the committee may
relax that requirement, but we should be consistent within G++, one
way or the other.)

Tested on x86_64-unknown-linux-gnu, applied on the mainline and on the
4.0 branch.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2005-11-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/19253
	* parser.c (cp_parser_postfix_expression): Use
	cp_parser_elaborated_type_specifier to handle typename-types in
	functional casts.
	(cp_parser_enclosed_argument_list): Skip ahead to the end of the
	template argument list if the closing ">" is not found.

2005-11-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/19253
	* g++.dg/parse/typename8.C: Compile with -w -fpermissive.
	* g++.dg/parse/typename9.C: New test.
	* g++/dg/parse/typename10.C: Likewise.

Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 106390)
+++ gcc/cp/parser.c	(working copy)
@@ -3961,55 +3961,12 @@ cp_parser_postfix_expression (cp_parser 
 
     case RID_TYPENAME:
       {
-	bool template_p = false;
-	tree id;
 	tree type;
-	tree scope;
-
-	/* Consume the `typename' token.  */
-	cp_lexer_consume_token (parser->lexer);
-
-	/* Look for the optional `::' operator.  */
-	cp_parser_global_scope_opt (parser,
-				    /*current_scope_valid_p=*/false);
-	/* Look for the nested-name-specifier.  In case of error here,
-	   consume the trailing id to avoid subsequent error messages
-	   for usual cases.  */
-	scope = cp_parser_nested_name_specifier (parser,
-						 /*typename_keyword_p=*/true,
-						 /*check_dependency_p=*/true,
-						 /*type_p=*/true,
-						 /*is_declaration=*/true);
-
-	/* Look for the optional `template' keyword.  */
-	template_p = cp_parser_optional_template_keyword (parser);
-	/* We don't know whether we're looking at a template-id or an
-	   identifier.  */
-	cp_parser_parse_tentatively (parser);
-	/* Try a template-id.  */
-	id = cp_parser_template_id (parser, template_p,
-				    /*check_dependency_p=*/true,
-				    /*is_declaration=*/true);
-	/* If that didn't work, try an identifier.  */
-	if (!cp_parser_parse_definitely (parser))
-	  id = cp_parser_identifier (parser);
-
-	/* Don't process id if nested name specifier is invalid.  */
-	if (!scope || scope == error_mark_node)
-	  return error_mark_node;
-	/* If we look up a template-id in a non-dependent qualifying
-	   scope, there's no need to create a dependent type.  */
-	if (TREE_CODE (id) == TYPE_DECL
-	    && (!TYPE_P (scope)
-	        || !dependent_type_p (parser->scope)))
-	  type = TREE_TYPE (id);
-	/* Create a TYPENAME_TYPE to represent the type to which the
-	   functional cast is being performed.  */
-	else
-	  type = make_typename_type (parser->scope, id,
-				     typename_type,
-				     /*complain=*/1);
-
+	/* The syntax permitted here is the same permitted for an
+	   elaborated-type-specifier.  */
+	type = cp_parser_elaborated_type_specifier (parser,
+						    /*is_friend=*/false,
+						    /*is_declaration=*/false);
 	postfix_expression = cp_parser_functional_cast (parser, type);
       }
       break;
@@ -15498,11 +15455,8 @@ cp_parser_enclosed_template_argument_lis
 		 "a template argument list");
 	}
     }
-  else if (!cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
-    error ("missing %<>%> to terminate the template argument list");
   else
-    /* It's what we want, a '>'; consume it.  */
-    cp_lexer_consume_token (parser->lexer);
+    cp_parser_skip_until_found (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;
Index: gcc/testsuite/g++.dg/parse/typename8.C
===================================================================
--- gcc/testsuite/g++.dg/parse/typename8.C	(revision 106390)
+++ gcc/testsuite/g++.dg/parse/typename8.C	(working copy)
@@ -4,6 +4,8 @@
 // PR 23797:ICE
 // Origin:  Volker Reichelt <reichelt@gcc.gnu.org>
 
+// { dg-options "-fpermissive -w" }
+
 struct A { typedef int X; };
 
 int i = typename A::X();
Index: gcc/testsuite/g++.dg/parse/typename9.C
===================================================================
--- gcc/testsuite/g++.dg/parse/typename9.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/typename9.C	(revision 0)
@@ -0,0 +1,3 @@
+struct A { typedef int X; };
+
+int i = typename A::X(); // { dg-error "typename" }
Index: gcc/testsuite/g++.dg/parse/typename10.C
===================================================================
--- gcc/testsuite/g++.dg/parse/typename10.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/typename10.C	(revision 0)
@@ -0,0 +1,8 @@
+// PR c++/19253
+
+namespace N { struct X; }
+
+template<typename> struct A
+{
+  A<typename N::X x> a; // { dg-error "invalid" }
+};


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]