public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for c++/38798 (auto f() -> struct A {})
@ 2009-10-17  6:51 Jason Merrill
  2009-10-21 16:36 ` H.J. Lu
  0 siblings, 1 reply; 3+ messages in thread
From: Jason Merrill @ 2009-10-17  6:51 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 243 bytes --]

DR 770 clarified that we shouldn't try to parse a class or 
enum-specifier in the context of a trailing return type.  I've 
implemented that with a flag passed down into cp_parser_type_specifier.

Tested x86_64-pc-linux-gnu, applied to trunk.

[-- Attachment #2: 38798.patch --]
[-- Type: text/x-patch, Size: 7979 bytes --]

commit 638569c50c4b6f6f3025ff5e00265eeabd495417
Author: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Sat Oct 17 06:11:08 2009 +0000

    	PR c++/38798
    	* parser.c (CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS): New.
    	(cp_parser_type_specifier): Don't try to parse a class-specifier
    	or enum-specifier in that case.
    	(cp_parser_trailing_type_id): New.
    	(cp_parser_late_return_type_opt): Call it.
    	(cp_parser_type_id_1): Add is_trailing_return parm.
    	(cp_parser_type_specifier_seq): Likewise.
    
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 5e37343..b9b53e5 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1194,8 +1194,12 @@ enum
   /* The construct is optional.  If it is not present, then no error
      should be issued.  */
   CP_PARSER_FLAGS_OPTIONAL = 0x1,
-  /* When parsing a type-specifier, do not allow user-defined types.  */
-  CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2
+  /* When parsing a type-specifier, treat user-defined type-names
+     as non-type identifiers.  */
+  CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2,
+  /* When parsing a type-specifier, do not try to parse a class-specifier
+     or enum-specifier.  */
+  CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS = 0x4
 };
 
 /* This type is used for parameters and variables which hold
@@ -1741,10 +1745,11 @@ static tree cp_parser_type_id
   (cp_parser *);
 static tree cp_parser_template_type_arg
   (cp_parser *);
+static tree cp_parser_trailing_type_id (cp_parser *);
 static tree cp_parser_type_id_1
-  (cp_parser *, bool);
+  (cp_parser *, bool, bool);
 static void cp_parser_type_specifier_seq
-  (cp_parser *, bool, cp_decl_specifier_seq *);
+  (cp_parser *, bool, bool, cp_decl_specifier_seq *);
 static tree cp_parser_parameter_declaration_clause
   (cp_parser *);
 static tree cp_parser_parameter_declaration_list
@@ -5795,6 +5800,7 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts)
     = "types may not be defined in a new-type-id";
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+				/*is_trailing_return=*/false,
 				&type_specifier_seq);
   /* Restore the old message.  */
   parser->type_definition_forbidden_message = saved_message;
@@ -8028,6 +8034,7 @@ cp_parser_condition (cp_parser* parser)
     = "types may not be defined in conditions";
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_condition==*/true,
+				/*is_trailing_return=*/false,
 				&type_specifiers);
   /* Restore the saved message.  */
   parser->type_definition_forbidden_message = saved_message;
@@ -9669,6 +9676,7 @@ cp_parser_conversion_type_id (cp_parser* parser)
   attributes = cp_parser_attributes_opt (parser);
   /* Parse the type-specifiers.  */
   cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+				/*is_trailing_return=*/false,
 				&type_specifiers);
   /* If that didn't work, stop.  */
   if (type_specifiers.type == error_mark_node)
@@ -11644,6 +11652,9 @@ cp_parser_type_specifier (cp_parser* parser,
   switch (keyword)
     {
     case RID_ENUM:
+      if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
+	goto elaborated_type_specifier;
+
       /* Look for the enum-specifier.  */
       type_spec = cp_parser_enum_specifier (parser);
       /* If that worked, we're done.  */
@@ -11666,6 +11677,9 @@ cp_parser_type_specifier (cp_parser* parser,
     case RID_CLASS:
     case RID_STRUCT:
     case RID_UNION:
+      if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
+	goto elaborated_type_specifier;
+
       /* Parse tentatively so that we can back up if we don't find a
 	 class-specifier.  */
       cp_parser_parse_tentatively (parser);
@@ -12532,6 +12546,7 @@ cp_parser_enum_specifier (cp_parser* parser)
 
       /* Parse the type-specifier-seq.  */
       cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+				    /*is_trailing_return=*/false,
                                     &type_specifiers);
 
       /* At this point this is surely not elaborated type specifier.  */
@@ -14422,7 +14437,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
 /* Parse a late-specified return type, if any.  This is not a separate
    non-terminal, but part of a function declarator, which looks like
 
-   -> type-id
+   -> trailing-type-specifier-seq abstract-declarator(opt)
 
    Returns the type indicated by the type-id.  */
 
@@ -14440,7 +14455,7 @@ cp_parser_late_return_type_opt (cp_parser* parser)
   /* Consume the ->.  */
   cp_lexer_consume_token (parser->lexer);
 
-  return cp_parser_type_id (parser);
+  return cp_parser_trailing_type_id (parser);
 }
 
 /* Parse a declarator-id.
@@ -14493,13 +14508,15 @@ cp_parser_declarator_id (cp_parser* parser, bool optional_p)
    Returns the TYPE specified.  */
 
 static tree
-cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg)
+cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg,
+		     bool is_trailing_return)
 {
   cp_decl_specifier_seq type_specifier_seq;
   cp_declarator *abstract_declarator;
 
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+				is_trailing_return,
 				&type_specifier_seq);
   if (type_specifier_seq.type == error_mark_node)
     return error_mark_node;
@@ -14537,12 +14554,17 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg)
 
 static tree cp_parser_type_id (cp_parser *parser)
 {
-  return cp_parser_type_id_1 (parser, false);
+  return cp_parser_type_id_1 (parser, false, false);
 }
 
 static tree cp_parser_template_type_arg (cp_parser *parser)
 {
-  return cp_parser_type_id_1 (parser, true);
+  return cp_parser_type_id_1 (parser, true, false);
+}
+
+static tree cp_parser_trailing_type_id (cp_parser *parser)
+{
+  return cp_parser_type_id_1 (parser, false, true);
 }
 
 /* Parse a type-specifier-seq.
@@ -14558,11 +14580,15 @@ static tree cp_parser_template_type_arg (cp_parser *parser)
    If IS_CONDITION is true, we are at the start of a "condition",
    e.g., we've just seen "if (".
 
+   If IS_TRAILING_RETURN is true, we are in a trailing-return-type,
+   i.e. we've just seen "->".
+
    Sets *TYPE_SPECIFIER_SEQ to represent the sequence.  */
 
 static void
 cp_parser_type_specifier_seq (cp_parser* parser,
 			      bool is_condition,
+			      bool is_trailing_return,
 			      cp_decl_specifier_seq *type_specifier_seq)
 {
   bool seen_type_specifier = false;
@@ -14572,6 +14598,12 @@ cp_parser_type_specifier_seq (cp_parser* parser,
   /* Clear the TYPE_SPECIFIER_SEQ.  */
   clear_decl_specs (type_specifier_seq);
 
+  /* In the context of a trailing return type, enum E { } is an
+     elaborated-type-specifier followed by a function-body, not an
+     enum-specifier.  */
+  if (is_trailing_return)
+    flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;
+
   /* Parse the type-specifiers and attributes.  */
   while (true)
     {
@@ -17283,6 +17315,7 @@ cp_parser_exception_declaration (cp_parser* parser)
 
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+				/*is_trailing_return=*/false,
 				&type_specifiers);
   /* If it's a `)', then there is no declarator.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
