public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ Patch] PR 61857
@ 2014-09-23 12:46 Paolo Carlini
  2014-09-23 15:05 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Paolo Carlini @ 2014-09-23 12:46 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

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

Hi,

in this C++14 rejects valid issue, we reject the testcase with "‘x’ was 
not declared in this scope", because in cp_parser_initializer_list we 
tentatively try to parse what follows the '[' as a 
cp_parser_constant_expression. As far as I can see, we can easily solve 
the issue with the approach already used in many other places, thus 
don't even try a constant if the ']' isn't followed by '='. Tested 
x86_64-linux.

Thanks!
Paolo.

PS: I tried to once reuse as is the new 
cp_parser_skip_to_closing_square_bracket in cp_parser_lambda_introducer 
but we get more redundant diagnostic eg, at the end of 
g++.old-deja/g++.other/crash28.C. In fact, the context is slightly 
different, because in cp_parser_skip_to_closing_square_bracket we are in 
error recovery. I suppose we can further investigate this later...

[-- Attachment #2: CL_61857 --]
[-- Type: text/plain, Size: 331 bytes --]

/cp
2014-09-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/61857
	* parser.c (cp_parser_skip_to_closing_square_bracket,
	cp_parser_array_designator_p): New.
	(cp_parser_initializer_list): Use the latter.

/testsuite
2014-09-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/61857
	* g++.dg/cpp1y/lambda-init10.C: New.

[-- Attachment #3: patch_61857 --]
[-- Type: text/plain, Size: 3488 bytes --]

Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 215496)
+++ cp/parser.c	(working copy)
@@ -2487,6 +2487,10 @@ static cp_declarator * cp_parser_make_indirect_dec
   (enum tree_code, tree, cp_cv_quals, cp_declarator *, tree);
 static bool cp_parser_compound_literal_p
   (cp_parser *);
+static bool cp_parser_array_designator_p
+  (cp_parser *);
+static bool cp_parser_skip_to_closing_square_bracket
+  (cp_parser *);
 
 /* Returns nonzero if we are parsing tentatively.  */
 
@@ -19157,6 +19161,69 @@ cp_parser_braced_list (cp_parser* parser, bool* no
   return initializer;
 }
 
+/* Consume tokens up to, and including, the next non-nested closing `]'.
+   Returns true iff we found a closing `]'.  */
+
+static bool
+cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
+{
+  unsigned square_depth = 0;
+
+  while (true)
+    {
+      cp_token * token = cp_lexer_peek_token (parser->lexer);
+
+      switch (token->type)
+	{
+	case CPP_EOF:
+	case CPP_PRAGMA_EOL:
+	  /* If we've run out of tokens, then there is no closing `]'.  */
+	  return false;
+
+        case CPP_OPEN_SQUARE:
+          ++square_depth;
+          break;
+
+        case CPP_CLOSE_SQUARE:
+	  if (!square_depth--)
+	    {
+	      cp_lexer_consume_token (parser->lexer);
+	      return true;
+	    }
+	  break;
+
+	default:
+	  break;
+	}
+
+      /* Consume the token.  */
+      cp_lexer_consume_token (parser->lexer);
+    }
+}
+
+/* Return true if we are looking at an array-designator, false otherwise.  */
+
+static bool
+cp_parser_array_designator_p (cp_parser *parser)
+{
+  /* Consume the `['.  */
+  cp_lexer_consume_token (parser->lexer);
+
+  cp_lexer_save_tokens (parser->lexer);
+
+  /* Skip tokens until the next token is a closing square bracket.
+     If we find the closing `]', and the next token is a `=', then
+     we are looking at an array designator.  */
+  bool array_designator_p
+    = (cp_parser_skip_to_closing_square_bracket (parser)
+       && cp_lexer_next_token_is (parser->lexer, CPP_EQ));
+  
+  /* Roll back the tokens we skipped.  */
+  cp_lexer_rollback_tokens (parser->lexer);
+
+  return array_designator_p;
+}
+
 /* Parse an initializer-list.
 
    initializer-list:
@@ -19235,10 +19302,20 @@ cp_parser_initializer_list (cp_parser* parser, boo
 	  bool non_const = false;
 
 	  cp_parser_parse_tentatively (parser);
-	  cp_lexer_consume_token (parser->lexer);
-	  designator = cp_parser_constant_expression (parser, true, &non_const);
-	  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
-	  cp_parser_require (parser, CPP_EQ, RT_EQ);
+
+	  if (!cp_parser_array_designator_p (parser))
+	    {
+	      cp_parser_simulate_error (parser);
+	      designator = NULL_TREE;
+	    }
+	  else
+	    {
+	      designator = cp_parser_constant_expression (parser, true,
+							  &non_const);
+	      cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+	      cp_parser_require (parser, CPP_EQ, RT_EQ);
+	    }
+
 	  if (!cp_parser_parse_definitely (parser))
 	    designator = NULL_TREE;
 	  else if (non_const)
Index: testsuite/g++.dg/cpp1y/lambda-init10.C
===================================================================
--- testsuite/g++.dg/cpp1y/lambda-init10.C	(revision 0)
+++ testsuite/g++.dg/cpp1y/lambda-init10.C	(working copy)
@@ -0,0 +1,8 @@
+// PR c++/61857
+// { dg-do compile { target c++14 } }
+
+struct A { 
+  A(int val) {}
+};
+
+A a{ [x=123]{ return x; }() }; 

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

* Re: [C++ Patch] PR 61857
  2014-09-23 12:46 [C++ Patch] PR 61857 Paolo Carlini
@ 2014-09-23 15:05 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2014-09-23 15:05 UTC (permalink / raw)
  To: Paolo Carlini, gcc-patches

OK.

Jason

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

end of thread, other threads:[~2014-09-23 15:05 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-23 12:46 [C++ Patch] PR 61857 Paolo Carlini
2014-09-23 15:05 ` 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).