X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-parser.c;h=dc3f26e5a2ca67260a625bd0e261ae585985c556;hb=b3d889a555f0de3257a55e1f1ad5e3c540d4fd15;hp=3f6e949fe8e087a780984864a9ee9f9a6cb0d2b3;hpb=3bb63aebd8060e2baf8baf687c1a320e81ebba91;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 3f6e949fe8e..dc3f26e5a2c 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -1,6 +1,6 @@ /* Parser for C and Objective-C. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Parser actions based on the old Bison parser; structure somewhat @@ -40,9 +40,9 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" -#include "tm.h" +#include "tm.h" /* For rtl.h: needs enum reg_class. */ #include "tree.h" -#include "rtl.h" +#include "rtl.h" /* For decl_default_tls_model. */ #include "langhooks.h" #include "input.h" #include "cpplib.h" @@ -58,7 +58,6 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cgraph.h" #include "plugin.h" -#include "except.h" /* Initialization routine for this file. */ @@ -72,6 +71,10 @@ c_parse_init (void) tree id; int mask = 0; + /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in + the c_token structure. */ + gcc_assert (RID_MAX <= 255); + mask |= D_CXXONLY; if (!flag_isoc99) mask |= D_C99; @@ -132,6 +135,8 @@ typedef enum c_id_kind { C_ID_TYPENAME, /* An identifier declared as an Objective-C class name. */ C_ID_CLASSNAME, + /* An address space identifier. */ + C_ID_ADDRSPACE, /* Not an identifier. */ C_ID_NONE } c_id_kind; @@ -150,10 +155,10 @@ typedef struct GTY (()) c_token { /* If this token is a CPP_PRAGMA, this indicates the pragma that was seen. Otherwise it is PRAGMA_NONE. */ ENUM_BITFIELD (pragma_kind) pragma_kind : 8; - /* The value associated with this token, if any. */ - tree value; /* The location at which this token was found. */ location_t location; + /* The value associated with this token, if any. */ + tree value; } c_token; /* A parser structure recording information about the state and @@ -226,6 +231,13 @@ c_lex_one_token (c_parser *parser, c_token *token) "identifier %qE conflicts with C++ keyword", token->value); } + else if (rid_code >= RID_FIRST_ADDR_SPACE + && rid_code <= RID_LAST_ADDR_SPACE) + { + token->id_kind = C_ID_ADDRSPACE; + token->keyword = rid_code; + break; + } else if (c_dialect_objc ()) { if (!objc_is_reserved_word (token->value) @@ -352,6 +364,8 @@ c_token_starts_typename (c_token *token) { case C_ID_ID: return false; + case C_ID_ADDRSPACE: + return true; case C_ID_TYPENAME: return true; case C_ID_CLASSNAME: @@ -422,6 +436,8 @@ c_token_starts_declspecs (c_token *token) { case C_ID_ID: return false; + case C_ID_ADDRSPACE: + return true; case C_ID_TYPENAME: return true; case C_ID_CLASSNAME: @@ -478,6 +494,19 @@ c_token_starts_declspecs (c_token *token) } } + +/* Return true if TOKEN can start declaration specifiers or a static + assertion, false otherwise. */ +static bool +c_token_starts_declaration (c_token *token) +{ + if (c_token_starts_declspecs (token) + || token->keyword == RID_STATIC_ASSERT) + return true; + else + return false; +} + /* Return true if the next token from PARSER can start declaration specifiers, false otherwise. */ static inline bool @@ -487,6 +516,15 @@ c_parser_next_token_starts_declspecs (c_parser *parser) return c_token_starts_declspecs (token); } +/* Return true if the next token from PARSER can start declaration + specifiers or a static assertion, false otherwise. */ +static inline bool +c_parser_next_token_starts_declaration (c_parser *parser) +{ + c_token *token = c_parser_peek_token (parser); + return c_token_starts_declaration (token); +} + /* Return a pointer to the next-but-one token from PARSER, reading it in if necessary. The next token is already read in. */ @@ -867,7 +905,10 @@ typedef enum c_dtr_syn { static void c_parser_external_declaration (c_parser *); static void c_parser_asm_definition (c_parser *); -static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool, bool); +static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool, + bool, bool); +static void c_parser_static_assert_declaration_no_semi (c_parser *); +static void c_parser_static_assert_declaration (c_parser *); static void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool, bool); static struct c_typespec c_parser_enum_specifier (c_parser *); @@ -889,8 +930,9 @@ static tree c_parser_attributes (c_parser *); static struct c_type_name *c_parser_type_name (c_parser *); static struct c_expr c_parser_initializer (c_parser *); static struct c_expr c_parser_braced_init (c_parser *, tree, bool); -static void c_parser_initelt (c_parser *); -static void c_parser_initval (c_parser *, struct c_expr *); +static void c_parser_initelt (c_parser *, struct obstack *); +static void c_parser_initval (c_parser *, struct c_expr *, + struct obstack *); static tree c_parser_compound_statement (c_parser *); static void c_parser_compound_statement_nostart (c_parser *); static void c_parser_label (c_parser *); @@ -975,7 +1017,7 @@ c_parser_translation_unit (c_parser *parser) { if (c_parser_next_token_is (parser, CPP_EOF)) { - pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, + pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, "ISO C forbids an empty translation unit"); } else @@ -1061,7 +1103,7 @@ c_parser_external_declaration (c_parser *parser) } break; case CPP_SEMICOLON: - pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, + pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, "ISO C does not allow extra %<;%> outside of a function"); c_parser_consume_token (parser); break; @@ -1084,7 +1126,7 @@ c_parser_external_declaration (c_parser *parser) /* A declaration or a function definition. We can only tell which after parsing the declaration specifiers, if any, and the first declarator. */ - c_parser_declaration_or_fndef (parser, true, true, false, true); + c_parser_declaration_or_fndef (parser, true, true, true, false, true); break; } } @@ -1093,18 +1135,21 @@ c_parser_external_declaration (c_parser *parser) /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 6.7, 6.9.1). If FNDEF_OK is true, a function definition is accepted; otherwise (old-style parameter declarations) only other - declarations are accepted. If NESTED is true, we are inside a - function or parsing old-style parameter declarations; any functions - encountered are nested functions and declaration specifiers are - required; otherwise we are at top level and functions are normal - functions and declaration specifiers may be optional. If EMPTY_OK - is true, empty declarations are OK (subject to all other - constraints); otherwise (old-style parameter declarations) they are - diagnosed. If START_ATTR_OK is true, the declaration specifiers - may start with attributes; otherwise they may not. + declarations are accepted. If STATIC_ASSERT_OK is true, a static + assertion is accepted; otherwise (old-style parameter declarations) + it is not. If NESTED is true, we are inside a function or parsing + old-style parameter declarations; any functions encountered are + nested functions and declaration specifiers are required; otherwise + we are at top level and functions are normal functions and + declaration specifiers may be optional. If EMPTY_OK is true, empty + declarations are OK (subject to all other constraints); otherwise + (old-style parameter declarations) they are diagnosed. If + START_ATTR_OK is true, the declaration specifiers may start with + attributes; otherwise they may not. declaration: declaration-specifiers init-declarator-list[opt] ; + static_assert-declaration function-definition: declaration-specifiers[opt] declarator declaration-list[opt] @@ -1141,14 +1186,15 @@ c_parser_external_declaration (c_parser *parser) C we also allow but diagnose declarations without declaration specifiers, but only at top level (elsewhere they conflict with other syntax). - + OpenMP: - + declaration: threadprivate-directive */ static void -c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, +c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, + bool static_assert_ok, bool empty_ok, bool nested, bool start_attr_ok) { struct c_declspecs *specs; @@ -1157,6 +1203,12 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, bool diagnosed_no_specs = false; location_t here = c_parser_peek_token (parser)->location; + if (static_assert_ok + && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) + { + c_parser_static_assert_declaration (parser); + return; + } specs = build_null_declspecs (); c_parser_declspecs (parser, specs, true, true, start_attr_ok); if (parser->error) @@ -1315,7 +1367,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, function definitions either. */ while (c_parser_next_token_is_not (parser, CPP_EOF) && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE)) - c_parser_declaration_or_fndef (parser, false, false, true, false); + c_parser_declaration_or_fndef (parser, false, false, false, + true, false); store_parm_decls (); DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus = c_parser_peek_token (parser)->location; @@ -1358,6 +1411,97 @@ c_parser_asm_definition (c_parser *parser) c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } +/* Parse a static assertion (C1X N1425 6.7.10). + + static_assert-declaration: + static_assert-declaration-no-semi ; +*/ + +static void +c_parser_static_assert_declaration (c_parser *parser) +{ + c_parser_static_assert_declaration_no_semi (parser); + if (parser->error + || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) + c_parser_skip_to_end_of_block_or_statement (parser); +} + +/* Parse a static assertion (C1X N1425 6.7.10), without the trailing + semicolon. + + static_assert-declaration-no-semi: + _Static_assert ( constant-expression , string-literal ) +*/ + +static void +c_parser_static_assert_declaration_no_semi (c_parser *parser) +{ + location_t assert_loc, value_loc; + tree value; + tree string; + + gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)); + assert_loc = c_parser_peek_token (parser)->location; + if (!flag_isoc1x) + { + if (flag_isoc99) + pedwarn (assert_loc, OPT_pedantic, + "ISO C99 does not support %<_Static_assert%>"); + else + pedwarn (assert_loc, OPT_pedantic, + "ISO C90 does not support %<_Static_assert%>"); + } + c_parser_consume_token (parser); + if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + return; + value_loc = c_parser_peek_token (parser)->location; + value = c_parser_expr_no_commas (parser, NULL).value; + parser->lex_untranslated_string = true; + if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) + { + parser->lex_untranslated_string = false; + return; + } + switch (c_parser_peek_token (parser)->type) + { + case CPP_STRING: + case CPP_STRING16: + case CPP_STRING32: + case CPP_WSTRING: + case CPP_UTF8STRING: + string = c_parser_peek_token (parser)->value; + c_parser_consume_token (parser); + parser->lex_untranslated_string = false; + break; + default: + c_parser_error (parser, "expected string literal"); + parser->lex_untranslated_string = false; + return; + } + c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + + if (!INTEGRAL_TYPE_P (TREE_TYPE (value))) + { + error_at (value_loc, "expression in static assertion is not an integer"); + return; + } + if (TREE_CODE (value) != INTEGER_CST) + { + value = c_fully_fold (value, false, NULL); + if (TREE_CODE (value) == INTEGER_CST) + pedwarn (value_loc, OPT_pedantic, "expression in static assertion " + "is not an integer constant expression"); + } + if (TREE_CODE (value) != INTEGER_CST) + { + error_at (value_loc, "expression in static assertion is not constant"); + return; + } + constant_expression_warning (value); + if (integer_zerop (value)) + error_at (assert_loc, "static assertion failed: %E", string); +} + /* Parse some declaration specifiers (possibly none) (C90 6.5, C99 6.7), adding them to SPECS (which may already include some). Storage class specifiers are accepted iff SCSPEC_OK; type @@ -1411,6 +1555,7 @@ c_parser_asm_definition (c_parser *parser) const restrict volatile + address-space-qualifier (restrict is new in C99.) @@ -1419,6 +1564,12 @@ c_parser_asm_definition (c_parser *parser) declaration-specifiers: attributes declaration-specifiers[opt] + type-qualifier: + address-space + + address-space: + identifier recognized by the target + storage-class-specifier: __thread @@ -1459,6 +1610,17 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, { tree value = c_parser_peek_token (parser)->value; c_id_kind kind = c_parser_peek_token (parser)->id_kind; + + if (kind == C_ID_ADDRSPACE) + { + addr_space_t as + = c_parser_peek_token (parser)->keyword - RID_FIRST_ADDR_SPACE; + declspecs_add_addrspace (specs, as); + c_parser_consume_token (parser); + attrs_ok = true; + continue; + } + /* This finishes the specifiers unless a type name is OK, it is declared as a type name and a type name hasn't yet been seen. */ @@ -1873,7 +2035,7 @@ c_parser_struct_or_union_specifier (c_parser *parser) /* Parse any stray semicolon. */ if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { - pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, + pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, "extra semicolon in struct or union specified"); c_parser_consume_token (parser); continue; @@ -1902,7 +2064,7 @@ c_parser_struct_or_union_specifier (c_parser *parser) else { if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) - pedwarn (c_parser_peek_token (parser)->location, 0, + pedwarn (c_parser_peek_token (parser)->location, 0, "no semicolon at end of struct or union"); else { @@ -1938,6 +2100,7 @@ c_parser_struct_or_union_specifier (c_parser *parser) struct-declaration: specifier-qualifier-list struct-declarator-list + static_assert-declaration-no-semi specifier-qualifier-list: type-specifier specifier-qualifier-list[opt] @@ -1982,6 +2145,11 @@ c_parser_struct_declaration (c_parser *parser) restore_extension_diagnostics (ext); return decl; } + if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) + { + c_parser_static_assert_declaration_no_semi (parser); + return NULL_TREE; + } specs = build_null_declspecs (); decl_loc = c_parser_peek_token (parser)->location; c_parser_declspecs (parser, specs, false, true, true); @@ -1998,7 +2166,7 @@ c_parser_struct_declaration (c_parser *parser) tree ret; if (!specs->type_seen_p) { - pedwarn (decl_loc, OPT_pedantic, + pedwarn (decl_loc, OPT_pedantic, "ISO C forbids member declarations with no members"); shadow_tag_warned (specs, pedantic); ret = NULL_TREE; @@ -2136,6 +2304,7 @@ c_parser_typeof_specifier (c_parser *parser) if (TREE_CODE (expr.value) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) error_at (here, "% applied to a bit-field"); + mark_exp_read (expr.value); ret.spec = TREE_TYPE (expr.value); was_vm = variably_modified_type_p (ret.spec, NULL_TREE); /* This is returned with the type so that when the type is @@ -2379,7 +2548,7 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present, /* Parse a sequence of array declarators and parameter lists. */ if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) { - location_t brace_loc = c_parser_peek_token (parser)->location; + location_t brace_loc = c_parser_peek_token (parser)->location; struct c_declarator *declarator; struct c_declspecs *quals_attrs = build_null_declspecs (); bool static_seen; @@ -2437,6 +2606,8 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present, "expected %<]%>"); return NULL; } + if (dimen) + mark_exp_read (dimen); declarator = build_array_declarator (brace_loc, dimen, quals_attrs, static_seen, star_seen); if (declarator == NULL) @@ -3038,7 +3209,7 @@ c_parser_initializer (c_parser *parser) ret = c_parser_expr_no_commas (parser, NULL); if (TREE_CODE (ret.value) != STRING_CST && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR) - ret = default_function_array_conversion (loc, ret); + ret = default_function_array_read_conversion (loc, ret); return ret; } } @@ -3052,11 +3223,14 @@ c_parser_initializer (c_parser *parser) static struct c_expr c_parser_braced_init (c_parser *parser, tree type, bool nested_p) { + struct c_expr ret; + struct obstack braced_init_obstack; location_t brace_loc = c_parser_peek_token (parser)->location; + gcc_obstack_init (&braced_init_obstack); gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); c_parser_consume_token (parser); if (nested_p) - push_init_level (0); + push_init_level (0, &braced_init_obstack); else really_start_incremental_init (type); if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) @@ -3069,7 +3243,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) comma. */ while (true) { - c_parser_initelt (parser); + c_parser_initelt (parser, &braced_init_obstack); if (parser->error) break; if (c_parser_next_token_is (parser, CPP_COMMA)) @@ -3082,22 +3256,24 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) } if (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) { - struct c_expr ret; ret.value = error_mark_node; ret.original_code = ERROR_MARK; ret.original_type = NULL; c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>"); - pop_init_level (0); + pop_init_level (0, &braced_init_obstack); + obstack_free (&braced_init_obstack, NULL); return ret; } c_parser_consume_token (parser); - return pop_init_level (0); + ret = pop_init_level (0, &braced_init_obstack); + obstack_free (&braced_init_obstack, NULL); + return ret; } /* Parse a nested initializer, including designators. */ static void -c_parser_initelt (c_parser *parser) +c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) { /* Parse any designator or designator list. A single array designator may have the subsequent "=" omitted in GNU C, but a @@ -3106,9 +3282,10 @@ c_parser_initelt (c_parser *parser) && c_parser_peek_2nd_token (parser)->type == CPP_COLON) { /* Old-style structure member designator. */ - set_init_label (c_parser_peek_token (parser)->value); + set_init_label (c_parser_peek_token (parser)->value, + braced_init_obstack); /* Use the colon as the error location. */ - pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic, + pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic, "obsolete use of designated initializer with %<:%>"); c_parser_consume_token (parser); c_parser_consume_token (parser); @@ -3134,7 +3311,8 @@ c_parser_initelt (c_parser *parser) c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_NAME)) { - set_init_label (c_parser_peek_token (parser)->value); + set_init_label (c_parser_peek_token (parser)->value, + braced_init_obstack); c_parser_consume_token (parser); } else @@ -3145,7 +3323,7 @@ c_parser_initelt (c_parser *parser) init.original_type = NULL; c_parser_error (parser, "expected identifier"); c_parser_skip_until_found (parser, CPP_COMMA, NULL); - process_init_element (init, false); + process_init_element (init, false, braced_init_obstack); return; } } @@ -3194,6 +3372,7 @@ c_parser_initelt (c_parser *parser) goto parse_message_args; } first = c_parser_expr_no_commas (parser, NULL).value; + mark_exp_read (first); if (c_parser_next_token_is (parser, CPP_ELLIPSIS) || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) goto array_desig_after_first; @@ -3209,7 +3388,8 @@ c_parser_initelt (c_parser *parser) c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; next = c_parser_expr_no_commas (parser, NULL); - next = default_function_array_conversion (exp_loc, next); + next = default_function_array_read_conversion (exp_loc, + next); rec = build_compound_expr (comma_loc, rec, next.value); } parse_message_args: @@ -3224,26 +3404,28 @@ c_parser_initelt (c_parser *parser) /* Now parse and process the remainder of the initializer, starting with this message expression as a primary-expression. */ - c_parser_initval (parser, &mexpr); + c_parser_initval (parser, &mexpr, braced_init_obstack); return; } c_parser_consume_token (parser); first = c_parser_expr_no_commas (parser, NULL).value; + mark_exp_read (first); array_desig_after_first: if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) { ellipsis_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); second = c_parser_expr_no_commas (parser, NULL).value; + mark_exp_read (second); } else second = NULL_TREE; if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) { c_parser_consume_token (parser); - set_init_index (first, second); + set_init_index (first, second, braced_init_obstack); if (second) - pedwarn (ellipsis_loc, OPT_pedantic, + pedwarn (ellipsis_loc, OPT_pedantic, "ISO C forbids specifying range of elements to initialize"); } else @@ -3256,14 +3438,14 @@ c_parser_initelt (c_parser *parser) if (c_parser_next_token_is (parser, CPP_EQ)) { if (!flag_isoc99) - pedwarn (des_loc, OPT_pedantic, + pedwarn (des_loc, OPT_pedantic, "ISO C90 forbids specifying subobject to initialize"); c_parser_consume_token (parser); } else { if (des_seen == 1) - pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, + pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, "obsolete use of designated initializer without %<=%>"); else { @@ -3273,13 +3455,13 @@ c_parser_initelt (c_parser *parser) init.original_type = NULL; c_parser_error (parser, "expected %<=%>"); c_parser_skip_until_found (parser, CPP_COMMA, NULL); - process_init_element (init, false); + process_init_element (init, false, braced_init_obstack); return; } } } } - c_parser_initval (parser, NULL); + c_parser_initval (parser, NULL, braced_init_obstack); } /* Parse a nested initializer; as c_parser_initializer but parses @@ -3289,7 +3471,8 @@ c_parser_initelt (c_parser *parser) initializer. */ static void -c_parser_initval (c_parser *parser, struct c_expr *after) +c_parser_initval (c_parser *parser, struct c_expr *after, + struct obstack * braced_init_obstack) { struct c_expr init; gcc_assert (!after || c_dialect_objc ()); @@ -3302,9 +3485,9 @@ c_parser_initval (c_parser *parser, struct c_expr *after) if (init.value != NULL_TREE && TREE_CODE (init.value) != STRING_CST && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR) - init = default_function_array_conversion (loc, init); + init = default_function_array_read_conversion (loc, init); } - process_init_element (init, false); + process_init_element (init, false, braced_init_obstack); } /* Parse a compound statement (possibly a function body) (C90 6.6.2, @@ -3350,9 +3533,9 @@ c_parser_initval (c_parser *parser, struct c_expr *after) old parser in requiring something after label declarations. Although they are erroneous if the labels declared aren't defined, is it useful for the syntax to be this way? - + OpenMP: - + block-item: openmp-directive @@ -3455,13 +3638,13 @@ c_parser_compound_statement_nostart (c_parser *parser) c_parser_label (parser); } else if (!last_label - && c_parser_next_token_starts_declspecs (parser)) + && c_parser_next_token_starts_declaration (parser)) { last_label = false; mark_valid_location_for_stdc_pragma (false); - c_parser_declaration_or_fndef (parser, true, true, true, true); + c_parser_declaration_or_fndef (parser, true, true, true, true, true); if (last_stmt) - pedwarn_c90 (loc, + pedwarn_c90 (loc, (pedantic && !flag_isoc99) ? OPT_pedantic : OPT_Wdeclaration_after_statement, @@ -3479,14 +3662,15 @@ c_parser_compound_statement_nostart (c_parser *parser) && (c_parser_peek_2nd_token (parser)->keyword == RID_EXTENSION)) c_parser_consume_token (parser); - if (c_token_starts_declspecs (c_parser_peek_2nd_token (parser))) + if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))) { int ext; ext = disable_extension_diagnostics (); c_parser_consume_token (parser); last_label = false; mark_valid_location_for_stdc_pragma (false); - c_parser_declaration_or_fndef (parser, true, true, true, true); + c_parser_declaration_or_fndef (parser, true, true, true, true, + true); /* Following the old parser, __extension__ does not disable this diagnostic. */ restore_extension_diagnostics (ext); @@ -3518,13 +3702,13 @@ c_parser_compound_statement_nostart (c_parser *parser) } else if (c_parser_next_token_is_keyword (parser, RID_ELSE)) { - if (parser->in_if_block) + if (parser->in_if_block) { mark_valid_location_for_stdc_pragma (save_valid_for_pragma); error_at (loc, """expected %<}%> before %"); return; } - else + else { error_at (loc, "% without a previous %"); c_parser_consume_token (parser); @@ -3616,14 +3800,15 @@ c_parser_label (c_parser *parser) } if (label) { - if (c_parser_next_token_starts_declspecs (parser) + if (c_parser_next_token_starts_declaration (parser) && !(c_parser_next_token_is (parser, CPP_NAME) && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) { error_at (c_parser_peek_token (parser)->location, "a label can only be part of a statement and " "a declaration is not a statement"); - c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false, + c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false, + /*static_assert_ok*/ true, /*nested*/ true, /*empty_ok*/ false, /*start_attr_ok*/ true); } @@ -3805,6 +3990,7 @@ c_parser_statement_after_labels (c_parser *parser) else { struct c_expr expr = c_parser_expression_conv (parser); + mark_exp_read (expr.value); stmt = c_finish_return (loc, expr.value, expr.original_type); goto expect_semicolon; } @@ -3979,7 +4165,7 @@ c_parser_else_body (c_parser *parser) add_stmt (build_empty_stmt (loc)); c_parser_consume_token (parser); } - else + else c_parser_statement_after_labels (parser); return c_end_compound_stmt (else_loc, block, flag_isoc99); } @@ -4159,9 +4345,9 @@ c_parser_for_statement (c_parser *parser) c_parser_consume_token (parser); c_finish_expr_stmt (loc, NULL_TREE); } - else if (c_parser_next_token_starts_declspecs (parser)) + else if (c_parser_next_token_starts_declaration (parser)) { - c_parser_declaration_or_fndef (parser, true, true, true, true); + c_parser_declaration_or_fndef (parser, true, true, true, true, true); check_for_loop_decls (for_loc); } else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) @@ -4174,12 +4360,13 @@ c_parser_for_statement (c_parser *parser) && (c_parser_peek_2nd_token (parser)->keyword == RID_EXTENSION)) c_parser_consume_token (parser); - if (c_token_starts_declspecs (c_parser_peek_2nd_token (parser))) + if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))) { int ext; ext = disable_extension_diagnostics (); c_parser_consume_token (parser); - c_parser_declaration_or_fndef (parser, true, true, true, true); + c_parser_declaration_or_fndef (parser, true, true, true, true, + true); restore_extension_diagnostics (ext); check_for_loop_decls (for_loc); } @@ -4420,6 +4607,7 @@ c_parser_asm_operands (c_parser *parser, bool convert_p) } loc = c_parser_peek_token (parser)->location; expr = c_parser_expression (parser); + mark_exp_read (expr.value); if (convert_p) expr = default_function_array_conversion (loc, expr); expr.value = c_fully_fold (expr.value, false, NULL); @@ -4466,7 +4654,7 @@ c_parser_asm_clobbers (c_parser *parser) } /* Parse asm goto labels, a GNU extension. - + asm-goto-operands: identifier asm-goto-operands , identifier @@ -4570,7 +4758,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after) c_parser_consume_token (parser); exp_location = c_parser_peek_token (parser)->location; rhs = c_parser_expr_no_commas (parser, NULL); - rhs = default_function_array_conversion (exp_location, rhs); + rhs = default_function_array_read_conversion (exp_location, rhs); ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type, code, exp_location, rhs.value, rhs.original_type); @@ -4612,12 +4800,12 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after) if (c_parser_next_token_is_not (parser, CPP_QUERY)) return cond; cond_loc = c_parser_peek_token (parser)->location; - cond = default_function_array_conversion (cond_loc, cond); + cond = default_function_array_read_conversion (cond_loc, cond); c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_COLON)) { tree eptype = NULL_TREE; - pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, + pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, "ISO C forbids omitting the middle term of a ?: expression"); if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR) { @@ -4639,6 +4827,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after) (cond_loc, default_conversion (cond.value)); c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node; exp1 = c_parser_expression_conv (parser); + mark_exp_read (exp1.value); c_inhibit_evaluation_warnings += ((cond.value == truthvalue_true_node) - (cond.value == truthvalue_false_node)); @@ -4656,7 +4845,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after) { location_t exp2_loc = c_parser_peek_token (parser)->location; exp2 = c_parser_conditional_expression (parser, NULL); - exp2 = default_function_array_conversion (exp2_loc, exp2); + exp2 = default_function_array_read_conversion (exp2_loc, exp2); } c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node; ret.value = build_conditional_expr (colon_loc, cond.value, @@ -4809,10 +4998,11 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after) break; \ } \ stack[sp - 1].expr \ - = default_function_array_conversion (stack[sp - 1].loc, \ - stack[sp - 1].expr); \ + = default_function_array_read_conversion (stack[sp - 1].loc, \ + stack[sp - 1].expr); \ stack[sp].expr \ - = default_function_array_conversion (stack[sp].loc, stack[sp].expr); \ + = default_function_array_read_conversion (stack[sp].loc, \ + stack[sp].expr); \ stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \ stack[sp].op, \ stack[sp - 1].expr, \ @@ -4917,8 +5107,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after) { case TRUTH_ANDIF_EXPR: stack[sp].expr - = default_function_array_conversion (stack[sp].loc, - stack[sp].expr); + = default_function_array_read_conversion (stack[sp].loc, + stack[sp].expr); stack[sp].expr.value = c_objc_common_truthvalue_conversion (stack[sp].loc, default_conversion (stack[sp].expr.value)); c_inhibit_evaluation_warnings += (stack[sp].expr.value @@ -4926,8 +5116,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after) break; case TRUTH_ORIF_EXPR: stack[sp].expr - = default_function_array_conversion (stack[sp].loc, - stack[sp].expr); + = default_function_array_read_conversion (stack[sp].loc, + stack[sp].expr); stack[sp].expr.value = c_objc_common_truthvalue_conversion (stack[sp].loc, default_conversion (stack[sp].expr.value)); c_inhibit_evaluation_warnings += (stack[sp].expr.value @@ -4997,7 +5187,7 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after) { location_t expr_loc = c_parser_peek_token (parser)->location; expr = c_parser_cast_expression (parser, NULL); - expr = default_function_array_conversion (expr_loc, expr); + expr = default_function_array_read_conversion (expr_loc, expr); } ret.value = c_cast_expr (cast_loc, type_name, expr.value); ret.original_code = ERROR_MARK; @@ -5050,24 +5240,25 @@ c_parser_unary_expression (c_parser *parser) c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - op = default_function_array_conversion (exp_loc, op); + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op); case CPP_MINUS_MINUS: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - op = default_function_array_conversion (exp_loc, op); + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op); case CPP_AND: c_parser_consume_token (parser); - return parser_build_unary_op (op_loc, ADDR_EXPR, - c_parser_cast_expression (parser, NULL)); + op = c_parser_cast_expression (parser, NULL); + mark_exp_read (op.value); + return parser_build_unary_op (op_loc, ADDR_EXPR, op); case CPP_MULT: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - op = default_function_array_conversion (exp_loc, op); - ret.value = build_indirect_ref (op_loc, op.value, "unary *"); + op = default_function_array_read_conversion (exp_loc, op); + ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR); return ret; case CPP_PLUS: if (!c_dialect_objc () && !in_system_header) @@ -5077,25 +5268,25 @@ c_parser_unary_expression (c_parser *parser) c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - op = default_function_array_conversion (exp_loc, op); + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, CONVERT_EXPR, op); case CPP_MINUS: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - op = default_function_array_conversion (exp_loc, op); + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, NEGATE_EXPR, op); case CPP_COMPL: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - op = default_function_array_conversion (exp_loc, op); + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op); case CPP_NOT: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - op = default_function_array_conversion (exp_loc, op); + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op); case CPP_AND_AND: /* Refer to the address of a label as a pointer. */ @@ -5195,6 +5386,7 @@ c_parser_sizeof_expression (c_parser *parser) sizeof_expr: c_inhibit_evaluation_warnings--; in_sizeof--; + mark_exp_read (expr.value); if (TREE_CODE (expr.value) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) error_at (expr_loc, "% applied to a bit-field"); @@ -5255,6 +5447,7 @@ c_parser_alignof_expression (c_parser *parser) struct c_expr ret; expr = c_parser_unary_expression (parser); alignof_expr: + mark_exp_read (expr.value); c_inhibit_evaluation_warnings--; in_alignof--; ret.value = c_alignof_expr (loc, expr.value); @@ -5349,6 +5542,7 @@ c_parser_postfix_expression (c_parser *parser) case CPP_STRING16: case CPP_STRING32: case CPP_WSTRING: + case CPP_UTF8STRING: expr.value = c_parser_peek_token (parser)->value; expr.original_code = STRING_CST; c_parser_consume_token (parser); @@ -5400,7 +5594,7 @@ c_parser_postfix_expression (c_parser *parser) c_parser_compound_statement_nostart (parser); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); - pedwarn (loc, OPT_pedantic, + pedwarn (loc, OPT_pedantic, "ISO C forbids braced-groups within expressions"); expr.value = c_finish_stmt_expr (brace_loc, stmt); } @@ -5459,6 +5653,7 @@ c_parser_postfix_expression (c_parser *parser) break; } e1 = c_parser_expr_no_commas (parser, NULL); + mark_exp_read (e1.value); e1.value = c_fully_fold (e1.value, false, NULL); if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) { @@ -5603,6 +5798,8 @@ c_parser_postfix_expression (c_parser *parser) tree c; c = e1.value; + mark_exp_read (e2.value); + mark_exp_read (e3.value); if (TREE_CODE (c) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (c))) error_at (loc, @@ -5774,6 +5971,14 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser, finish_init (); maybe_warn_string_init (type, init); + if (type != error_mark_node + && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type)) + && current_function_decl) + { + error ("compound literal qualified by address-space qualifier"); + type = error_mark_node; + } + if (!flag_isoc99) pedwarn (start_loc, OPT_pedantic, "ISO C90 forbids compound literals"); non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR) @@ -5839,6 +6044,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); orig_expr = expr; + mark_exp_read (expr.value); /* FIXME diagnostics: Ideally we want the FUNCNAME, not the "(" after the FUNCNAME, which is what we have now. */ expr.value = build_function_call_vec (op_loc, expr.value, exprlist, @@ -5903,7 +6109,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, expr.value = build_component_ref (op_loc, build_indirect_ref (op_loc, expr.value, - "->"), + RO_ARROW), ident); expr.original_code = ERROR_MARK; if (TREE_CODE (expr.value) != COMPONENT_REF) @@ -5921,7 +6127,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, case CPP_PLUS_PLUS: /* Postincrement. */ c_parser_consume_token (parser); - expr = default_function_array_conversion (expr_loc, expr); + expr = default_function_array_read_conversion (expr_loc, expr); expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR, expr.value, 0); expr.original_code = ERROR_MARK; @@ -5930,7 +6136,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, case CPP_MINUS_MINUS: /* Postdecrement. */ c_parser_consume_token (parser); - expr = default_function_array_conversion (expr_loc, expr); + expr = default_function_array_read_conversion (expr_loc, expr); expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR, expr.value, 0); expr.original_code = ERROR_MARK; @@ -5957,10 +6163,16 @@ c_parser_expression (c_parser *parser) while (c_parser_next_token_is (parser, CPP_COMMA)) { struct c_expr next; + tree lhsval; location_t loc = c_parser_peek_token (parser)->location; location_t expr_loc; c_parser_consume_token (parser); expr_loc = c_parser_peek_token (parser)->location; + lhsval = expr.value; + while (TREE_CODE (lhsval) == COMPOUND_EXPR) + lhsval = TREE_OPERAND (lhsval, 1); + if (DECL_P (lhsval) || handled_component_p (lhsval)) + mark_exp_read (lhsval); next = c_parser_expr_no_commas (parser, NULL); next = default_function_array_conversion (expr_loc, next); expr.value = build_compound_expr (loc, expr.value, next.value); @@ -6008,7 +6220,7 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, expr = c_parser_expr_no_commas (parser, NULL); if (convert_p) - expr = default_function_array_conversion (loc, expr); + expr = default_function_array_read_conversion (loc, expr); if (fold_p) expr.value = c_fully_fold (expr.value, false, NULL); VEC_quick_push (tree, ret, expr.value); @@ -6020,7 +6232,7 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, loc = c_parser_peek_token (parser)->location; expr = c_parser_expr_no_commas (parser, NULL); if (convert_p) - expr = default_function_array_conversion (loc, expr); + expr = default_function_array_read_conversion (loc, expr); if (fold_p) expr.value = c_fully_fold (expr.value, false, NULL); VEC_safe_push (tree, gc, ret, expr.value); @@ -6172,7 +6384,7 @@ c_parser_objc_class_instance_variables (c_parser *parser) /* Parse any stray semicolon. */ if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { - pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, + pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, "extra semicolon in struct or union specified"); c_parser_consume_token (parser); continue; @@ -6389,7 +6601,7 @@ c_parser_objc_method_definition (c_parser *parser) if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { c_parser_consume_token (parser); - pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, + pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, "extra semicolon in method definition specified"); } if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE)) @@ -6426,7 +6638,7 @@ c_parser_objc_methodprotolist (c_parser *parser) switch (c_parser_peek_token (parser)->type) { case CPP_SEMICOLON: - pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, + pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, "ISO C does not allow extra %<;%> outside of a function"); c_parser_consume_token (parser); break; @@ -6442,7 +6654,8 @@ c_parser_objc_methodprotolist (c_parser *parser) default: if (c_parser_next_token_is_keyword (parser, RID_AT_END)) return; - c_parser_declaration_or_fndef (parser, false, true, false, true); + c_parser_declaration_or_fndef (parser, false, false, true, + false, true); break; } } @@ -7002,7 +7215,7 @@ c_parser_pragma (c_parser *parser, enum pragma_context context) c_parser_consume_pragma (parser); c_invoke_pragma_handler (id); - /* Skip to EOL, but suppress any error message. Those will have been + /* Skip to EOL, but suppress any error message. Those will have been generated by the handler routine through calling error, as opposed to calling c_parser_error. */ parser->error = true; @@ -7766,7 +7979,7 @@ c_parser_omp_structured_block (c_parser *parser) binop: +, *, -, /, &, ^, |, <<, >> - where x is an lvalue expression with scalar type. + where x is an lvalue expression with scalar type. LOC is the location of the #pragma token. */ @@ -7843,7 +8056,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) { location_t rhs_loc = c_parser_peek_token (parser)->location; rhs_expr = c_parser_expression (parser); - rhs_expr = default_function_array_conversion (rhs_loc, rhs_expr); + rhs_expr = default_function_array_read_conversion (rhs_loc, rhs_expr); } rhs = rhs_expr.value; rhs = c_fully_fold (rhs, false, NULL); @@ -7963,12 +8176,12 @@ c_parser_omp_for_loop (location_t loc, goto pop_scopes; /* Parse the initialization declaration or expression. */ - if (c_parser_next_token_starts_declspecs (parser)) + if (c_parser_next_token_starts_declaration (parser)) { if (i > 0) for_block = tree_cons (NULL, c_begin_compound_stmt (true), for_block); - c_parser_declaration_or_fndef (parser, true, true, true, true); + c_parser_declaration_or_fndef (parser, true, true, true, true, true); decl = check_for_loop_decls (for_loc); if (decl == NULL) goto error_init; @@ -7990,7 +8203,8 @@ c_parser_omp_for_loop (location_t loc, init_loc = c_parser_peek_token (parser)->location; init_exp = c_parser_expr_no_commas (parser, NULL); - init_exp = default_function_array_conversion (init_loc, init_exp); + init_exp = default_function_array_read_conversion (init_loc, + init_exp); init = build_modify_expr (init_loc, decl, decl_exp.original_type, NOP_EXPR, init_loc, init_exp.value, init_exp.original_type); @@ -8276,7 +8490,7 @@ c_parser_omp_ordered (location_t loc, c_parser *parser) section-sequence: section-directive[opt] structured-block - section-sequence section-directive structured-block + section-sequence section-directive structured-block SECTIONS_LOC is the location of the #pragma omp sections. */