@@ -22056,6 +22089,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
 
 	  cp_parser_parse_tentatively (parser);
 	  cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+					/*is_trailing_return=*/false,
 					&type_specifiers);
 	  if (cp_parser_parse_definitely (parser))
 	    {
diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing5.C b/gcc/testsuite/g++.dg/cpp0x/trailing5.C
new file mode 100644
index 0000000..b97d362
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/trailing5.C
@@ -0,0 +1,10 @@
+// PR c++/38798, DR 770
+// { dg-options -std=c++0x }
+
+struct A {};
+auto foo() -> struct A {}
+
+enum B {};
+auto bar() -> enum B {}
+
+auto baz() -> struct C {} {}	// { dg-error "" }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ PATCH for c++/38798 (auto f() -> struct A {})
  2009-10-17  6:51 C++ PATCH for c++/38798 (auto f() -> struct A {}) Jason Merrill
@ 2009-10-21 16:36 ` H.J. Lu
  2009-10-21 21:43   ` Jason Merrill
  0 siblings, 1 reply; 3+ messages in thread
From: H.J. Lu @ 2009-10-21 16:36 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

On Fri, Oct 16, 2009 at 11:20 PM, Jason Merrill <jason@redhat.com> wrote:
> DR 770 clarified that we shouldn't try to parse a class or enum-specifier in
> the context of a trailing return type.  I've implemented that with a flag
> passed down into cp_parser_type_specifier.
>
> Tested x86_64-pc-linux-gnu, applied to trunk.
>

Hi Jason,

You removed 4 testcases:

    trunk/gcc/testsuite/g++.dg/cpp0x/auto12.C
    trunk/gcc/testsuite/g++.dg/cpp0x/auto13.C
    trunk/gcc/testsuite/g++.dg/cpp0x/auto6.C
    trunk/gcc/testsuite/g++.dg/cpp0x/auto8.C

But there are no ChangeLog entries. Is that intentional?

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ PATCH for c++/38798 (auto f() -> struct A {})
  2009-10-21 16:36 ` H.J. Lu
@ 2009-10-21 21:43   ` Jason Merrill
  0 siblings, 0 replies; 3+ messages in thread
From: Jason Merrill @ 2009-10-21 21:43 UTC (permalink / raw)
  To: H.J. Lu; +Cc: gcc-patches List

On 10/21/2009 09:03 AM, H.J. Lu wrote:
> You removed 4 testcases:

I renamed them.

> But there are no ChangeLog entries. Is that intentional?

I'll add some.

Jason

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-10-21 21:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-17  6:51 C++ PATCH for c++/38798 (auto f() -> struct A {}) Jason Merrill
2009-10-21 16:36 ` H.J. Lu
2009-10-21 21:43   ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).