X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-decl.c;h=eececb18d39b5b7c19ef8735756df051ee1a7372;hb=b2eafcc8ff6d32d29cd7d207a0231ed31b01b873;hp=c8516c7501b3e1df044d2de705e4873699ef9f19;hpb=3eafcdb5bf402c162e8b5f18a77a8afebfcc20a0;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-decl.c b/gcc/c-decl.c index c8516c7501b..eececb18d39 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -16,8 +16,8 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ /* Process declarations and symbol lookup for C front end. Also constructs types; the standard scalar types at initialization, @@ -418,6 +418,31 @@ static tree grokdeclarator (const struct c_declarator *, static tree grokparms (struct c_arg_info *, bool); static void layout_array_type (tree); +/* T is a statement. Add it to the statement-tree. This is the + C/ObjC version--C++ has a slightly different version of this + function. */ + +tree +add_stmt (tree t) +{ + enum tree_code code = TREE_CODE (t); + + if (EXPR_P (t) && code != LABEL_EXPR) + { + if (!EXPR_HAS_LOCATION (t)) + SET_EXPR_LOCATION (t, input_location); + } + + if (code == LABEL_EXPR || code == CASE_LABEL_EXPR) + STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1; + + /* Add T to the statement-tree. Non-side-effect statements need to be + recorded during statement expressions. */ + append_to_statement_list_force (t, &cur_stmt_list); + + return t; +} + /* States indicating how grokdeclarator() should handle declspecs marked with __attribute__((deprecated)). An object declared as __attribute__((deprecated)) suppresses warnings of uses of other @@ -566,15 +591,7 @@ objc_mark_locals_volatile (void *enclosing_blk) scope = scope->outer) { for (b = scope->bindings; b; b = b->prev) - { - if (TREE_CODE (b->decl) == VAR_DECL - || TREE_CODE (b->decl) == PARM_DECL) - { - C_DECL_REGISTER (b->decl) = 0; - DECL_REGISTER (b->decl) = 0; - TREE_THIS_VOLATILE (b->decl) = 1; - } - } + objc_volatilize_decl (b->decl); /* Do not climb up past the current function. */ if (scope->function_body) @@ -784,14 +801,13 @@ pop_scope (void) case VAR_DECL: /* Warnings for unused variables. */ - if (warn_unused_variable - && !TREE_USED (p) + if (!TREE_USED (p) && !DECL_IN_SYSTEM_HEADER (p) && DECL_NAME (p) && !DECL_ARTIFICIAL (p) && scope != file_scope && scope != external_scope) - warning (0, "%Junused variable %qD", p, p); + warning (OPT_Wunused_variable, "%Junused variable %qD", p, p); if (b->inner_comp) { @@ -1109,16 +1125,16 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype) first in a pair of mismatched declarations, using the diagnostic function DIAG. */ static void -locate_old_decl (tree decl, void (*diag)(const char *, ...)) +locate_old_decl (tree decl, void (*diag)(const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2)) { if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl)) ; else if (DECL_INITIAL (decl)) - diag (N_("%Jprevious definition of %qD was here"), decl, decl); + diag (G_("%Jprevious definition of %qD was here"), decl, decl); else if (C_DECL_IMPLICIT (decl)) - diag (N_("%Jprevious implicit declaration of %qD was here"), decl, decl); + diag (G_("%Jprevious implicit declaration of %qD was here"), decl, decl); else - diag (N_("%Jprevious declaration of %qD was here"), decl, decl); + diag (G_("%Jprevious declaration of %qD was here"), decl, decl); } /* Subroutine of duplicate_decls. Compare NEWDECL to OLDDECL. @@ -1162,9 +1178,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, else if (TREE_PUBLIC (newdecl)) warning (0, "%Jbuilt-in function %qD declared as non-function", newdecl, newdecl); - else if (warn_shadow) - warning (0, "%Jdeclaration of %qD shadows a built-in function", - newdecl, newdecl); + else + warning (OPT_Wshadow, "%Jdeclaration of %qD shadows " + "a built-in function", newdecl, newdecl); return false; } @@ -1278,9 +1294,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, || (DECL_INITIAL (newdecl) && !TYPE_ARG_TYPES (TREE_TYPE (newdecl))))) { - if (warn_shadow) - warning (0, "%Jdeclaration of %qD shadows a built-in function", - newdecl, newdecl); + warning (OPT_Wshadow, "%Jdeclaration of %qD shadows " + "a built-in function", newdecl, newdecl); /* Discard the old built-in function. */ return false; } @@ -1376,8 +1391,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } else if (warn_traditional) { - warning (0, "%Jnon-static declaration of %qD follows " - "static declaration", newdecl, newdecl); + warning (OPT_Wtraditional, "%Jnon-static declaration of %qD " + "follows static declaration", newdecl, newdecl); warned = true; } } @@ -1429,8 +1444,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } else if (warn_traditional) { - warning (0, "%Jnon-static declaration of %qD follows " - "static declaration", newdecl, newdecl); + warning (OPT_Wtraditional, "%Jnon-static declaration of %qD " + "follows static declaration", newdecl, newdecl); warned = true; } } @@ -1489,15 +1504,15 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (DECL_DECLARED_INLINE_P (newdecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) { - warning (0, "%Jinline declaration of %qD follows " + warning (OPT_Wattributes, "%Jinline declaration of %qD follows " "declaration with attribute noinline", newdecl, newdecl); warned = true; } else if (DECL_DECLARED_INLINE_P (olddecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) { - warning (0, "%Jdeclaration of %qD with attribute noinline follows " - "inline declaration ", newdecl, newdecl); + warning (OPT_Wattributes, "%Jdeclaration of %qD with attribute " + "noinline follows inline declaration ", newdecl, newdecl); warned = true; } @@ -1561,7 +1576,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && !(TREE_CODE (newdecl) == PARM_DECL && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))) { - warning (0, "%Jredundant redeclaration of %qD", newdecl, newdecl); + warning (OPT_Wredundant_decls, "%Jredundant redeclaration of %qD", + newdecl, newdecl); warned = true; } @@ -2029,11 +2045,52 @@ pushdecl (tree x) b = I_SYMBOL_BINDING (name); if (b && B_IN_SCOPE (b, scope)) { + struct c_binding *b_ext, *b_use; + tree type = TREE_TYPE (x); + tree visdecl = b->decl; + tree vistype = TREE_TYPE (visdecl); if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE && COMPLETE_TYPE_P (TREE_TYPE (x))) b->inner_comp = false; - if (duplicate_decls (x, b->decl)) - return b->decl; + b_use = b; + b_ext = b; + /* If this is an external linkage declaration, we should check + for compatibility with the type in the external scope before + setting the type at this scope based on the visible + information only. */ + if (TREE_PUBLIC (x) && TREE_PUBLIC (visdecl)) + { + while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext)) + b_ext = b_ext->shadowed; + if (b_ext) + { + b_use = b_ext; + if (b_use->type) + TREE_TYPE (b_use->decl) = b_use->type; + } + } + if (duplicate_decls (x, b_use->decl)) + { + if (b_use != b) + { + /* Save the updated type in the external scope and + restore the proper type for this scope. */ + tree thistype; + if (comptypes (vistype, type)) + thistype = composite_type (vistype, type); + else + thistype = TREE_TYPE (b_use->decl); + b_use->type = TREE_TYPE (b_use->decl); + if (TREE_CODE (b_use->decl) == FUNCTION_DECL + && DECL_BUILT_IN (b_use->decl)) + thistype + = build_type_attribute_variant (thistype, + TYPE_ATTRIBUTES + (b_use->type)); + TREE_TYPE (b_use->decl) = thistype; + } + return b_use->decl; + } else goto skip_external_and_shadow_checks; } @@ -2064,10 +2121,9 @@ pushdecl (tree x) visdecl = b->decl; vistype = TREE_TYPE (visdecl); } - if (warn_nested_externs - && scope != file_scope + if (scope != file_scope && !DECL_IN_SYSTEM_HEADER (x)) - warning (0, "nested extern declaration of %qD", x); + warning (OPT_Wnested_externs, "nested extern declaration of %qD", x); while (b && !B_IN_EXTERNAL_SCOPE (b)) { @@ -2120,7 +2176,15 @@ pushdecl (tree x) && duplicate_decls (x, b->decl)) { tree thistype; - thistype = (vistype ? composite_type (vistype, type) : type); + if (vistype) + { + if (comptypes (vistype, type)) + thistype = composite_type (vistype, type); + else + thistype = TREE_TYPE (b->decl); + } + else + thistype = type; b->type = TREE_TYPE (b->decl); if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl)) thistype @@ -2218,7 +2282,7 @@ pushdecl_top_level (tree x) static void implicit_decl_warning (tree id, tree olddecl) { - void (*diag) (const char *, ...); + void (*diag) (const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2); switch (mesg_implicit_function_declaration) { case 0: return; @@ -2227,7 +2291,7 @@ implicit_decl_warning (tree id, tree olddecl) default: gcc_unreachable (); } - diag (N_("implicit declaration of function %qE"), id); + diag (G_("implicit declaration of function %qE"), id); if (olddecl) locate_old_decl (olddecl, diag); } @@ -2502,9 +2566,9 @@ define_label (location_t location, tree name) /*invisible=*/false, /*nested=*/false); } - if (warn_traditional && !in_system_header && lookup_name (name)) - warning (0, "%Htraditional C lacks a separate namespace for labels, " - "identifier %qE conflicts", &location, name); + if (!in_system_header && lookup_name (name)) + warning (OPT_Wtraditional, "%Htraditional C lacks a separate namespace " + "for labels, identifier %qE conflicts", &location, name); nlist_se = XOBNEW (&parser_obstack, struct c_label_list); nlist_se->next = label_context_stack_se->labels_def; @@ -3037,7 +3101,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (decl))) - warning (0, "%J%qD is usually a function", decl, decl); + warning (OPT_Wmain, "%J%qD is usually a function", decl, decl); if (initialized) /* Is it valid for this decl to have an initializer at all? @@ -3158,7 +3222,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, && DECL_DECLARED_INLINE_P (decl) && DECL_UNINLINABLE (decl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl))) - warning (0, "%Jinline function %qD given attribute noinline", decl, decl); + warning (OPT_Wattributes, "%Jinline function %qD given attribute noinline", + decl, decl); /* Add this decl to the current scope. TEM may equal DECL or it may be a previous decl of the same name. */ @@ -3226,11 +3291,13 @@ finish_decl (tree decl, tree init, tree asmspec_tree) /* Get the completed type made by complete_array_type. */ type = TREE_TYPE (decl); - if (failure == 1) - error ("%Jinitializer fails to determine size of %qD", decl, decl); - - else if (failure == 2) + switch (failure) { + case 1: + error ("%Jinitializer fails to determine size of %qD", decl, decl); + break; + + case 2: if (do_default) error ("%Jarray size missing in %qD", decl, decl); /* If a `static' var's size isn't known, @@ -3241,9 +3308,33 @@ finish_decl (tree decl, tree init, tree asmspec_tree) and it will get allocated. */ else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl)) DECL_EXTERNAL (decl) = 1; + break; + + case 3: + error ("%Jzero or negative size array %qD", decl, decl); + break; + + case 0: + /* For global variables, update the copy of the type that + exists in the binding. */ + if (TREE_PUBLIC (decl)) + { + struct c_binding *b_ext = I_SYMBOL_BINDING (DECL_NAME (decl)); + while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext)) + b_ext = b_ext->shadowed; + if (b_ext) + { + if (b_ext->type) + b_ext->type = composite_type (b_ext->type, type); + else + b_ext->type = type; + } + } + break; + + default: + gcc_unreachable (); } - else if (failure == 3) - error ("%Jzero or negative size array %qD", decl, decl); if (DECL_INITIAL (decl)) TREE_TYPE (DECL_INITIAL (decl)) = type; @@ -3446,6 +3537,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) = init_one_libfunc (USING_SJLJ_EXCEPTIONS ? "__gcc_personality_sj0" : "__gcc_personality_v0"); + default_init_unwind_resume_libfunc (); using_eh_for_cleanups (); } @@ -4088,10 +4180,10 @@ grokdeclarator (const struct c_declarator *declarator, - 1. Do the calculation in index_type, so that if it is a variable the computations will be done in the proper mode. */ - itype = fold (build2 (MINUS_EXPR, index_type, - convert (index_type, size), - convert (index_type, - size_one_node))); + itype = fold_build2 (MINUS_EXPR, index_type, + convert (index_type, size), + convert (index_type, + size_one_node)); /* If that overflowed, the array is too big. ??? While a size of INT_MAX+1 technically shouldn't @@ -4100,7 +4192,8 @@ grokdeclarator (const struct c_declarator *declarator, index_type, before the subtraction. Handling this case seems like an unnecessary complication. */ - if (TREE_OVERFLOW (itype)) + if (TREE_CODE (itype) == INTEGER_CST + && TREE_OVERFLOW (itype)) { error ("size of array %qs is too large", name); type = error_mark_node; @@ -4204,8 +4297,9 @@ grokdeclarator (const struct c_declarator *declarator, them for noreturn functions. */ if (VOID_TYPE_P (type) && really_funcdef) pedwarn ("function definition has qualified void return type"); - else if (warn_return_type) - warning (0, "type qualifiers ignored on function return type"); + else + warning (OPT_Wreturn_type, + "type qualifiers ignored on function return type"); type = c_build_qualified_type (type, type_quals); } @@ -4264,6 +4358,7 @@ grokdeclarator (const struct c_declarator *declarator, if (TREE_CODE (type) == ARRAY_TYPE && COMPLETE_TYPE_P (type) + && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST && TREE_OVERFLOW (TYPE_SIZE (type))) { error ("size of array %qs is too large", name); @@ -4366,7 +4461,8 @@ grokdeclarator (const struct c_declarator *declarator, /* We don't yet implement attributes in this context. */ if (array_ptr_attrs != NULL_TREE) - warning (0, "attributes in parameter array declarator ignored"); + warning (OPT_Wattributes, + "attributes in parameter array declarator ignored"); size_varies = 0; } @@ -4646,9 +4742,9 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) { tree arg_types = arg_info->types; - if (warn_strict_prototypes && arg_types == 0 && !funcdef_flag - && !in_system_header) - warning (0, "function declaration isn%'t a prototype"); + if (arg_types == 0 && !funcdef_flag && !in_system_header) + warning (OPT_Wstrict_prototypes, + "function declaration isn%'t a prototype"); if (arg_types == error_mark_node) return 0; /* don't set TYPE_ARG_TYPES in this case */ @@ -5708,14 +5804,19 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, /* If the declarator is not suitable for a function definition, cause a syntax error. */ if (decl1 == 0) - return 0; + { + label_context_stack_se = label_context_stack_se->next; + label_context_stack_vm = label_context_stack_vm->next; + return 0; + } decl_attributes (&decl1, attributes, 0); if (DECL_DECLARED_INLINE_P (decl1) && DECL_UNINLINABLE (decl1) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1))) - warning (0, "%Jinline function %qD given attribute noinline", decl1, decl1); + warning (OPT_Wattributes, "%Jinline function %qD given attribute noinline", + decl1, decl1); announce_function (decl1); @@ -5792,14 +5893,16 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, && old_decl != error_mark_node && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0 && C_DECL_ISNT_PROTOTYPE (old_decl)) - warning (0, "function declaration isn%'t a prototype"); + warning (OPT_Wstrict_prototypes, + "function declaration isn%'t a prototype"); /* Optionally warn of any global def with no previous prototype. */ else if (warn_missing_prototypes && old_decl != error_mark_node && TREE_PUBLIC (decl1) && !MAIN_NAME_P (DECL_NAME (decl1)) && C_DECL_ISNT_PROTOTYPE (old_decl)) - warning (0, "%Jno previous prototype for %qD", decl1, decl1); + warning (OPT_Wmissing_prototypes, "%Jno previous prototype for %qD", + decl1, decl1); /* Optionally warn of any def with no previous prototype if the function has already been used. */ else if (warn_missing_prototypes @@ -5807,14 +5910,16 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, && old_decl != error_mark_node && TREE_USED (old_decl) && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0) - warning (0, "%J%qD was used with no prototype before its definition", + warning (OPT_Wmissing_prototypes, + "%J%qD was used with no prototype before its definition", decl1, decl1); /* Optionally warn of any global def with no previous declaration. */ else if (warn_missing_declarations && TREE_PUBLIC (decl1) && old_decl == 0 && !MAIN_NAME_P (DECL_NAME (decl1))) - warning (0, "%Jno previous declaration for %qD", decl1, decl1); + warning (OPT_Wmissing_declarations, "%Jno previous declaration for %qD", + decl1, decl1); /* Optionally warn of any def with no previous declaration if the function has already been used. */ else if (warn_missing_declarations @@ -5822,7 +5927,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, && old_decl != error_mark_node && TREE_USED (old_decl) && C_DECL_IMPLICIT (old_decl)) - warning (0, "%J%qD was used with no declaration before its definition", + warning (OPT_Wmissing_declarations, + "%J%qD was used with no declaration before its definition", decl1, decl1); /* This is a definition, not a reference. @@ -5958,9 +6064,10 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info) warning if we got here because ARG_INFO_TYPES was error_mark_node (this happens when a function definition has just an ellipsis in its parameter list). */ - else if (warn_traditional && !in_system_header && !current_function_scope + else if (!in_system_header && !current_function_scope && arg_info->types != error_mark_node) - warning (0, "%Jtraditional C rejects ISO C style function definitions", + warning (OPT_Wtraditional, + "%Jtraditional C rejects ISO C style function definitions", fndecl); /* Now make all the parameter declarations visible in the function body. @@ -6011,8 +6118,9 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) gcc_assert (TREE_CODE (b->decl) != PARM_DECL || !DECL_WEAK (b->decl)); #endif - if (warn_old_style_definition && !in_system_header) - warning (0, "%Jold-style function definition", fndecl); + if (!in_system_header) + warning (OPT_Wold_style_definition, "%Jold-style function definition", + fndecl); /* Match each formal parameter name with its declaration. Save each decl in the appropriate TREE_PURPOSE slot of the parmids chain. */ @@ -6061,7 +6169,8 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) if (flag_isoc99) pedwarn ("%Jtype of %qD defaults to %", decl, decl); else if (extra_warnings) - warning (0, "%Jtype of %qD defaults to %", decl, decl); + warning (OPT_Wextra, "%Jtype of %qD defaults to %", + decl, decl); } TREE_PURPOSE (parm) = decl; @@ -6415,14 +6524,18 @@ finish_function (void) /* Normally, with -Wreturn-type, flow will complain. Unless we're an inline function, as we might never be compiled separately. */ && DECL_INLINE (fndecl)) - warning (0, "no return statement in function returning non-void"); + { + warning (OPT_Wreturn_type, + "no return statement in function returning non-void"); + TREE_NO_WARNING (fndecl) = 1; + } /* With just -Wextra, complain only if function returns both with and without a value. */ if (extra_warnings && current_function_returns_value && current_function_returns_null) - warning (0, "this function may return with or without a value"); + warning (OPT_Wextra, "this function may return with or without a value"); /* Store the end of the function, so that we get good line number info for the epilogue. */ @@ -6643,16 +6756,6 @@ c_dup_lang_specific_decl (tree decl) functions are not called from anywhere in the C front end, but as these changes continue, that will change. */ -/* Returns nonzero if the current statement is a full expression, - i.e. temporaries created during that statement should be destroyed - at the end of the statement. */ - -int -stmts_are_full_exprs_p (void) -{ - return 0; -} - /* Returns the stmt_tree (if any) to which statements are currently being added. If there is no active statement-tree, NULL is returned. */ @@ -7170,7 +7273,7 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec) && C_IS_RESERVED_WORD (scspec)); i = C_RID_CODE (scspec); if (extra_warnings && specs->non_sc_seen_p) - warning (0, "%qE is not at beginning of declaration", scspec); + warning (OPT_Wextra, "%qE is not at beginning of declaration", scspec); switch (i) { case RID_INLINE: