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] Fix postfix-expression parsing (PR c++/78089, take 2)


Hi!

On Mon, Oct 24, 2016 at 04:20:25PM +0200, Jakub Jelinek wrote:
> While writing a testcase for __builtin_launder, I've noticed we don't parse
> __builtin_shuffle or __builtin_addressof properly (as well as do error
> recovery e.g. for typeid in constant expression etc.).
> 
> The problem is that several spots would return something; from the first
> switch in cp_parser_postfix_expression, but that is not something we really
> want, that primary expression part can be followed by [, ., -> etc. to form
> postfix-expression, but this is done in the same function.  So instead of
> returning, we need to set postfix_expression to whatever we were returning
> and just get out of the first switch, then continue parsing in the loop
> after that.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> For release branches, __builtin_addressof doesn't apply and the
> __builtin_shuffle code is differently formatted, but the bug is there
> for __builtin_shuffle, ok to backport to the release branches too?

The patch doesn't apply any longer, as the __builtin_launder patch has been
committed earlier.
So here is the same patch updated for current trunk, bootstrapped/regtested
on x86_64-linux and i686-linux again, ok for trunk?

2016-10-31  Jakub Jelinek  <jakub@redhat.com>

	PR c++/78089
	* parser.c (cp_parser_postfix_expression): Replace return statement in
	the first switch with setting postfix_expression to the return
	expression and break;.

	* c-c++-common/builtin-shuffle-1.c: New test.
	* g++.dg/cpp0x/addressof3.C: New test.

--- gcc/cp/parser.c.jj	2016-10-22 20:58:11.000000000 +0200
+++ gcc/cp/parser.c	2016-10-31 13:03:57.504037757 +0200
@@ -6441,7 +6441,10 @@ cp_parser_postfix_expression (cp_parser
 	   can be used in constant-expressions.  */
 	if (!cast_valid_in_integral_constant_expression_p (type)
 	    && cp_parser_non_integral_constant_expression (parser, NIC_CAST))
-	  return error_mark_node;
+	  {
+	    postfix_expression = error_mark_node;
+	    break;
+	  }
 
 	switch (keyword)
 	  {
@@ -6521,7 +6524,7 @@ cp_parser_postfix_expression (cp_parser
 	parser->type_definition_forbidden_message = saved_message;
 	/* `typeid' may not appear in an integral constant expression.  */
 	if (cp_parser_non_integral_constant_expression (parser, NIC_TYPEID))
-	  return error_mark_node;
+	  postfix_expression = error_mark_node;
       }
       break;
 
@@ -6615,7 +6618,10 @@ cp_parser_postfix_expression (cp_parser
 		    /*cast_p=*/false, /*allow_expansion_p=*/true,
 		    /*non_constant_p=*/NULL);
 	if (vec == NULL)
-	  return error_mark_node;
+	  {
+	    postfix_expression = error_mark_node;
+	    break;
+	  }
 
 	FOR_EACH_VEC_ELT (*vec, i, p)
 	  mark_exp_read (p);
@@ -6624,10 +6630,15 @@ cp_parser_postfix_expression (cp_parser
 	  {
 	  case RID_ADDRESSOF:
 	    if (vec->length () == 1)
-	      return cp_build_addressof (loc, (*vec)[0], tf_warning_or_error);
-	    error_at (loc, "wrong number of arguments to "
-			   "%<__builtin_addressof%>");
-	    return error_mark_node;
+	      postfix_expression
+		= cp_build_addressof (loc, (*vec)[0], tf_warning_or_error);
+	    else
+	      {
+		error_at (loc, "wrong number of arguments to "
+			       "%<__builtin_addressof%>");
+		postfix_expression = error_mark_node;
+	      }
+	    break;
 
 	  case RID_BUILTIN_LAUNDER:
 	    if (vec->length () == 1)
@@ -6643,14 +6654,20 @@ cp_parser_postfix_expression (cp_parser
 
 	  case RID_BUILTIN_SHUFFLE:
 	    if (vec->length () == 2)
-	      return build_x_vec_perm_expr (loc, (*vec)[0], NULL_TREE,
-					    (*vec)[1], tf_warning_or_error);
+	      postfix_expression
+		= build_x_vec_perm_expr (loc, (*vec)[0], NULL_TREE,
+					 (*vec)[1], tf_warning_or_error);
 	    else if (vec->length () == 3)
-	      return build_x_vec_perm_expr (loc, (*vec)[0], (*vec)[1],
-					    (*vec)[2], tf_warning_or_error);
-	    error_at (loc, "wrong number of arguments to "
-			   "%<__builtin_shuffle%>");
-	    return error_mark_node;
+	      postfix_expression
+		= build_x_vec_perm_expr (loc, (*vec)[0], (*vec)[1],
+					 (*vec)[2], tf_warning_or_error);
+	    else
+	      {
+		error_at (loc, "wrong number of arguments to "
+			       "%<__builtin_shuffle%>");
+		postfix_expression = error_mark_node;
+	      }
+	    break;
 
 	  default:
 	    gcc_unreachable ();
--- gcc/testsuite/c-c++-common/builtin-shuffle-1.c.jj	2016-10-24 09:37:45.161340576 +0200
+++ gcc/testsuite/c-c++-common/builtin-shuffle-1.c	2016-10-24 09:44:35.804156775 +0200
@@ -0,0 +1,22 @@
+/* PR c++/78089 */
+/* { dg-do run } */
+
+typedef int V __attribute__((vector_size (16)));
+V a, b, c;
+
+int
+foo ()
+{
+  return __builtin_shuffle (a, b, c)[3];
+}
+
+int
+main ()
+{
+  a = (V) { 1, 2, 3, 4 };
+  b = (V) { 5, 6, 7, 8 };
+  c = (V) { 7, 2, 5, 6 };
+  if (foo () != 7)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/g++.dg/cpp0x/addressof3.C.jj	2016-10-24 09:47:24.175031324 +0200
+++ gcc/testsuite/g++.dg/cpp0x/addressof3.C	2016-10-24 09:50:36.000000000 +0200
@@ -0,0 +1,9 @@
+// { dg-do compile }
+
+struct S { int foo (); int s; };
+int a[10];
+int b;
+S c;
+int d = __builtin_addressof (a)[0][0];
+int e = __builtin_addressof (b)[0];
+int f = __builtin_addressof (c)->foo ();


	Jakub


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