X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-decl.c;h=a9929c1a85c2aad7c55c219823996c55d61d7b19;hb=27f97b121b8499a35e7f1d915649d099ebe7fcfe;hp=ae8861e2b8504358221be0be9d16e8fb57536956;hpb=aaa76ff28925caba3b152379980ca2d60fe8ee74;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-decl.c b/gcc/c-decl.c index ae8861e2b85..a9929c1a85c 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks-def.h" #include "pointer-set.h" #include "gimple.h" +#include "plugin.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -125,6 +126,15 @@ static GTY(()) struct stmt_tree_s c_stmt_tree; tree c_break_label; tree c_cont_label; +/* True if we are currently parsing the fields of a struct or + union. */ + +static bool in_struct; + +/* A list of types defined in the current struct or union. */ + +static VEC(tree,heap) *struct_types; + /* Linked list of TRANSLATION_UNIT_DECLS for the translation units included in this invocation. Note that the current translation unit is not included in this list. */ @@ -197,8 +207,7 @@ bool c_override_global_bindings_to_false; in all such cases, the binding in the outer scope will have its invisible bit true. */ -struct c_binding GTY((chain_next ("%h.prev"))) -{ +struct GTY((chain_next ("%h.prev"))) c_binding { tree decl; /* the decl bound */ tree type; /* the type in this scope */ tree id; /* the identifier it's bound to */ @@ -209,6 +218,7 @@ struct c_binding GTY((chain_next ("%h.prev"))) BOOL_BITFIELD nested : 1; /* do not set DECL_CONTEXT when popping */ BOOL_BITFIELD inner_comp : 1; /* incomplete array completed in inner scope */ /* one free bit */ + location_t locus; /* location for nested bindings */ }; #define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth) #define B_IN_CURRENT_SCOPE(b) ((b)->depth == current_scope->depth) @@ -234,8 +244,7 @@ struct c_binding GTY((chain_next ("%h.prev"))) These describe the values of the identifier in the three different namespaces defined by the language. */ -struct lang_identifier GTY(()) -{ +struct GTY(()) lang_identifier { struct c_common_identifier common_id; struct c_binding *symbol_binding; /* vars, funcs, constants, typedefs */ struct c_binding *tag_binding; /* struct/union/enum tags */ @@ -248,10 +257,9 @@ extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate /* The resulting tree type. */ -union lang_tree_node - GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), - chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))"))) -{ +union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), + chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))"))) lang_tree_node + { union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic; @@ -303,8 +311,7 @@ union lang_tree_node pop_scope relies on this. */ -struct c_scope GTY((chain_next ("%h.outer"))) -{ +struct GTY((chain_next ("%h.outer"))) c_scope { /* The scope containing this one. */ struct c_scope *outer; @@ -344,6 +351,9 @@ struct c_scope GTY((chain_next ("%h.outer"))) /* True means make a BLOCK for this scope no matter what. */ BOOL_BITFIELD keep : 1; + + /* True means that an unsuffixed float constant is _Decimal64. */ + BOOL_BITFIELD float_const_decimal64 : 1; }; /* The scope currently in effect. */ @@ -395,6 +405,32 @@ static GTY((deletable)) struct c_binding *binding_freelist; t_->to##_last = f_->from##_last; \ } while (0) +/* A c_inline_static structure stores details of a static identifier + referenced in a definition of a function that may be an inline + definition if no subsequent declaration of that function uses + "extern" or does not use "inline". */ + +struct GTY((chain_next ("%h.next"))) c_inline_static { + /* The location for a diagnostic. */ + location_t location; + + /* The function that may be an inline definition. */ + tree function; + + /* The object or function referenced. */ + tree static_decl; + + /* What sort of reference this is. */ + enum c_inline_static_type type; + + /* The next such structure or NULL. */ + struct c_inline_static *next; +}; + +/* List of static identifiers used or referenced in functions that may + be inline definitions. */ +static GTY(()) struct c_inline_static *c_inline_statics; + /* True means unconditionally make a BLOCK for the next scope pushed. */ static bool keep_next_level_flag; @@ -410,8 +446,8 @@ static tree lookup_name_in_scope (tree, struct c_scope *); static tree c_make_fname_decl (tree, int); static tree grokdeclarator (const struct c_declarator *, struct c_declspecs *, - enum decl_context, bool, tree *, tree *, - enum deprecated_states); + enum decl_context, bool, tree *, tree *, tree *, + bool *, enum deprecated_states); static tree grokparms (struct c_arg_info *, bool); static void layout_array_type (tree); @@ -460,7 +496,8 @@ c_print_identifier (FILE *file, tree node, int indent) which may be any of several kinds of DECL or TYPE or error_mark_node, in the scope SCOPE. */ static void -bind (tree name, tree decl, struct c_scope *scope, bool invisible, bool nested) +bind (tree name, tree decl, struct c_scope *scope, bool invisible, + bool nested, location_t locus) { struct c_binding *b, **here; @@ -479,6 +516,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible, bool nested) b->invisible = invisible; b->nested = nested; b->inner_comp = 0; + b->locus = locus; b->type = 0; @@ -555,6 +593,53 @@ c_finish_incomplete_decl (tree decl) } } +/* Record that inline function FUNC contains a reference (location + LOC) to static DECL (file-scope or function-local according to + TYPE). */ + +void +record_inline_static (location_t loc, tree func, tree decl, + enum c_inline_static_type type) +{ + struct c_inline_static *csi = GGC_NEW (struct c_inline_static); + csi->location = loc; + csi->function = func; + csi->static_decl = decl; + csi->type = type; + csi->next = c_inline_statics; + c_inline_statics = csi; +} + +/* Check for references to static declarations in inline functions at + the end of the translation unit and diagnose them if the functions + are still inline definitions. */ + +static void +check_inline_statics (void) +{ + struct c_inline_static *csi; + for (csi = c_inline_statics; csi; csi = csi->next) + { + if (DECL_EXTERNAL (csi->function)) + switch (csi->type) + { + case csi_internal: + pedwarn (csi->location, 0, + "%qD is static but used in inline function %qD " + "which is not static", csi->static_decl, csi->function); + break; + case csi_modifiable: + pedwarn (csi->location, 0, + "%q+D is static but declared in inline function %qD " + "which is not static", csi->static_decl, csi->function); + break; + default: + gcc_unreachable (); + } + } + c_inline_statics = NULL; +} + /* The Objective-C front-end often needs to determine the current scope. */ void * @@ -590,7 +675,9 @@ objc_mark_locals_volatile (void *enclosing_blk) int global_bindings_p (void) { - return current_scope == file_scope && !c_override_global_bindings_to_false; + return (current_scope == file_scope && !c_override_global_bindings_to_false + ? -1 + : 0); } void @@ -599,6 +686,30 @@ keep_next_level (void) keep_next_level_flag = true; } +/* Set the flag for the FLOAT_CONST_DECIMAL64 pragma being ON. */ + +void +set_float_const_decimal64 (void) +{ + current_scope->float_const_decimal64 = true; +} + +/* Clear the flag for the FLOAT_CONST_DECIMAL64 pragma. */ + +void +clear_float_const_decimal64 (void) +{ + current_scope->float_const_decimal64 = false; +} + +/* Return nonzero if an unsuffixed float constant is _Decimal64. */ + +bool +float_const_decimal64_p (void) +{ + return current_scope->float_const_decimal64; +} + /* Identify this scope as currently being filled with parameters. */ void @@ -630,6 +741,13 @@ push_scope (void) keep_next_level_flag = false; next_is_function_body = false; + + /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */ + if (current_scope->outer) + current_scope->float_const_decimal64 + = current_scope->outer->float_const_decimal64; + else + current_scope->float_const_decimal64 = false; } else { @@ -642,6 +760,12 @@ push_scope (void) else scope = GGC_CNEW (struct c_scope); + /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */ + if (current_scope) + scope->float_const_decimal64 = current_scope->float_const_decimal64; + else + scope->float_const_decimal64 = false; + scope->keep = keep_next_level_flag; scope->outer = current_scope; scope->depth = current_scope ? (current_scope->depth + 1) : 0; @@ -781,14 +905,18 @@ pop_scope (void) error ("nested function %q+D declared but never defined", p); undef_nested_function = true; } - /* C99 6.7.4p6: "a function with external linkage... declared - with an inline function specifier ... shall also be defined in the - same translation unit." */ else if (DECL_DECLARED_INLINE_P (p) && TREE_PUBLIC (p) - && !DECL_INITIAL (p) - && !flag_gnu89_inline) - pedwarn (input_location, 0, "inline function %q+D declared but never defined", p); + && !DECL_INITIAL (p)) + { + /* C99 6.7.4p6: "a function with external linkage... declared + with an inline function specifier ... shall also be defined + in the same translation unit." */ + if (!flag_gnu89_inline) + pedwarn (input_location, 0, + "inline function %q+D declared but never defined", p); + DECL_EXTERNAL (p) = 1; + } goto common_symbol; @@ -820,6 +948,29 @@ pop_scope (void) TREE_CHAIN (p) = BLOCK_VARS (block); BLOCK_VARS (block) = p; } + else if (VAR_OR_FUNCTION_DECL_P (p)) + { + /* For block local externs add a special + DECL_EXTERNAL decl for debug info generation. */ + tree extp = copy_node (p); + + DECL_EXTERNAL (extp) = 1; + TREE_STATIC (extp) = 0; + TREE_PUBLIC (extp) = 1; + DECL_INITIAL (extp) = NULL_TREE; + DECL_LANG_SPECIFIC (extp) = NULL; + DECL_CONTEXT (extp) = current_function_decl; + if (TREE_CODE (p) == FUNCTION_DECL) + { + DECL_RESULT (extp) = NULL_TREE; + DECL_SAVED_TREE (extp) = NULL_TREE; + DECL_STRUCT_FUNCTION (extp) = NULL; + } + if (b->locus != UNKNOWN_LOCATION) + DECL_SOURCE_LOCATION (extp) = b->locus; + TREE_CHAIN (extp) = BLOCK_VARS (block); + BLOCK_VARS (block) = extp; + } /* If this is the file scope, and we are processing more than one translation unit in this compilation, set DECL_CONTEXT of each decl to the TRANSLATION_UNIT_DECL. @@ -901,7 +1052,7 @@ push_file_scope (void) for (decl = visible_builtins; decl; decl = TREE_CHAIN (decl)) bind (DECL_NAME (decl), decl, file_scope, - /*invisible=*/false, /*nested=*/true); + /*invisible=*/false, /*nested=*/true, DECL_SOURCE_LOCATION (decl)); } void @@ -917,6 +1068,8 @@ pop_file_scope (void) still works without it. */ finish_fname_decls (); + check_inline_statics (); + /* This is the point to write out a PCH if we're doing that. In that case we do not want to do anything else. */ if (pch_file) @@ -942,12 +1095,12 @@ pop_file_scope (void) In that case, the TYPE_SIZE will be zero. */ static void -pushtag (tree name, tree type) +pushtag (tree name, tree type, location_t loc) { /* Record the identifier as the type's name if it has none. */ if (name && !TYPE_NAME (type)) TYPE_NAME (type) = name; - bind (name, type, current_scope, /*invisible=*/false, /*nested=*/false); + bind (name, type, current_scope, /*invisible=*/false, /*nested=*/false, loc); /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the tagged type we just added to the current scope. This fake @@ -1775,17 +1928,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) throw it away, in case it was inlined into a function that hasn't been written out yet. */ if (new_is_definition && DECL_INITIAL (olddecl)) - { - if (TREE_USED (olddecl) - /* We never inline re-defined extern inline functions. - FIXME: This would be better handled by keeping both functions - as separate declarations. */ - && cgraph_function_possibly_inlined_p (olddecl)) - (*debug_hooks->outlining_inline_function) (olddecl); - - /* The new defn must not be inline. */ - DECL_UNINLINABLE (newdecl) = 1; - } + /* The new defn must not be inline. */ + DECL_UNINLINABLE (newdecl) = 1; else { /* If either decl says `inline', this fn is inline, unless @@ -1831,12 +1975,15 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) /* Also preserve various other info from the definition. */ if (!new_is_definition) { + tree t; DECL_RESULT (newdecl) = DECL_RESULT (olddecl); DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl); DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); gimple_set_body (newdecl, gimple_body (olddecl)); - DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); + DECL_ARGUMENTS (newdecl) = copy_list (DECL_ARGUMENTS (olddecl)); + for (t = DECL_ARGUMENTS (newdecl); t ; t = TREE_CHAIN (t)) + DECL_CONTEXT (t) = newdecl; /* See if we've got a function to instantiate from. */ if (DECL_SAVED_TREE (olddecl)) @@ -1858,6 +2005,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) { unsigned olddecl_uid = DECL_UID (olddecl); tree olddecl_context = DECL_CONTEXT (olddecl); + tree olddecl_arguments = NULL; + if (TREE_CODE (olddecl) == FUNCTION_DECL) + olddecl_arguments = DECL_ARGUMENTS (olddecl); memcpy ((char *) olddecl + sizeof (struct tree_common), (char *) newdecl + sizeof (struct tree_common), @@ -1888,6 +2038,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) } DECL_UID (olddecl) = olddecl_uid; DECL_CONTEXT (olddecl) = olddecl_context; + if (TREE_CODE (olddecl) == FUNCTION_DECL) + DECL_ARGUMENTS (olddecl) = olddecl_arguments; } /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl @@ -1980,67 +2132,6 @@ warn_if_shadowing (tree new_decl) } } - -/* Subroutine of pushdecl. - - X is a TYPE_DECL for a typedef statement. Create a brand new - ..._TYPE node (which will be just a variant of the existing - ..._TYPE node with identical properties) and then install X - as the TYPE_NAME of this brand new (duplicate) ..._TYPE node. - - The whole point here is to end up with a situation where each - and every ..._TYPE node the compiler creates will be uniquely - associated with AT MOST one node representing a typedef name. - This way, even though the compiler substitutes corresponding - ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very - early on, later parts of the compiler can always do the reverse - translation and get back the corresponding typedef name. For - example, given: - - typedef struct S MY_TYPE; - MY_TYPE object; - - Later parts of the compiler might only know that `object' was of - type `struct S' if it were not for code just below. With this - code however, later parts of the compiler see something like: - - struct S' == struct S - typedef struct S' MY_TYPE; - struct S' object; - - And they can then deduce (from the node for type struct S') that - the original object declaration was: - - MY_TYPE object; - - Being able to do this is important for proper support of protoize, - and also for generating precise symbolic debugging information - which takes full account of the programmer's (typedef) vocabulary. - - Obviously, we don't want to generate a duplicate ..._TYPE node if - the TYPE_DECL node that we are now processing really represents a - standard built-in type. */ - -static void -clone_underlying_type (tree x) -{ - if (DECL_IS_BUILTIN (x)) - { - if (TYPE_NAME (TREE_TYPE (x)) == 0) - TYPE_NAME (TREE_TYPE (x)) = x; - } - else if (TREE_TYPE (x) != error_mark_node - && DECL_ORIGINAL_TYPE (x) == NULL_TREE) - { - tree tt = TREE_TYPE (x); - DECL_ORIGINAL_TYPE (x) = tt; - tt = build_variant_type_copy (tt); - TYPE_NAME (tt) = x; - TREE_USED (tt) = TREE_USED (x); - TREE_TYPE (x) = tt; - } -} - /* Record a decl-node X as belonging to the current lexical scope. Check for errors (such as an incompatible declaration for the same name already seen in the same scope). @@ -2056,6 +2147,7 @@ pushdecl (tree x) struct c_scope *scope = current_scope; struct c_binding *b; bool nested = false; + location_t locus = DECL_SOURCE_LOCATION (x); /* Must set DECL_CONTEXT for everything not at file scope or DECL_FILE_SCOPE_P won't work. Local externs don't count @@ -2074,7 +2166,8 @@ pushdecl (tree x) /* Anonymous decls are just inserted in the scope. */ if (!name) { - bind (name, x, scope, /*invisible=*/false, /*nested=*/false); + bind (name, x, scope, /*invisible=*/false, /*nested=*/false, + locus); return x; } @@ -2234,7 +2327,8 @@ pushdecl (tree x) = build_type_attribute_variant (thistype, TYPE_ATTRIBUTES (b->type)); TREE_TYPE (b->decl) = thistype; - bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true); + bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true, + locus); return b->decl; } else if (TREE_PUBLIC (x)) @@ -2252,7 +2346,7 @@ pushdecl (tree x) else { bind (name, x, external_scope, /*invisible=*/true, - /*nested=*/false); + /*nested=*/false, locus); nested = true; } } @@ -2263,9 +2357,9 @@ pushdecl (tree x) skip_external_and_shadow_checks: if (TREE_CODE (x) == TYPE_DECL) - clone_underlying_type (x); + set_underlying_type (x); - bind (name, x, scope, /*invisible=*/false, nested); + bind (name, x, scope, /*invisible=*/false, nested, locus); /* If x's type is incomplete because it's based on a structure or union which has not yet been fully declared, @@ -2314,11 +2408,12 @@ pushdecl_top_level (tree x) if (TREE_PUBLIC (x)) { - bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false); + bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false, + UNKNOWN_LOCATION); nested = true; } if (file_scope) - bind (name, x, file_scope, /*invisible=*/false, nested); + bind (name, x, file_scope, /*invisible=*/false, nested, UNKNOWN_LOCATION); return x; } @@ -2373,7 +2468,8 @@ implicitly_declare (tree functionid) if (!DECL_BUILT_IN (decl) && DECL_IS_BUILTIN (decl)) { bind (functionid, decl, file_scope, - /*invisible=*/false, /*nested=*/true); + /*invisible=*/false, /*nested=*/true, + DECL_SOURCE_LOCATION (decl)); return decl; } else @@ -2414,7 +2510,8 @@ implicitly_declare (tree functionid) b->type = TREE_TYPE (decl); TREE_TYPE (decl) = newtype; bind (functionid, decl, current_scope, - /*invisible=*/false, /*nested=*/true); + /*invisible=*/false, /*nested=*/true, + DECL_SOURCE_LOCATION (decl)); return decl; } } @@ -2477,7 +2574,8 @@ undeclared_variable (tree id, location_t loc) will be nonnull but current_function_scope will be null. */ scope = current_function_scope ? current_function_scope : current_scope; } - bind (id, error_mark_node, scope, /*invisible=*/false, /*nested=*/false); + bind (id, error_mark_node, scope, /*invisible=*/false, /*nested=*/false, + UNKNOWN_LOCATION); } /* Subroutine of lookup_label, declare_label, define_label: construct a @@ -2531,7 +2629,7 @@ lookup_label (tree name) /* Ordinary labels go in the current function scope. */ bind (name, label, current_function_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); return label; } @@ -2561,7 +2659,7 @@ declare_label (tree name) /* Declared labels go in the current scope. */ bind (name, label, current_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); return label; } @@ -2608,7 +2706,7 @@ define_label (location_t location, tree name) /* Ordinary labels go in the current function scope. */ bind (name, label, current_function_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } if (!in_system_header && lookup_name (name)) @@ -2635,10 +2733,13 @@ define_label (location_t location, tree name) If THISLEVEL_ONLY is nonzero, searches only the current_scope. CODE says which kind of type the caller wants; it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE. + If PLOC is not NULL and this returns non-null, it sets *PLOC to the + location where the tag was defined. If the wrong kind of type is found, an error is reported. */ static tree -lookup_tag (enum tree_code code, tree name, int thislevel_only) +lookup_tag (enum tree_code code, tree name, int thislevel_only, + location_t *ploc) { struct c_binding *b = I_TAG_BINDING (name); int thislevel = 0; @@ -2675,6 +2776,10 @@ lookup_tag (enum tree_code code, tree name, int thislevel_only) if (thislevel) pending_xref_error (); } + + if (ploc != NULL) + *ploc = b->locus; + return b->decl; } @@ -2811,10 +2916,10 @@ c_make_fname_decl (tree id, int type_dep) { DECL_CONTEXT (decl) = current_function_decl; bind (id, decl, current_function_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } - finish_decl (decl, init, NULL_TREE); + finish_decl (decl, init, NULL_TREE, NULL_TREE); return decl; } @@ -2831,7 +2936,8 @@ c_builtin_function (tree decl) /* Should never be called on a symbol with a preexisting meaning. */ gcc_assert (!I_SYMBOL_BINDING (id)); - bind (id, decl, external_scope, /*invisible=*/true, /*nested=*/false); + bind (id, decl, external_scope, /*invisible=*/true, /*nested=*/false, + UNKNOWN_LOCATION); /* Builtins in the implementation namespace are made visible without needing to be explicitly declared. See push_file_scope. */ @@ -2856,7 +2962,8 @@ c_builtin_function_ext_scope (tree decl) /* Should never be called on a symbol with a preexisting meaning. */ gcc_assert (!I_SYMBOL_BINDING (id)); - bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false); + bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false, + UNKNOWN_LOCATION); /* Builtins in the implementation namespace are made visible without needing to be explicitly declared. See push_file_scope. */ @@ -2904,6 +3011,12 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) found_tag = true; + if (declspecs->restrict_p) + { + error ("invalid use of %"); + warned = 1; + } + if (name == 0) { if (warned != 1 && code != ENUMERAL_TYPE) @@ -2939,12 +3052,12 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) else { pending_invalid_xref = 0; - t = lookup_tag (code, name, 1); + t = lookup_tag (code, name, 1, NULL); if (t == 0) { t = make_node (code); - pushtag (name, t); + pushtag (name, t, input_location); } } } @@ -3133,10 +3246,15 @@ add_flexible_array_elts_to_size (tree decl, tree init) } } -/* Decode a "typename", such as "int **", returning a ..._TYPE node. */ +/* Decode a "typename", such as "int **", returning a ..._TYPE node. + Set *EXPR, if EXPR not NULL, to any expression to be evaluated + before the type name, and set *EXPR_CONST_OPERANDS, if + EXPR_CONST_OPERANDS not NULL, to indicate whether the type name may + appear in a constant expression. */ tree -groktypename (struct c_type_name *type_name) +groktypename (struct c_type_name *type_name, tree *expr, + bool *expr_const_operands) { tree type; tree attrs = type_name->specs->attrs; @@ -3144,7 +3262,8 @@ groktypename (struct c_type_name *type_name) type_name->specs->attrs = NULL_TREE; type = grokdeclarator (type_name->declarator, type_name->specs, TYPENAME, - false, NULL, &attrs, DEPRECATED_NORMAL); + false, NULL, &attrs, expr, expr_const_operands, + DEPRECATED_NORMAL); /* Apply attributes. */ decl_attributes (&type, attrs, 0); @@ -3173,6 +3292,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, { tree decl; tree tem; + tree expr = NULL_TREE; enum deprecated_states deprecated_state = DEPRECATED_NORMAL; /* An object declared as __attribute__((deprecated)) suppresses @@ -3181,11 +3301,14 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, deprecated_state = DEPRECATED_SUPPRESS; decl = grokdeclarator (declarator, declspecs, - NORMAL, initialized, NULL, &attributes, + NORMAL, initialized, NULL, &attributes, &expr, NULL, deprecated_state); if (!decl) return 0; + if (expr) + add_stmt (expr); + if (TREE_CODE (decl) != FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (decl))) warning (OPT_Wmain, "%q+D is usually a function", decl); @@ -3333,9 +3456,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, && !TREE_READONLY (decl) && DECL_DECLARED_INLINE_P (current_function_decl) && DECL_EXTERNAL (current_function_decl)) - pedwarn (input_location, 0, - "%q+D is static but declared in inline function %qD " - "which is not static", decl, current_function_decl); + record_inline_static (input_location, current_function_decl, + decl, csi_modifiable); /* Add this decl to the current scope. TEM may equal DECL or it may be a previous decl of the same name. */ @@ -3369,11 +3491,12 @@ c_maybe_initialize_eh (void) /* Finish processing of a declaration; install its initial value. + If ORIGTYPE is not NULL_TREE, it is the original type of INIT. If the length of an array type is not known before, it must be determined now, from the initial value, or it is an error. */ void -finish_decl (tree decl, tree init, tree asmspec_tree) +finish_decl (tree decl, tree init, tree origtype, tree asmspec_tree) { tree type; int was_incomplete = (DECL_SIZE (decl) == 0); @@ -3395,7 +3518,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) init = 0; if (init) - store_init_value (decl, init); + store_init_value (decl, init, origtype); if (c_dialect_objc () && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL @@ -3648,11 +3771,14 @@ finish_decl (tree decl, tree init, tree asmspec_tree) tree cleanup_id = TREE_VALUE (TREE_VALUE (attr)); tree cleanup_decl = lookup_name (cleanup_id); tree cleanup; + VEC(tree,gc) *vec; /* Build "cleanup(&decl)" for the destructor. */ - cleanup = build_unary_op (ADDR_EXPR, decl, 0); - cleanup = build_tree_list (NULL_TREE, cleanup); - cleanup = build_function_call (cleanup_decl, cleanup); + cleanup = build_unary_op (input_location, ADDR_EXPR, decl, 0); + vec = VEC_alloc (tree, gc, 1); + VEC_quick_push (tree, vec, cleanup); + cleanup = build_function_call_vec (cleanup_decl, vec, NULL); + VEC_free (tree, gc, vec); /* Don't warn about decl unused; the cleanup uses it. */ TREE_USED (decl) = 1; @@ -3673,7 +3799,7 @@ grokparm (const struct c_parm *parm) { tree attrs = parm->attrs; tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, - NULL, &attrs, DEPRECATED_NORMAL); + NULL, &attrs, NULL, NULL, DEPRECATED_NORMAL); decl_attributes (&decl, attrs, 0); @@ -3690,12 +3816,12 @@ push_parm_decl (const struct c_parm *parm) tree decl; decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL, - &attrs, DEPRECATED_NORMAL); + &attrs, NULL, NULL, DEPRECATED_NORMAL); decl_attributes (&decl, attrs, 0); decl = pushdecl (decl); - finish_decl (decl, NULL_TREE, NULL_TREE); + finish_decl (decl, NULL_TREE, NULL_TREE, NULL_TREE); } /* Mark all the parameter declarations to date as forward decls. @@ -3721,10 +3847,11 @@ mark_forward_parm_decls (void) /* Build a COMPOUND_LITERAL_EXPR. TYPE is the type given in the compound literal, which may be an incomplete array type completed by the initializer; INIT is a CONSTRUCTOR that initializes the compound - literal. */ + literal. NON_CONST is true if the initializers contain something + that cannot occur in a constant expression. */ tree -build_compound_literal (tree type, tree init) +build_compound_literal (tree type, tree init, bool non_const) { /* We do not use start_decl here because we have a type, not a declarator; and do not use finish_decl because the decl should be stored inside @@ -3744,7 +3871,7 @@ build_compound_literal (tree type, tree init) TREE_USED (decl) = 1; TREE_TYPE (decl) = type; TREE_READONLY (decl) = TYPE_READONLY (type); - store_init_value (decl, init); + store_init_value (decl, init, NULL_TREE); if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type)) { @@ -3777,8 +3904,25 @@ build_compound_literal (tree type, tree init) rest_of_decl_compilation (decl, 1, 0); } + if (non_const) + { + complit = build2 (C_MAYBE_CONST_EXPR, type, NULL, complit); + C_MAYBE_CONST_EXPR_NON_CONST (complit) = 1; + } + return complit; } + +/* Check the type of a compound literal. Here we just check that it + is valid for C++. */ + +void +check_compound_literal_type (struct c_type_name *type_name, location_t loc) +{ + if (warn_cxx_compat && type_name->specs->tag_defined_p) + warning_at (loc, OPT_Wc___compat, + "defining a type in a compound literal is invalid in C++"); +} /* Determine whether TYPE is a structure with a flexible array member, or a union containing such a structure (possibly recursively). */ @@ -3816,12 +3960,14 @@ flexible_array_type_p (tree type) /* Performs sanity checks on the TYPE and WIDTH of the bit-field NAME, replacing with appropriate values if they are invalid. */ static void -check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) +check_bitfield_type_and_width (tree *type, tree *width, tree orig_name) { tree type_mv; unsigned int max_width; unsigned HOST_WIDE_INT w; - const char *name = orig_name ? orig_name: _(""); + const char *name = (orig_name + ? identifier_to_locale (IDENTIFIER_POINTER (orig_name)) + : _("")); /* Detect and ignore out of range field width and process valid field widths. */ @@ -3878,8 +4024,8 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) { struct lang_type *lt = TYPE_LANG_SPECIFIC (*type); if (!lt - || w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type)) - || w < min_precision (lt->enum_max, TYPE_UNSIGNED (*type))) + || w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type)) + || w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type))) warning (0, "%qs is narrower than values of its type", name); } } @@ -3889,7 +4035,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) /* Print warning about variable length array if necessary. */ static void -warn_variable_length_array (const char *name, tree size) +warn_variable_length_array (tree name, tree size) { int const_size = TREE_CONSTANT (size); @@ -3898,7 +4044,8 @@ warn_variable_length_array (const char *name, tree size) if (const_size) { if (name) - pedwarn (input_location, OPT_Wvla, "ISO C90 forbids array %qs whose size " + pedwarn (input_location, OPT_Wvla, + "ISO C90 forbids array %qE whose size " "can%'t be evaluated", name); else @@ -3908,7 +4055,8 @@ warn_variable_length_array (const char *name, tree size) else { if (name) - pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array %qs", + pedwarn (input_location, OPT_Wvla, + "ISO C90 forbids variable length array %qE", name); else pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array"); @@ -3920,7 +4068,7 @@ warn_variable_length_array (const char *name, tree size) { if (name) warning (OPT_Wvla, - "the size of array %qs can" + "the size of array %qE can" "%'t be evaluated", name); else warning (OPT_Wvla, @@ -3930,7 +4078,7 @@ warn_variable_length_array (const char *name, tree size) { if (name) warning (OPT_Wvla, - "variable length array %qs is used", + "variable length array %qE is used", name); else warning (OPT_Wvla, @@ -3939,6 +4087,34 @@ warn_variable_length_array (const char *name, tree size) } } +/* Given a size SIZE that may not be a constant, return a SAVE_EXPR to + serve as the actual size-expression for a type or decl. This is + like variable_size in stor-layout.c, but we make global_bindings_p + return negative to avoid calls to that function from outside the + front end resulting in errors at file scope, then call this version + instead from front-end code. */ + +static tree +c_variable_size (tree size) +{ + tree save; + + if (TREE_CONSTANT (size)) + return size; + + size = save_expr (size); + + save = skip_simple_arithmetic (size); + + if (cfun && cfun->dont_save_pending_sizes_p) + return size; + + if (!global_bindings_p ()) + put_pending_size (save); + + return size; +} + /* Given declspecs and a declarator, determine the name and type of the object declared and construct a ..._DECL node for it. @@ -3963,6 +4139,11 @@ warn_variable_length_array (const char *name, tree size) DECL_ATTRS points to the list of attributes that should be added to this decl. Any nested attributes that belong on the decl itself will be added to this list. + If EXPR is not NULL, any expressions that need to be evaluated as + part of evaluating variably modified types will be stored in *EXPR. + If EXPR_CONST_OPERANDS is not NULL, *EXPR_CONST_OPERANDS will be + set to indicate whether operands in *EXPR can be used in constant + expressions. DEPRECATED_STATE is a deprecated_states value indicating whether deprecation warnings should be suppressed. @@ -3977,7 +4158,8 @@ static tree grokdeclarator (const struct c_declarator *declarator, struct c_declspecs *declspecs, enum decl_context decl_context, bool initialized, tree *width, - tree *decl_attrs, enum deprecated_states deprecated_state) + tree *decl_attrs, tree *expr, bool *expr_const_operands, + enum deprecated_states deprecated_state) { tree type = declspecs->type; bool threadp = declspecs->thread_p; @@ -3986,7 +4168,7 @@ grokdeclarator (const struct c_declarator *declarator, int restrictp; int volatilep; int type_quals = TYPE_UNQUALIFIED; - const char *name, *orig_name; + tree name = NULL_TREE; bool funcdef_flag = false; bool funcdef_syntax = false; int size_varies = 0; @@ -3999,15 +4181,24 @@ grokdeclarator (const struct c_declarator *declarator, bool bitfield = width != NULL; tree element_type; struct c_arg_info *arg_info = 0; + tree expr_dummy; + bool expr_const_operands_dummy; + + if (expr == NULL) + expr = &expr_dummy; + if (expr_const_operands == NULL) + expr_const_operands = &expr_const_operands_dummy; + + *expr = declspecs->expr; + *expr_const_operands = declspecs->expr_const_operands; if (decl_context == FUNCDEF) funcdef_flag = true, decl_context = NORMAL; /* Look inside a declarator for the name being declared - and get it as a string, for an error message. */ + and get it as an IDENTIFIER_NODE, for an error message. */ { const struct c_declarator *decl = declarator; - name = 0; while (decl) switch (decl->kind) @@ -4025,16 +4216,21 @@ grokdeclarator (const struct c_declarator *declarator, case cdk_id: if (decl->u.id) - name = IDENTIFIER_POINTER (decl->u.id); + name = decl->u.id; decl = 0; break; default: gcc_unreachable (); } - orig_name = name; if (name == 0) - name = "type name"; + { + gcc_assert (decl_context == PARM + || decl_context == TYPENAME + || (decl_context == FIELD + && declarator->kind == cdk_id)); + gcc_assert (!initialized); + } } /* A function definition's declarator must have the form of @@ -4050,13 +4246,16 @@ grokdeclarator (const struct c_declarator *declarator, decl_context = PARM; if (declspecs->deprecated_p && deprecated_state != DEPRECATED_SUPPRESS) - warn_deprecated_use (declspecs->type); + warn_deprecated_use (declspecs->type, declspecs->decl_attr); if ((decl_context == NORMAL || decl_context == FIELD) && current_scope == file_scope && variably_modified_type_p (type, NULL_TREE)) { - error ("variably modified %qs at file scope", name); + if (name) + error ("variably modified %qE at file scope", name); + else + error ("variably modified field at file scope"); type = integer_type_node; } @@ -4072,9 +4271,16 @@ grokdeclarator (const struct c_declarator *declarator, if ((warn_implicit_int || warn_return_type || flag_isoc99) && funcdef_flag) warn_about_return_type = 1; - else - pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, - "type defaults to % in declaration of %qs", name); + else + { + if (name) + pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, + "type defaults to % in declaration of %qE", + name); + else + pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, + "type defaults to % in type name"); + } } /* Adjust the type if a bit-field is being declared, @@ -4148,11 +4354,17 @@ grokdeclarator (const struct c_declarator *declarator, switch (decl_context) { case FIELD: - error ("storage class specified for structure field %qs", - name); + if (name) + error ("storage class specified for structure field %qE", + name); + else + error ("storage class specified for structure field"); break; case PARM: - error ("storage class specified for parameter %qs", name); + if (name) + error ("storage class specified for parameter %qE", name); + else + error ("storage class specified for unnamed parameter"); break; default: error ("storage class specified for typename"); @@ -4172,26 +4384,26 @@ grokdeclarator (const struct c_declarator *declarator, /* It is fine to have 'extern const' when compiling at C and C++ intersection. */ if (!(warn_cxx_compat && constp)) - warning (0, "%qs initialized and declared %", name); + warning (0, "%qE initialized and declared %", name); } else - error ("%qs has both % and initializer", name); + error ("%qE has both % and initializer", name); } else if (current_scope == file_scope) { if (storage_class == csc_auto) - error ("file-scope declaration of %qs specifies %", name); + error ("file-scope declaration of %qE specifies %", name); if (pedantic && storage_class == csc_register) pedwarn (input_location, OPT_pedantic, - "file-scope declaration of %qs specifies %", name); + "file-scope declaration of %qE specifies %", name); } else { if (storage_class == csc_extern && funcdef_flag) - error ("nested function %qs declared %", name); + error ("nested function %qE declared %", name); else if (threadp && storage_class == csc_none) { - error ("function-scope %qs implicitly auto and declared " + error ("function-scope %qE implicitly auto and declared " "%<__thread%>", name); threadp = false; @@ -4285,13 +4497,19 @@ grokdeclarator (const struct c_declarator *declarator, if (VOID_TYPE_P (type)) { - error ("declaration of %qs as array of voids", name); + if (name) + error ("declaration of %qE as array of voids", name); + else + error ("declaration of type name as array of voids"); type = error_mark_node; } if (TREE_CODE (type) == FUNCTION_TYPE) { - error ("declaration of %qs as array of functions", name); + if (name) + error ("declaration of %qE as array of functions", name); + else + error ("declaration of type name as array of functions"); type = error_mark_node; } @@ -4311,33 +4529,70 @@ grokdeclarator (const struct c_declarator *declarator, if (size) { + bool size_maybe_const = true; + bool size_int_const = (TREE_CODE (size) == INTEGER_CST + && !TREE_OVERFLOW (size)); + bool this_size_varies = false; + /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ STRIP_TYPE_NOPS (size); if (!INTEGRAL_TYPE_P (TREE_TYPE (size))) { - error ("size of array %qs has non-integer type", name); + if (name) + error ("size of array %qE has non-integer type", name); + else + error ("size of unnamed array has non-integer type"); size = integer_one_node; } - if (pedantic && integer_zerop (size)) - pedwarn (input_location, OPT_pedantic, - "ISO C forbids zero-size array %qs", name); + size = c_fully_fold (size, false, &size_maybe_const); + + if (pedantic && size_maybe_const && integer_zerop (size)) + { + if (name) + pedwarn (input_location, OPT_pedantic, + "ISO C forbids zero-size array %qE", name); + else + pedwarn (input_location, OPT_pedantic, + "ISO C forbids zero-size array"); + } - if (TREE_CODE (size) == INTEGER_CST) + if (TREE_CODE (size) == INTEGER_CST && size_maybe_const) { constant_expression_warning (size); if (tree_int_cst_sgn (size) < 0) { - error ("size of array %qs is negative", name); + if (name) + error ("size of array %qE is negative", name); + else + error ("size of unnamed array is negative"); size = integer_one_node; } + /* Handle a size folded to an integer constant but + not an integer constant expression. */ + if (!size_int_const) + { + /* If this is a file scope declaration of an + ordinary identifier, this is invalid code; + diagnosing it here and not subsequently + treating the type as variable-length avoids + more confusing diagnostics later. */ + if ((decl_context == NORMAL || decl_context == FIELD) + && current_scope == file_scope) + pedwarn (input_location, 0, + "variably modified %qE at file scope", + name); + else + this_size_varies = size_varies = 1; + warn_variable_length_array (name, size); + } } else if ((decl_context == NORMAL || decl_context == FIELD) && current_scope == file_scope) { - error ("variably modified %qs at file scope", name); + error ("variably modified %qE at file scope", name); size = integer_one_node; } else @@ -4345,11 +4600,11 @@ grokdeclarator (const struct c_declarator *declarator, /* Make sure the array size remains visibly nonconstant even if it is (eg) a const variable with known value. */ - size_varies = 1; - warn_variable_length_array (orig_name, size); + this_size_varies = size_varies = 1; + warn_variable_length_array (name, size); } - if (integer_zerop (size)) + if (integer_zerop (size) && !this_size_varies) { /* A zero-length array cannot be represented with an unsigned index type, which is what we'll @@ -4363,7 +4618,10 @@ grokdeclarator (const struct c_declarator *declarator, MINUS_EXPR, which allows the -1 to get folded with the +1 that happens when building TYPE_SIZE. */ if (size_varies) - size = variable_size (size); + size = c_variable_size (size); + if (this_size_varies && TREE_CODE (size) == INTEGER_CST) + size = build2 (COMPOUND_EXPR, TREE_TYPE (size), + integer_zero_node, size); /* Compute the maximum valid index, that is, size - 1. Do the calculation in index_type, so that @@ -4384,34 +4642,58 @@ grokdeclarator (const struct c_declarator *declarator, if (TREE_CODE (itype) == INTEGER_CST && TREE_OVERFLOW (itype)) { - error ("size of array %qs is too large", name); + if (name) + error ("size of array %qE is too large", name); + else + error ("size of unnamed array is too large"); type = error_mark_node; continue; } itype = build_index_type (itype); } + if (this_size_varies) + { + if (*expr) + *expr = build2 (COMPOUND_EXPR, TREE_TYPE (size), + *expr, size); + else + *expr = size; + *expr_const_operands &= size_maybe_const; + } } else if (decl_context == FIELD) { - if (pedantic && !flag_isoc99 && !in_system_header) + bool flexible_array_member = false; + if (array_parm_vla_unspec_p) + /* Field names can in fact have function prototype + scope so [*] is disallowed here through making + the field variably modified, not through being + something other than a declaration with function + prototype scope. */ + size_varies = 1; + else + { + const struct c_declarator *t = declarator; + while (t->kind == cdk_attrs) + t = t->declarator; + flexible_array_member = (t->kind == cdk_id); + } + if (flexible_array_member + && pedantic && !flag_isoc99 && !in_system_header) pedwarn (input_location, OPT_pedantic, "ISO C90 does not support flexible array members"); /* ISO C99 Flexible array members are effectively identical to GCC's zero-length array extension. */ - itype = build_range_type (sizetype, size_zero_node, NULL_TREE); + if (flexible_array_member || array_parm_vla_unspec_p) + itype = build_range_type (sizetype, size_zero_node, + NULL_TREE); } else if (decl_context == PARM) { if (array_parm_vla_unspec_p) { - if (! orig_name) - { - /* C99 6.7.5.2p4 */ - error ("%<[*]%> not allowed in other than a declaration"); - } - itype = build_range_type (sizetype, size_zero_node, NULL_TREE); size_varies = 1; } @@ -4420,12 +4702,14 @@ grokdeclarator (const struct c_declarator *declarator, { if (array_parm_vla_unspec_p) { - /* The error is printed elsewhere. We use this to - avoid messing up with incomplete array types of - the same type, that would otherwise be modified - below. */ + /* C99 6.7.5.2p4 */ + warning (0, "%<[*]%> not in a declaration"); + /* We use this to avoid messing up with incomplete + array types of the same type, that would + otherwise be modified below. */ itype = build_range_type (sizetype, size_zero_node, NULL_TREE); + size_varies = 1; } } @@ -4514,12 +4798,20 @@ grokdeclarator (const struct c_declarator *declarator, /* Warn about some types functions can't return. */ if (TREE_CODE (type) == FUNCTION_TYPE) { - error ("%qs declared as function returning a function", name); + if (name) + error ("%qE declared as function returning a function", + name); + else + error ("type name declared as function " + "returning a function"); type = integer_type_node; } if (TREE_CODE (type) == ARRAY_TYPE) { - error ("%qs declared as function returning an array", name); + if (name) + error ("%qE declared as function returning an array", name); + else + error ("type name declared as function returning an array"); type = integer_type_node; } @@ -4610,7 +4902,7 @@ grokdeclarator (const struct c_declarator *declarator, tree decl = build_decl (TYPE_DECL, NULL_TREE, type); DECL_ARTIFICIAL (decl) = 1; pushdecl (decl); - finish_decl (decl, NULL_TREE, NULL_TREE); + finish_decl (decl, NULL_TREE, NULL_TREE, NULL_TREE); TYPE_NAME (type) = decl; } @@ -4634,7 +4926,7 @@ grokdeclarator (const struct c_declarator *declarator, /* Check the type and width of a bit-field. */ if (bitfield) - check_bitfield_type_and_width (&type, width, orig_name); + check_bitfield_type_and_width (&type, width, name); /* Did array size calculations overflow? */ @@ -4643,7 +4935,10 @@ grokdeclarator (const struct c_declarator *declarator, && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST && TREE_OVERFLOW (TYPE_SIZE_UNIT (type))) { - error ("size of array %qs is too large", name); + if (name) + error ("size of array %qE is too large", name); + else + error ("size of unnamed array is too large"); /* If we proceed with the array type as it is, we'll eventually crash in tree_low_cst(). */ type = error_mark_node; @@ -4708,7 +5003,7 @@ grokdeclarator (const struct c_declarator *declarator, && !(storage_class == csc_static || storage_class == csc_register))))) { - error ("variable or field %qs declared void", name); + error ("variable or field %qE declared void", name); type = integer_type_node; } @@ -4786,13 +5081,16 @@ grokdeclarator (const struct c_declarator *declarator, if (TREE_CODE (type) == FUNCTION_TYPE) { - error ("field %qs declared as a function", name); + error ("field %qE declared as a function", name); type = build_pointer_type (type); } else if (TREE_CODE (type) != ERROR_MARK && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type)) { - error ("field %qs has incomplete type", name); + if (name) + error ("field %qE has incomplete type", name); + else + error ("unnamed field has incomplete type"); type = error_mark_node; } type = c_build_qualified_type (type, type_quals); @@ -4809,7 +5107,7 @@ grokdeclarator (const struct c_declarator *declarator, { if (storage_class == csc_register || threadp) { - error ("invalid storage class for function %qs", name); + error ("invalid storage class for function %qE", name); } else if (current_scope != file_scope) { @@ -4819,10 +5117,11 @@ grokdeclarator (const struct c_declarator *declarator, GCC allows 'auto', perhaps with 'inline', to support nested functions. */ if (storage_class == csc_auto) - pedwarn (input_location, OPT_pedantic, "invalid storage class for function %qs", name); + pedwarn (input_location, OPT_pedantic, + "invalid storage class for function %qE", name); else if (storage_class == csc_static) { - error ("invalid storage class for function %qs", name); + error ("invalid storage class for function %qE", name); if (funcdef_flag) storage_class = declspecs->storage_class = csc_none; else @@ -4944,11 +5243,17 @@ grokdeclarator (const struct c_declarator *declarator, DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); } - if (storage_class == csc_extern + if ((storage_class == csc_extern + || (storage_class == csc_none + && TREE_CODE (type) == FUNCTION_TYPE + && !funcdef_flag)) && variably_modified_type_p (type, NULL_TREE)) { /* C99 6.7.5.2p2 */ - error ("object with variably modified type must have no linkage"); + if (TREE_CODE (type) == FUNCTION_TYPE) + error ("non-nested function with variably modified type"); + else + error ("object with variably modified type must have no linkage"); } /* Record `register' declaration for warnings on & @@ -5276,13 +5581,19 @@ get_parm_info (bool ellipsis) Return a c_typespec structure for the type specifier. */ struct c_typespec -parser_xref_tag (enum tree_code code, tree name) +parser_xref_tag (enum tree_code code, tree name, location_t loc) { struct c_typespec ret; + tree ref; + location_t refloc; + + ret.expr = NULL_TREE; + ret.expr_const_operands = true; + /* If a cross reference is requested, look up the type already defined for this tag and return it. */ - tree ref = lookup_tag (code, name, 0); + ref = lookup_tag (code, name, 0, &refloc); /* If this is the right type of tag, return what we found. (This reference will be shadowed by shadow_tag later if appropriate.) If this is the wrong type of tag, do not return it. If it was the @@ -5297,6 +5608,35 @@ parser_xref_tag (enum tree_code code, tree name) ret.kind = (ref ? ctsk_tagref : ctsk_tagfirstref); if (ref && TREE_CODE (ref) == code) { + if (C_TYPE_DEFINED_IN_STRUCT (ref) + && loc != UNKNOWN_LOCATION + && warn_cxx_compat) + { + switch (code) + { + case ENUMERAL_TYPE: + warning_at (loc, OPT_Wc___compat, + ("enum type defined in struct or union " + "is not visible in C++")); + inform (refloc, "enum type defined here"); + break; + case RECORD_TYPE: + warning_at (loc, OPT_Wc___compat, + ("struct defined in struct or union " + "is not visible in C++")); + inform (refloc, "struct defined here"); + break; + case UNION_TYPE: + warning_at (loc, OPT_Wc___compat, + ("union defined in struct or union " + "is not visible in C++")); + inform (refloc, "union defined here"); + break; + default: + gcc_unreachable(); + } + } + ret.spec = ref; return ret; } @@ -5311,7 +5651,7 @@ parser_xref_tag (enum tree_code code, tree name) { /* Give the type a default layout like unsigned int to avoid crashing if it does not get defined. */ - TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); + SET_TYPE_MODE (ref, TYPE_MODE (unsigned_type_node)); TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); TYPE_USER_ALIGN (ref) = 0; TYPE_UNSIGNED (ref) = 1; @@ -5320,7 +5660,7 @@ parser_xref_tag (enum tree_code code, tree name) TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node); } - pushtag (name, ref); + pushtag (name, ref, loc); ret.spec = ref; return ret; @@ -5333,38 +5673,53 @@ parser_xref_tag (enum tree_code code, tree name) tree xref_tag (enum tree_code code, tree name) { - return parser_xref_tag (code, name).spec; + return parser_xref_tag (code, name, UNKNOWN_LOCATION).spec; } /* Make sure that the tag NAME is defined *in the current scope* at least as a forward reference. - CODE says which kind of tag NAME ought to be. */ + CODE says which kind of tag NAME ought to be. + + This stores the current value of the file static IN_STRUCT in + *ENCLOSING_IN_STRUCT, and sets IN_STRUCT to true. Similarly, this + sets STRUCT_TYPES in *ENCLOSING_STRUCT_TYPES, and sets STRUCT_TYPES + to an empty vector. The old values are restored in + finish_struct. */ tree -start_struct (enum tree_code code, tree name) +start_struct (enum tree_code code, tree name, bool *enclosing_in_struct, + VEC(tree,heap) **enclosing_struct_types, location_t loc) { /* If there is already a tag defined at this scope (as a forward reference), just return it. */ - tree ref = 0; + tree ref = NULL_TREE; + location_t refloc = UNKNOWN_LOCATION; - if (name != 0) - ref = lookup_tag (code, name, 1); + if (name != NULL_TREE) + ref = lookup_tag (code, name, 1, &refloc); if (ref && TREE_CODE (ref) == code) { if (TYPE_SIZE (ref)) { if (code == UNION_TYPE) - error ("redefinition of %", name); + error_at (loc, "redefinition of %", name); else - error ("redefinition of %", name); + error_at (loc, "redefinition of %", name); + if (refloc != UNKNOWN_LOCATION) + inform (refloc, "originally defined here"); + /* Don't create structures using a name already in use. */ + ref = NULL_TREE; } else if (C_TYPE_BEING_DEFINED (ref)) { if (code == UNION_TYPE) - error ("nested redefinition of %", name); + error_at (loc, "nested redefinition of %", name); else - error ("nested redefinition of %", name); + error_at (loc, "nested redefinition of %", name); + /* Don't bother to report "originally defined here" for a + nested redefinition; the original definition should be + obvious. */ /* Don't create structures that contain themselves. */ ref = NULL_TREE; } @@ -5375,11 +5730,28 @@ start_struct (enum tree_code code, tree name) if (ref == NULL_TREE || TREE_CODE (ref) != code) { ref = make_node (code); - pushtag (name, ref); + pushtag (name, ref, loc); } C_TYPE_BEING_DEFINED (ref) = 1; TYPE_PACKED (ref) = flag_pack_struct; + + *enclosing_in_struct = in_struct; + *enclosing_struct_types = struct_types; + in_struct = true; + struct_types = VEC_alloc(tree, heap, 0); + + /* FIXME: This will issue a warning for a use of a type defined + within a statement expr used within sizeof, et. al. This is not + terribly serious as C++ doesn't permit statement exprs within + sizeof anyhow. */ + if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof)) + warning_at (loc, OPT_Wc___compat, + "defining type in %qs expression is invalid in C++", + (in_sizeof + ? "sizeof" + : (in_typeof ? "typeof" : "alignof"))); + return ref; } @@ -5449,10 +5821,10 @@ grokfield (location_t loc, } value = grokdeclarator (declarator, declspecs, FIELD, false, - width ? &width : NULL, decl_attrs, + width ? &width : NULL, decl_attrs, NULL, NULL, DEPRECATED_NORMAL); - finish_decl (value, NULL_TREE, NULL_TREE); + finish_decl (value, NULL_TREE, NULL_TREE, NULL_TREE); DECL_INITIAL (value) = width; return value; @@ -5517,14 +5889,22 @@ detect_field_duplicates (tree fieldlist) /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T. FIELDLIST is a chain of FIELD_DECL nodes for the fields. - ATTRIBUTES are attributes to be applied to the structure. */ + ATTRIBUTES are attributes to be applied to the structure. + + ENCLOSING_IN_STRUCT is the value of IN_STRUCT, and + ENCLOSING_STRUCT_TYPES is the value of STRUCT_TYPES, when the + struct was started. This sets the C_TYPE_DEFINED_IN_STRUCT flag + for any type defined in the current struct. */ tree -finish_struct (tree t, tree fieldlist, tree attributes) +finish_struct (tree t, tree fieldlist, tree attributes, + bool enclosing_in_struct, + VEC(tree,heap) *enclosing_struct_types) { tree x; bool toplevel = file_scope == current_scope; int saw_named_field; + unsigned int ix; /* If this type was previously laid out as a forward reference, make sure we lay it out again. */ @@ -5573,9 +5953,6 @@ finish_struct (tree t, tree fieldlist, tree attributes) DECL_CONTEXT (x) = t; - if (TYPE_PACKED (t) && TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT) - DECL_PACKED (x) = 1; - /* If any field is const, the structure type is pseudo-const. */ if (TREE_READONLY (x)) C_TYPE_FIELDS_READONLY (t) = 1; @@ -5607,6 +5984,11 @@ finish_struct (tree t, tree fieldlist, tree attributes) SET_DECL_C_BIT_FIELD (x); } + if (TYPE_PACKED (t) + && (DECL_BIT_FIELD (x) + || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)) + DECL_PACKED (x) = 1; + /* Detect flexible array member in an invalid context. */ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE @@ -5775,6 +6157,24 @@ finish_struct (tree t, tree fieldlist, tree attributes) if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE)) add_stmt (build_stmt (DECL_EXPR, build_decl (TYPE_DECL, NULL, t))); + /* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in + the current struct. We do this now at the end of the struct + because the flag is used to issue visibility warnings when using + -Wc++-compat, and we only want to issue those warnings if the + type is referenced outside of the struct declaration. */ + for (ix = 0; VEC_iterate (tree, struct_types, ix, x); ++ix) + C_TYPE_DEFINED_IN_STRUCT (x) = 1; + + VEC_free (tree, heap, struct_types); + + in_struct = enclosing_in_struct; + struct_types = enclosing_struct_types; + + /* If this struct is defined inside a struct, add it to + STRUCT_TYPES. */ + if (in_struct && !in_sizeof && !in_typeof && !in_alignof) + VEC_safe_push (tree, heap, struct_types, t); + return t; } @@ -5795,32 +6195,35 @@ layout_array_type (tree t) may be used to declare the individual values as they are read. */ tree -start_enum (struct c_enum_contents *the_enum, tree name) +start_enum (struct c_enum_contents *the_enum, tree name, location_t loc) { - tree enumtype = 0; + tree enumtype = NULL_TREE; + location_t enumloc = UNKNOWN_LOCATION; /* If this is the real definition for a previous forward reference, fill in the contents in the same object that used to be the forward reference. */ - if (name != 0) - enumtype = lookup_tag (ENUMERAL_TYPE, name, 1); + if (name != NULL_TREE) + enumtype = lookup_tag (ENUMERAL_TYPE, name, 1, &enumloc); if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE) { enumtype = make_node (ENUMERAL_TYPE); - pushtag (name, enumtype); + pushtag (name, enumtype, loc); } if (C_TYPE_BEING_DEFINED (enumtype)) - error ("nested redefinition of %", name); + error_at (loc, "nested redefinition of %", name); C_TYPE_BEING_DEFINED (enumtype) = 1; if (TYPE_VALUES (enumtype) != 0) { /* This enum is a named one that has been declared already. */ - error ("redeclaration of %", name); + error_at (loc, "redeclaration of %", name); + if (enumloc != UNKNOWN_LOCATION) + inform (enumloc, "originally defined here"); /* Completely replace its old definition. The old enumerators remain defined, however. */ @@ -5833,6 +6236,16 @@ start_enum (struct c_enum_contents *the_enum, tree name) if (flag_short_enums) TYPE_PACKED (enumtype) = 1; + /* FIXME: This will issue a warning for a use of a type defined + within sizeof in a statement expr. This is not terribly serious + as C++ doesn't permit statement exprs within sizeof anyhow. */ + if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof)) + warning_at (loc, OPT_Wc___compat, + "defining type in %qs expression is invalid in C++", + (in_sizeof + ? "sizeof" + : (in_typeof ? "typeof" : "alignof"))); + return enumtype; } @@ -5875,8 +6288,8 @@ finish_enum (tree enumtype, tree values, tree attributes) that normally we only go as narrow as int - and signed iff any of the values are negative. */ unsign = (tree_int_cst_sgn (minnode) >= 0); - precision = MAX (min_precision (minnode, unsign), - min_precision (maxnode, unsign)); + precision = MAX (tree_int_cst_min_precision (minnode, unsign), + tree_int_cst_min_precision (maxnode, unsign)); if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node)) { @@ -5926,17 +6339,15 @@ finish_enum (tree enumtype, tree values, tree attributes) /* The ISO C Standard mandates enumerators to have type int, even though the underlying type of an enum type is unspecified. However, GCC allows enumerators of any - integer type as an extensions. Here we convert any - enumerators that fit in an int to type int, to avoid - promotions to unsigned types when comparing integers with - enumerators that fit in the int range. When -pedantic is - given, build_enumerator() would have already warned about - those that don't fit. */ - if (int_fits_type_p (ini, integer_type_node)) - tem = integer_type_node; - else - tem = enumtype; - ini = convert (tem, ini); + integer type as an extensions. build_enumerator() + converts any enumerators that fit in an int to type int, + to avoid promotions to unsigned types when comparing + integers with enumerators that fit in the int range. + When -pedantic is given, build_enumerator() would have + already warned about those that don't fit. Here we + convert the rest to the enumerator type. */ + if (TREE_TYPE (ini) != integer_type_node) + ini = convert (enumtype, ini); DECL_INITIAL (enu) = ini; TREE_PURPOSE (pair) = DECL_NAME (enu); @@ -5963,7 +6374,7 @@ finish_enum (tree enumtype, tree values, tree attributes) TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); TYPE_SIZE (tem) = TYPE_SIZE (enumtype); TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype); - TYPE_MODE (tem) = TYPE_MODE (enumtype); + SET_TYPE_MODE (tem, TYPE_MODE (enumtype)); TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype); @@ -5974,6 +6385,11 @@ finish_enum (tree enumtype, tree values, tree attributes) /* Finish debugging output for this type. */ rest_of_type_compilation (enumtype, toplevel); + /* If this enum is defined inside a struct, add it to + STRUCT_TYPES. */ + if (in_struct && !in_sizeof && !in_typeof && !in_alignof) + VEC_safe_push (tree, heap, struct_types, enumtype); + return enumtype; } @@ -5996,16 +6412,32 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value, undeclared identifier) - just ignore the value expression. */ if (value == error_mark_node) value = 0; - else if (!INTEGRAL_TYPE_P (TREE_TYPE (value)) - || TREE_CODE (value) != INTEGER_CST) + else if (!INTEGRAL_TYPE_P (TREE_TYPE (value))) { error ("enumerator value for %qE is not an integer constant", name); value = 0; } else { - value = default_conversion (value); - constant_expression_warning (value); + if (TREE_CODE (value) != INTEGER_CST) + { + value = c_fully_fold (value, false, NULL); + if (TREE_CODE (value) == INTEGER_CST) + pedwarn (value_loc, OPT_pedantic, + "enumerator value for %qE is not an integer " + "constant expression", name); + } + if (TREE_CODE (value) != INTEGER_CST) + { + error ("enumerator value for %qE is not an integer constant", + name); + value = 0; + } + else + { + value = default_conversion (value); + constant_expression_warning (value); + } } } @@ -6026,9 +6458,23 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value, pedwarn (value_loc, OPT_pedantic, "ISO C restricts enumerator values to range of %"); + /* The ISO C Standard mandates enumerators to have type int, even + though the underlying type of an enum type is unspecified. + However, GCC allows enumerators of any integer type as an + extensions. Here we convert any enumerators that fit in an int + to type int, to avoid promotions to unsigned types when comparing + integers with enumerators that fit in the int range. When + -pedantic is given, we would have already warned about those that + don't fit. We have to do this here rather than in finish_enum + because this value may be used to define more enumerators. */ + if (int_fits_type_p (value, integer_type_node)) + value = convert (integer_type_node, value); + /* Set basis for default for next value. */ - the_enum->enum_next_value = build_binary_op (PLUS_EXPR, value, - integer_one_node, 0); + the_enum->enum_next_value + = build_binary_op + (EXPR_HAS_LOCATION (value) ? EXPR_LOCATION (value) : input_location, + PLUS_EXPR, value, integer_one_node, 0); the_enum->enum_overflow = tree_int_cst_lt (the_enum->enum_next_value, value); /* Now create a declaration for the enum value name. */ @@ -6094,7 +6540,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, c_break_label = c_cont_label = size_zero_node; decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL, - &attributes, DEPRECATED_NORMAL); + &attributes, NULL, NULL, DEPRECATED_NORMAL); /* If the declarator is not suitable for a function definition, cause a syntax error. */ @@ -6323,7 +6769,8 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info) if (DECL_NAME (decl)) { bind (DECL_NAME (decl), decl, current_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, + UNKNOWN_LOCATION); if (!TREE_USED (decl)) warn_if_shadowing (decl); } @@ -6340,14 +6787,14 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info) DECL_CONTEXT (decl) = current_function_decl; if (DECL_NAME (decl)) bind (DECL_NAME (decl), decl, current_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } /* And all the tag declarations. */ for (decl = arg_info->tags; decl; decl = TREE_CHAIN (decl)) if (TREE_PURPOSE (decl)) bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } /* Subroutine of store_parm_decls which handles old-style function @@ -6724,7 +7171,7 @@ finish_function (void) && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) == integer_type_node && flag_isoc99) { - tree stmt = c_finish_return (integer_zero_node); + tree stmt = c_finish_return (integer_zero_node, NULL_TREE); /* Hack. We don't want the middle-end to warn that this return is unreachable, so we mark its location as special. Using UNKNOWN_LOCATION has the problem that it gets clobbered in @@ -7107,10 +7554,12 @@ build_null_declspecs (void) { struct c_declspecs *ret = XOBNEW (&parser_obstack, struct c_declspecs); ret->type = 0; + ret->expr = 0; ret->decl_attr = 0; ret->attrs = 0; ret->typespec_word = cts_none; ret->storage_class = csc_none; + ret->expr_const_operands = true; ret->declspecs_seen_p = false; ret->type_seen_p = false; ret->non_sc_seen_p = false; @@ -7213,8 +7662,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) "declaration specifiers"); break; } - if (pedantic && !flag_isoc99 && !in_system_header) - pedwarn (input_location, OPT_Wlong_long, "ISO C90 does not support %"); + pedwarn_c90 (input_location, OPT_Wlong_long, + "ISO C90 does not support %"); specs->long_long_p = 1; break; } @@ -7632,7 +8081,18 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) if (spec.kind == ctsk_tagdef || spec.kind == ctsk_tagfirstref) specs->tag_defined_p = true; if (spec.kind == ctsk_typeof) - specs->typedef_p = true; + { + specs->typedef_p = true; + if (spec.expr) + { + if (specs->expr) + specs->expr = build2 (COMPOUND_EXPR, TREE_TYPE (spec.expr), + specs->expr, spec.expr); + else + specs->expr = spec.expr; + specs->expr_const_operands &= spec.expr_const_operands; + } + } specs->type = type; } @@ -7763,6 +8223,8 @@ finish_declspecs (struct c_declspecs *specs) if (specs->saturating_p) { error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>"); + if (!targetm.fixed_point_supported_p ()) + error ("fixed-point types not supported for this target"); specs->typespec_word = cts_fract; } else if (specs->long_p || specs->short_p @@ -7885,8 +8347,10 @@ finish_declspecs (struct c_declspecs *specs) specs->type = dfloat128_type_node; break; case cts_fract: - gcc_assert (!specs->complex_p); - if (specs->saturating_p) + gcc_assert (!specs->complex_p); + if (!targetm.fixed_point_supported_p ()) + specs->type = integer_type_node; + else if (specs->saturating_p) { if (specs->long_long_p) specs->type = specs->unsigned_p @@ -7904,7 +8368,7 @@ finish_declspecs (struct c_declspecs *specs) specs->type = specs->unsigned_p ? sat_unsigned_fract_type_node : sat_fract_type_node; - } + } else { if (specs->long_long_p) @@ -7923,11 +8387,13 @@ finish_declspecs (struct c_declspecs *specs) specs->type = specs->unsigned_p ? unsigned_fract_type_node : fract_type_node; - } + } break; case cts_accum: - gcc_assert (!specs->complex_p); - if (specs->saturating_p) + gcc_assert (!specs->complex_p); + if (!targetm.fixed_point_supported_p ()) + specs->type = integer_type_node; + else if (specs->saturating_p) { if (specs->long_long_p) specs->type = specs->unsigned_p @@ -7945,7 +8411,7 @@ finish_declspecs (struct c_declspecs *specs) specs->type = specs->unsigned_p ? sat_unsigned_accum_type_node : sat_accum_type_node; - } + } else { if (specs->long_long_p) @@ -7964,7 +8430,7 @@ finish_declspecs (struct c_declspecs *specs) specs->type = specs->unsigned_p ? unsigned_accum_type_node : accum_type_node; - } + } break; default: gcc_unreachable (); @@ -8040,7 +8506,7 @@ c_write_global_declarations (void) /* Don't waste time on further processing if -fsyntax-only or we've encountered errors. */ - if (flag_syntax_only || errorcount || sorrycount || cpp_errors (parse_in)) + if (flag_syntax_only || errorcount || sorrycount) return; /* Close the external scope. */