Just a loop was missing.

Tested on x86_64-unknown-linux-gnu.

Richard.

2016-10-27  Richard Biener  <rguent...@suse.de>

        c/
        * gimple-parser.c (c_parser_gimple_postfix_expression_after_primary):
        Add missing outer loop.

        * gcc.dg/gimplefe-15.c: Adjust.

diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 3924e6f..bcfb677 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -799,147 +799,147 @@ c_parser_gimple_postfix_expression_after_primary 
(c_parser *parser,
   vec<location_t> arg_loc = vNULL;
   location_t start;
   location_t finish;
+  tree ident;
+  location_t comp_loc;
 
-  location_t op_loc = c_parser_peek_token (parser)->location;
-
-  switch (c_parser_peek_token (parser)->type)
+  while (true)
     {
-    case CPP_OPEN_SQUARE:
-      {
-       c_parser_consume_token (parser);
-       tree idx = c_parser_gimple_unary_expression (parser).value;
+      location_t op_loc = c_parser_peek_token (parser)->location;
+      switch (c_parser_peek_token (parser)->type)
+       {
+       case CPP_OPEN_SQUARE:
+         {
+           c_parser_consume_token (parser);
+           tree idx = c_parser_gimple_unary_expression (parser).value;
 
-       if (! c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"))
-         break;
+           if (! c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"))
+             break;
 
-       start = expr.get_start ();
-       finish = c_parser_tokens_buf (parser, 0)->location;
-       expr.value = build_array_ref (op_loc, expr.value, idx);
-       set_c_expr_source_range (&expr, start, finish);
+           start = expr.get_start ();
+           finish = c_parser_tokens_buf (parser, 0)->location;
+           expr.value = build_array_ref (op_loc, expr.value, idx);
+           set_c_expr_source_range (&expr, start, finish);
 
-       expr.original_code = ERROR_MARK;
-       expr.original_type = NULL;
-       break;
-      }
-    case CPP_OPEN_PAREN:
-      {
-       /* Function call.  */
-       c_parser_consume_token (parser);
-       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
-         exprlist = NULL;
-       else
-         exprlist = c_parser_gimple_expr_list (parser, &origtypes,
-                                               &arg_loc);
-       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
-                                  "expected %<)%>");
-       orig_expr = expr;
-       start = expr.get_start ();
-       finish = c_parser_tokens_buf (parser, 0)->get_finish ();
-       expr.value = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
-                                               exprlist, origtypes);
-       set_c_expr_source_range (&expr, start, finish);
-
-       expr.original_code = ERROR_MARK;
-       if (TREE_CODE (expr.value) == INTEGER_CST
-           && TREE_CODE (orig_expr.value) == FUNCTION_DECL
-           && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
-           && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
-         expr.original_code = C_MAYBE_CONST_EXPR;
-       expr.original_type = NULL;
-       if (exprlist)
-         {
-           release_tree_vector (exprlist);
-           release_tree_vector (origtypes);
-         }
-       arg_loc.release ();
-       break;
-      }
-    case CPP_DOT:
-      {
-       /* Structure element reference.  */
-       tree ident;
-       location_t comp_loc;
-       c_parser_consume_token (parser);
-       if (c_parser_next_token_is (parser, CPP_NAME))
-         {
-           c_token *comp_tok = c_parser_peek_token (parser);
-           ident = comp_tok->value;
-           comp_loc = comp_tok->location;
+           expr.original_code = ERROR_MARK;
+           expr.original_type = NULL;
+           break;
          }
-       else
+       case CPP_OPEN_PAREN:
          {
-           c_parser_error (parser, "expected identifier");
-           expr.set_error ();
+           /* Function call.  */
+           c_parser_consume_token (parser);
+           if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+             exprlist = NULL;
+           else
+             exprlist = c_parser_gimple_expr_list (parser, &origtypes,
+                                                   &arg_loc);
+           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+                                      "expected %<)%>");
+           orig_expr = expr;
+           start = expr.get_start ();
+           finish = c_parser_tokens_buf (parser, 0)->get_finish ();
+           expr.value = c_build_function_call_vec (expr_loc, arg_loc,
+                                                   expr.value,
+                                                   exprlist, origtypes);
+           set_c_expr_source_range (&expr, start, finish);
+
            expr.original_code = ERROR_MARK;
+           if (TREE_CODE (expr.value) == INTEGER_CST
+               && TREE_CODE (orig_expr.value) == FUNCTION_DECL
+               && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
+               && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
+             expr.original_code = C_MAYBE_CONST_EXPR;
            expr.original_type = NULL;
-           return expr;
+           if (exprlist)
+             {
+               release_tree_vector (exprlist);
+               release_tree_vector (origtypes);
+             }
+           arg_loc.release ();
+           break;
          }
-       start = expr.get_start ();
-       finish = c_parser_peek_token (parser)->get_finish ();
-       c_parser_consume_token (parser);
-       expr.value = build_component_ref (op_loc, expr.value, ident,
-                                         comp_loc);
-       set_c_expr_source_range (&expr, start, finish);
-       expr.original_code = ERROR_MARK;
-       if (TREE_CODE (expr.value) != COMPONENT_REF)
-         expr.original_type = NULL;
-       else
+       case CPP_DOT:
          {
-           /* Remember the original type of a bitfield.  */
-           tree field = TREE_OPERAND (expr.value, 1);
-           if (TREE_CODE (field) != FIELD_DECL)
+           /* Structure element reference.  */
+           c_parser_consume_token (parser);
+           if (c_parser_next_token_is (parser, CPP_NAME))
+             {
+               c_token *comp_tok = c_parser_peek_token (parser);
+               ident = comp_tok->value;
+               comp_loc = comp_tok->location;
+             }
+           else
+             {
+               c_parser_error (parser, "expected identifier");
+               expr.set_error ();
+               expr.original_code = ERROR_MARK;
+               expr.original_type = NULL;
+               return expr;
+             }
+           start = expr.get_start ();
+           finish = c_parser_peek_token (parser)->get_finish ();
+           c_parser_consume_token (parser);
+           expr.value = build_component_ref (op_loc, expr.value, ident,
+                                             comp_loc);
+           set_c_expr_source_range (&expr, start, finish);
+           expr.original_code = ERROR_MARK;
+           if (TREE_CODE (expr.value) != COMPONENT_REF)
              expr.original_type = NULL;
            else
-             expr.original_type = DECL_BIT_FIELD_TYPE (field);
-         }
-       break;
-      }
-    case CPP_DEREF:
-      {
-       /* Structure element reference.  */
-       tree ident;
-       location_t comp_loc;
-       c_parser_consume_token (parser);
-       if (c_parser_next_token_is (parser, CPP_NAME))
-         {
-           c_token *comp_tok = c_parser_peek_token (parser);
-           ident = comp_tok->value;
-           comp_loc = comp_tok->location;
+             {
+               /* Remember the original type of a bitfield.  */
+               tree field = TREE_OPERAND (expr.value, 1);
+               if (TREE_CODE (field) != FIELD_DECL)
+                 expr.original_type = NULL;
+               else
+                 expr.original_type = DECL_BIT_FIELD_TYPE (field);
+             }
+           break;
          }
-       else
+       case CPP_DEREF:
          {
-           c_parser_error (parser, "expected identifier");
-           expr.set_error ();
+           /* Structure element reference.  */
+           c_parser_consume_token (parser);
+           if (c_parser_next_token_is (parser, CPP_NAME))
+             {
+               c_token *comp_tok = c_parser_peek_token (parser);
+               ident = comp_tok->value;
+               comp_loc = comp_tok->location;
+             }
+           else
+             {
+               c_parser_error (parser, "expected identifier");
+               expr.set_error ();
+               expr.original_code = ERROR_MARK;
+               expr.original_type = NULL;
+               return expr;
+             }
+           start = expr.get_start ();
+           finish = c_parser_peek_token (parser)->get_finish ();
+           c_parser_consume_token (parser);
+           expr.value = build_component_ref (op_loc,
+                                             build_simple_mem_ref_loc
+                                               (op_loc, expr.value),
+                                             ident, comp_loc);
+           set_c_expr_source_range (&expr, start, finish);
            expr.original_code = ERROR_MARK;
-           expr.original_type = NULL;
-           return expr;
-         }
-       start = expr.get_start ();
-       finish = c_parser_peek_token (parser)->get_finish ();
-       c_parser_consume_token (parser);
-       expr.value = build_component_ref (op_loc,
-                                         build_simple_mem_ref_loc (op_loc,
-                                                                   expr.value),
-                                         ident, comp_loc);
-       set_c_expr_source_range (&expr, start, finish);
-       expr.original_code = ERROR_MARK;
-       if (TREE_CODE (expr.value) != COMPONENT_REF)
-         expr.original_type = NULL;
-       else
-         {
-           /* Remember the original type of a bitfield.  */
-           tree field = TREE_OPERAND (expr.value, 1);
-           if (TREE_CODE (field) != FIELD_DECL)
+           if (TREE_CODE (expr.value) != COMPONENT_REF)
              expr.original_type = NULL;
            else
-             expr.original_type = DECL_BIT_FIELD_TYPE (field);
+             {
+               /* Remember the original type of a bitfield.  */
+               tree field = TREE_OPERAND (expr.value, 1);
+               if (TREE_CODE (field) != FIELD_DECL)
+                 expr.original_type = NULL;
+               else
+                 expr.original_type = DECL_BIT_FIELD_TYPE (field);
+             }
+           break;
          }
-       break;
-      }
-    default:
-      return expr;
+       default:
+         return expr;
+       }
     }
-  return expr;
 }
 
 /* Parse expression list.
diff --git a/gcc/testsuite/gcc.dg/gimplefe-15.c 
b/gcc/testsuite/gcc.dg/gimplefe-15.c
index 0c4b4d2..ca99031 100644
--- a/gcc/testsuite/gcc.dg/gimplefe-15.c
+++ b/gcc/testsuite/gcc.dg/gimplefe-15.c
@@ -1,7 +1,8 @@
 /* { dg-do compile } */
 /* { dg-options "-O -fgimple" } */
 
-struct X { int a; };
+struct Y { int b[2]; };
+struct X { int a; struct Y y; };
 struct X x;
 
 int __GIMPLE ()
@@ -10,8 +11,8 @@ foo (struct X *p, _Complex int q)
   int b;
   b = __real q;
   p->a = b;
-  x.a = b;
-  b = p->a;
+  x.y.b[b] = b;
+  b = p->y.b[1];
   b = x.a;
   return b;
 }

Reply via email to