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; }