From patchwork Tue Oct 4 21:48:17 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Shinkarov X-Patchwork-Id: 117704 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 72E271007D1 for ; Wed, 5 Oct 2011 08:48:58 +1100 (EST) Received: (qmail 1617 invoked by alias); 4 Oct 2011 21:48:55 -0000 Received: (qmail 1604 invoked by uid 22791); 4 Oct 2011 21:48:53 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-vx0-f175.google.com (HELO mail-vx0-f175.google.com) (209.85.220.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 04 Oct 2011 21:48:38 +0000 Received: by vcbfl17 with SMTP id fl17so978823vcb.20 for ; Tue, 04 Oct 2011 14:48:37 -0700 (PDT) Received: by 10.52.110.35 with SMTP id hx3mr1788024vdb.165.1317764917170; Tue, 04 Oct 2011 14:48:37 -0700 (PDT) MIME-Version: 1.0 Received: by 10.220.150.13 with HTTP; Tue, 4 Oct 2011 14:48:17 -0700 (PDT) From: Artem Shinkarov Date: Tue, 4 Oct 2011 22:48:17 +0100 Message-ID: Subject: Fix pr50607 bconstp-3.c failure To: GCC Patches Cc: "Joseph S. Myers" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi Here is the patch tho fix bconstp-3.c failure in the bug 50607. The failure was cause because the new parser routine did not consider original_tree_code of the expression. The patch is bootstrapped on x86-unknown-linux-gnu and is being tested. Thanks, Artem. Index: c-parser.c =================================================================== --- c-parser.c (revision 179464) +++ c-parser.c (working copy) @@ -297,7 +297,7 @@ c_lex_one_token (c_parser *parser, c_tok /* Else they are not special keywords. */ } - else if (c_dialect_objc () + else if (c_dialect_objc () && (OBJC_IS_AT_KEYWORD (rid_code) || OBJC_IS_CXX_KEYWORD (rid_code))) { @@ -689,9 +689,9 @@ c_parser_next_token_starts_declspecs (c_ setter/getter on the class. c_token_starts_declspecs() can't differentiate between the two cases because it only checks the current token, so we have a special check here. */ - if (c_dialect_objc () + if (c_dialect_objc () && token->type == CPP_NAME - && token->id_kind == C_ID_CLASSNAME + && token->id_kind == C_ID_CLASSNAME && c_parser_peek_2nd_token (parser)->type == CPP_DOT) return false; @@ -706,9 +706,9 @@ c_parser_next_tokens_start_declaration ( c_token *token = c_parser_peek_token (parser); /* Same as above. */ - if (c_dialect_objc () + if (c_dialect_objc () && token->type == CPP_NAME - && token->id_kind == C_ID_CLASSNAME + && token->id_kind == C_ID_CLASSNAME && c_parser_peek_2nd_token (parser)->type == CPP_DOT) return false; @@ -1516,7 +1516,7 @@ c_parser_declaration_or_fndef (c_parser return; if (specs->attrs) { - warning_at (c_parser_peek_token (parser)->location, + warning_at (c_parser_peek_token (parser)->location, OPT_Wattributes, "prefix attributes are ignored for methods"); specs->attrs = NULL_TREE; @@ -1551,12 +1551,12 @@ c_parser_declaration_or_fndef (c_parser return; if (specs->attrs) { - warning_at (c_parser_peek_token (parser)->location, + warning_at (c_parser_peek_token (parser)->location, OPT_Wattributes, "prefix attributes are ignored for implementations"); specs->attrs = NULL_TREE; } - c_parser_objc_class_definition (parser, NULL_TREE); + c_parser_objc_class_definition (parser, NULL_TREE); return; } break; @@ -1582,7 +1582,7 @@ c_parser_declaration_or_fndef (c_parser break; } } - + pending_xref_error (); prefix_attrs = specs->attrs; all_prefix_attrs = prefix_attrs; @@ -1597,7 +1597,7 @@ c_parser_declaration_or_fndef (c_parser should diagnose if there were no declaration specifiers) or a function definition (in which case the diagnostic for implicit int suffices). */ - declarator = c_parser_declarator (parser, + declarator = c_parser_declarator (parser, specs->typespec_kind != ctsk_none, C_DTR_NORMAL, &dummy); if (declarator == NULL) @@ -1657,13 +1657,13 @@ c_parser_declaration_or_fndef (c_parser if (d) finish_decl (d, UNKNOWN_LOCATION, NULL_TREE, NULL_TREE, asm_name); - + if (c_parser_next_token_is_keyword (parser, RID_IN)) { if (d) *objc_foreach_object_declaration = d; else - *objc_foreach_object_declaration = error_mark_node; + *objc_foreach_object_declaration = error_mark_node; } } if (c_parser_next_token_is (parser, CPP_COMMA)) @@ -3084,7 +3084,7 @@ c_parser_parms_declarator (c_parser *par && !attrs && c_parser_next_token_is (parser, CPP_NAME) && c_parser_peek_token (parser)->id_kind == C_ID_ID - + /* Look ahead to detect typos in type names. */ && c_parser_peek_2nd_token (parser)->type != CPP_NAME && c_parser_peek_2nd_token (parser)->type != CPP_MULT @@ -3478,11 +3478,11 @@ c_parser_attributes (c_parser *parser) /* Parse the attribute contents. If they start with an identifier which is followed by a comma or close parenthesis, then the arguments start with that - identifier; otherwise they are an expression list. + identifier; otherwise they are an expression list. In objective-c the identifier may be a classname. */ if (c_parser_next_token_is (parser, CPP_NAME) && (c_parser_peek_token (parser)->id_kind == C_ID_ID - || (c_dialect_objc () + || (c_dialect_objc () && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA) || (c_parser_peek_2nd_token (parser)->type @@ -4771,7 +4771,7 @@ c_parser_do_statement (c_parser *parser) Here is the canonical example of the first variant: for (object in array) { do something with object } - we call the first expression ("object") the "object_expression" and + we call the first expression ("object") the "object_expression" and the second expression ("array") the "collection_expression". object_expression must be an lvalue of type "id" (a generic Objective-C object) because the loop works by assigning to object_expression the @@ -4829,10 +4829,10 @@ c_parser_for_statement (c_parser *parser } else if (c_parser_next_tokens_start_declaration (parser)) { - c_parser_declaration_or_fndef (parser, true, true, true, true, true, + c_parser_declaration_or_fndef (parser, true, true, true, true, true, &object_expression); parser->objc_could_be_foreach_context = false; - + if (c_parser_next_token_is_keyword (parser, RID_IN)) { c_parser_consume_token (parser); @@ -4861,7 +4861,7 @@ c_parser_for_statement (c_parser *parser c_parser_declaration_or_fndef (parser, true, true, true, true, true, &object_expression); parser->objc_could_be_foreach_context = false; - + restore_extension_diagnostics (ext); if (c_parser_next_token_is_keyword (parser, RID_IN)) { @@ -5345,7 +5345,7 @@ c_parser_conditional_expression (c_parse tree eptype = NULL_TREE; middle_loc = c_parser_peek_token (parser)->location; - pedwarn (middle_loc, OPT_pedantic, + pedwarn (middle_loc, OPT_pedantic, "ISO C forbids omitting the middle term of a ?: expression"); warn_for_omitted_condop (middle_loc, cond.value); if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR) @@ -5993,16 +5993,16 @@ c_parser_alignof_expression (c_parser *p for the middle-end nodes like COMPLEX_EXPR, VEC_SHUFFLE_EXPR and others. The name of the builtin is passed using BNAME parameter. Function returns true if there were no errors while parsing and - stores the arguments in EXPR_LIST. List of original types can be - obtained by passing non NULL value to ORIG_TYPES. */ + stores the arguments in CEXPR_LIST. */ static bool c_parser_get_builtin_args (c_parser *parser, const char *bname, - VEC(tree,gc) **expr_list, - VEC(tree,gc) **orig_types) + VEC(c_expr_t,gc) **ret_cexpr_list) { location_t loc = c_parser_peek_token (parser)->location; - *expr_list = NULL; + VEC (c_expr_t,gc) *cexpr_list; + c_expr_t expr; + *ret_cexpr_list = NULL; if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) { error_at (loc, "cannot take address of %qs", bname); @@ -6016,15 +6016,21 @@ c_parser_get_builtin_args (c_parser *par c_parser_consume_token (parser); return true; } - - if (orig_types) - *expr_list = c_parser_expr_list (parser, false, false, orig_types); - else - *expr_list = c_parser_expr_list (parser, false, false, NULL); + + expr = c_parser_expr_no_commas (parser, NULL); + cexpr_list = VEC_alloc (c_expr_t, gc, 1); + C_EXPR_APPEND (cexpr_list, expr); + while (c_parser_next_token_is (parser, CPP_COMMA)) + { + c_parser_consume_token (parser); + expr = c_parser_expr_no_commas (parser, NULL); + C_EXPR_APPEND (cexpr_list, expr); + } if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) return false; + *ret_cexpr_list = cexpr_list; return true; } @@ -6068,7 +6074,7 @@ c_parser_get_builtin_args (c_parser *par __builtin_types_compatible_p ( type-name , type-name ) __builtin_complex ( assignment-expression , assignment-expression ) __builtin_shuffle ( assignment-expression , assignment-expression ) - __builtin_shuffle ( assignment-expression , + __builtin_shuffle ( assignment-expression , assignment-expression , assignment-expression, ) @@ -6165,7 +6171,7 @@ c_parser_postfix_expression (c_parser *p } component = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); - expr.value = objc_build_class_component_ref (class_name, + expr.value = objc_build_class_component_ref (class_name, component); break; } @@ -6378,52 +6384,41 @@ c_parser_postfix_expression (c_parser *p break; case RID_CHOOSE_EXPR: { - VEC(tree,gc) *expr_list; - VEC(tree,gc) *orig_types; - tree e1value, e2value, e3value, c; + VEC (c_expr_t, gc) *cexpr_list; + c_expr_t *e1_p, *e2_p, *e3_p; + tree c; c_parser_consume_token (parser); if (!c_parser_get_builtin_args (parser, "__builtin_choose_expr", - &expr_list, &orig_types)) + &cexpr_list)) { expr.value = error_mark_node; break; } - if (VEC_length (tree, expr_list) != 3) + if (VEC_length (c_expr_t, cexpr_list) != 3) { error_at (loc, "wrong number of arguments to " "%<__builtin_choose_expr%>"); expr.value = error_mark_node; break; } - - e1value = VEC_index (tree, expr_list, 0); - e2value = VEC_index (tree, expr_list, 1); - e3value = VEC_index (tree, expr_list, 2); - - c = e1value; - mark_exp_read (e2value); - mark_exp_read (e3value); + + e1_p = VEC_index (c_expr_t, cexpr_list, 0); + e2_p = VEC_index (c_expr_t, cexpr_list, 1); + e3_p = VEC_index (c_expr_t, cexpr_list, 2); + + c = e1_p->value; + mark_exp_read (e2_p->value); + mark_exp_read (e3_p->value); if (TREE_CODE (c) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (c))) error_at (loc, "first argument to %<__builtin_choose_expr%> not" " a constant"); constant_expression_warning (c); - - if (integer_zerop (c)) - { - expr.value = e3value; - expr.original_type = VEC_index (tree, orig_types, 2); - } - else - { - expr.value = e2value; - expr.original_type = VEC_index (tree, orig_types, 1); - } - + expr = integer_zerop (c) ? *e3_p : *e2_p; break; } case RID_TYPES_COMPATIBLE_P: @@ -6464,50 +6459,50 @@ c_parser_postfix_expression (c_parser *p } break; case RID_BUILTIN_COMPLEX: - { - VEC(tree,gc) *expr_list; - tree e1value, e2value; - + { + VEC(c_expr_t, gc) *cexpr_list; + c_expr_t *e1_p, *e2_p; + c_parser_consume_token (parser); if (!c_parser_get_builtin_args (parser, "__builtin_complex", - &expr_list, NULL)) + &cexpr_list)) { expr.value = error_mark_node; break; } - if (VEC_length (tree, expr_list) != 2) + if (VEC_length (c_expr_t, cexpr_list) != 2) { error_at (loc, "wrong number of arguments to " "%<__builtin_complex%>"); expr.value = error_mark_node; break; } - - e1value = VEC_index (tree, expr_list, 0); - e2value = VEC_index (tree, expr_list, 1); - - mark_exp_read (e1value); - if (TREE_CODE (e1value) == EXCESS_PRECISION_EXPR) - e1value = convert (TREE_TYPE (e1value), - TREE_OPERAND (e1value, 0)); - mark_exp_read (e2value); - if (TREE_CODE (e2value) == EXCESS_PRECISION_EXPR) - e2value = convert (TREE_TYPE (e2value), - TREE_OPERAND (e2value, 0)); - if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1value)) - || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1value)) - || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2value)) - || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2value))) + + e1_p = VEC_index (c_expr_t, cexpr_list, 0); + e2_p = VEC_index (c_expr_t, cexpr_list, 1); + + mark_exp_read (e1_p->value); + if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR) + e1_p->value = convert (TREE_TYPE (e1_p->value), + TREE_OPERAND (e1_p->value, 0)); + mark_exp_read (e2_p->value); + if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR) + e2_p->value = convert (TREE_TYPE (e2_p->value), + TREE_OPERAND (e2_p->value, 0)); + if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value)) + || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value)) + || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)) + || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))) { error_at (loc, "%<__builtin_complex%> operand " "not of real binary floating-point type"); expr.value = error_mark_node; break; } - if (TYPE_MAIN_VARIANT (TREE_TYPE (e1value)) - != TYPE_MAIN_VARIANT (TREE_TYPE (e2value))) + if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value)) + != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value))) { error_at (loc, "%<__builtin_complex%> operands of different types"); @@ -6518,34 +6513,37 @@ c_parser_postfix_expression (c_parser *p pedwarn (loc, OPT_pedantic, "ISO C90 does not support complex types"); expr.value = build2 (COMPLEX_EXPR, - build_complex_type (TYPE_MAIN_VARIANT - (TREE_TYPE (e1value))), - e1value, e2value); + build_complex_type + (TYPE_MAIN_VARIANT + (TREE_TYPE (e1_p->value))), + e1_p->value, e2_p->value); break; } case RID_BUILTIN_SHUFFLE: { - VEC(tree,gc) *expr_list; - + VEC(c_expr_t,gc) *cexpr_list; + c_parser_consume_token (parser); if (!c_parser_get_builtin_args (parser, "__builtin_shuffle", - &expr_list, NULL)) + &cexpr_list)) { expr.value = error_mark_node; break; } - if (VEC_length (tree, expr_list) == 2) - expr.value = c_build_vec_shuffle_expr - (loc, VEC_index (tree, expr_list, 0), - NULL_TREE, - VEC_index (tree, expr_list, 1)); - else if (VEC_length (tree, expr_list) == 3) - expr.value = c_build_vec_shuffle_expr - (loc, VEC_index (tree, expr_list, 0), - VEC_index (tree, expr_list, 1), - VEC_index (tree, expr_list, 2)); + if (VEC_length (c_expr_t, cexpr_list) == 2) + expr.value = + c_build_vec_shuffle_expr + (loc, VEC_index (c_expr_t, cexpr_list, 0)->value, + NULL_TREE, VEC_index (c_expr_t, cexpr_list, 1)->value); + + else if (VEC_length (c_expr_t, cexpr_list) == 3) + expr.value = + c_build_vec_shuffle_expr + (loc, VEC_index (c_expr_t, cexpr_list, 0)->value, + VEC_index (c_expr_t, cexpr_list, 1)->value, + VEC_index (c_expr_t, cexpr_list, 2)->value); else { error_at (loc, "wrong number of arguments to " @@ -7154,7 +7152,7 @@ c_parser_objc_class_instance_variables ( /* There is a syntax error. We want to skip the offending tokens up to the next ';' (included) or '}' (excluded). */ - + /* First, skip manually a ')' or ']'. This is because they reduce the nesting level, so c_parser_skip_until_found() wouldn't be able to skip past them. */ @@ -7460,32 +7458,32 @@ c_parser_objc_methodproto (c_parser *par /* Forget protocol qualifiers now. */ parser->objc_pq_context = false; - /* Do not allow the presence of attributes to hide an erroneous + /* Do not allow the presence of attributes to hide an erroneous method implementation in the interface section. */ if (!c_parser_next_token_is (parser, CPP_SEMICOLON)) { c_parser_error (parser, "expected %<;%>"); return; } - + if (decl != error_mark_node) objc_add_method_declaration (is_class_method, decl, attributes); c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } -/* If we are at a position that method attributes may be present, check that - there are not any parsed already (a syntax error) and then collect any +/* If we are at a position that method attributes may be present, check that + there are not any parsed already (a syntax error) and then collect any specified at the current location. Finally, if new attributes were present, check that the next token is legal ( ';' for decls and '{' for defs). */ - -static bool + +static bool c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes) { bool bad = false; if (*attributes) { - c_parser_error (parser, + c_parser_error (parser, "method attributes must be specified at the end only"); *attributes = NULL_TREE; bad = true; @@ -7505,7 +7503,7 @@ c_parser_objc_maybe_method_attributes (c return bad; /* We've got attributes, but not at the end. */ - c_parser_error (parser, + c_parser_error (parser, "expected %<;%> or %<{%> after method attribute definition"); return true; } @@ -7610,7 +7608,7 @@ c_parser_objc_method_decl (c_parser *par { ellipsis = true; c_parser_consume_token (parser); - attr_err |= c_parser_objc_maybe_method_attributes + attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ; break; } @@ -7740,7 +7738,7 @@ c_parser_objc_protocol_refs (c_parser *p where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS. PS: This function is identical to cp_parser_objc_try_catch_finally_statement - for C++. Keep them in sync. */ + for C++. Keep them in sync. */ static void c_parser_objc_try_catch_finally_statement (c_parser *parser) @@ -7798,7 +7796,7 @@ c_parser_objc_try_catch_finally_statemen going. */ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) c_parser_consume_token (parser); - + /* If these is no immediate closing parenthesis, the user probably doesn't know that parenthesis are required at all (ie, they typed "@catch NSException *e"). So, just @@ -8042,13 +8040,13 @@ c_parser_objc_keywordexpr (c_parser *par /* A check, needed in several places, that ObjC interface, implementation or method definitions are not prefixed by incorrect items. */ static bool -c_parser_objc_diagnose_bad_element_prefix (c_parser *parser, +c_parser_objc_diagnose_bad_element_prefix (c_parser *parser, struct c_declspecs *specs) { if (!specs->declspecs_seen_p || specs->non_sc_seen_p || specs->typespec_kind != ctsk_none) { - c_parser_error (parser, + c_parser_error (parser, "no type or storage class may be specified here,"); c_parser_skip_to_end_of_block_or_statement (parser); return true; @@ -8122,7 +8120,7 @@ c_parser_objc_at_property_declaration (c { /* Eat the '(' */ c_parser_consume_token (parser); - + /* Property attribute keywords are valid now. */ parser->objc_property_attr_context = true; @@ -8203,7 +8201,7 @@ c_parser_objc_at_property_declaration (c if (syntax_error) break; - + if (c_parser_next_token_is (parser, CPP_COMMA)) c_parser_consume_token (parser); else @@ -8229,7 +8227,7 @@ c_parser_objc_at_property_declaration (c /* Comma-separated properties are chained together in reverse order; add them one by one. */ properties = nreverse (properties); - + for (; properties; properties = TREE_CHAIN (properties)) objc_add_property_declaration (loc, copy_node (properties), property_readonly, property_readwrite, @@ -8952,9 +8950,9 @@ c_parser_omp_clause_private (c_parser *p reduction-operator: One of: + * - & ^ | && || - + OpenMP 3.1: - + reduction-operator: One of: + * - & ^ | && || max min */ @@ -9602,7 +9600,7 @@ restart: rhs_expr); rhs = rhs_expr.value; rhs = c_fully_fold (rhs, false, NULL); - goto stmt_done; + goto stmt_done; } /* FALLTHROUGH */ default: Index: c-tree.h =================================================================== --- c-tree.h (revision 179464) +++ c-tree.h (working copy) @@ -130,6 +130,22 @@ struct c_expr tree original_type; }; +/* Type alias for struct c_expr. This allows to use the structure + inside the VEC types. */ +typedef struct c_expr c_expr_t; + +/* A varray of c_expr_t. */ +DEF_VEC_O (c_expr_t); +DEF_VEC_ALLOC_O (c_expr_t, gc); +DEF_VEC_ALLOC_O (c_expr_t, heap); + +/* Append a new c_expr_t element to V. */ +#define C_EXPR_APPEND(V, ELEM) \ + do { \ + c_expr_t *__elem_p = VEC_safe_push (c_expr_t, gc, V, NULL); \ + *__elem_p = (ELEM); \ + } while (0) + /* A kind of type specifier. Note that this information is currently only used to distinguish tag definitions, tag references and typeof uses. */