X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-decl.c;h=eececb18d39b5b7c19ef8735756df051ee1a7372;hb=b2eafcc8ff6d32d29cd7d207a0231ed31b01b873;hp=f881ea8e052135b31945a06ae72ad20570921954;hpb=61ba37bfdc89277570f40931fdfeb82dfefc5585;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-decl.c b/gcc/c-decl.c index f881ea8e052..eececb18d39 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 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -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, @@ -29,6 +29,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "config.h" #include "system.h" #include "coretypes.h" +#include "input.h" #include "tm.h" #include "intl.h" #include "tree.h" @@ -97,6 +98,14 @@ static int enum_overflow; static location_t current_function_prototype_locus; +/* Whether this prototype was built-in. */ + +static bool current_function_prototype_built_in; + +/* The argument type information of this prototype. */ + +static tree current_function_prototype_arg_types; + /* The argument information structure for the function currently being defined. */ @@ -148,6 +157,11 @@ static int warn_about_return_type; static int current_extern_inline; +/* Nonzero when the current toplevel function contains a declaration + of a nested function which is never defined. */ + +static bool undef_nested_function; + /* True means global_bindings_p should return false even if the scope stack says we are in file scope. */ bool c_override_global_bindings_to_false; @@ -404,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 @@ -521,9 +560,9 @@ c_finish_incomplete_decl (tree decl) && !DECL_EXTERNAL (decl) && TYPE_DOMAIN (type) == 0) { - warning ("%Jarray %qD assumed to have one element", decl, decl); + warning (0, "%Jarray %qD assumed to have one element", decl, decl); - complete_array_type (type, NULL_TREE, 1); + complete_array_type (&TREE_TYPE (decl), NULL_TREE, true); layout_decl (decl, 0); } @@ -552,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) @@ -667,6 +698,8 @@ pop_scope (void) bool functionbody = scope->function_body; bool keep = functionbody || scope->keep || scope->bindings; + c_end_vm_scope (scope->depth); + /* If appropriate, create a BLOCK to record the decls for the life of this function. */ block = 0; @@ -724,9 +757,9 @@ pop_scope (void) else if (!TREE_USED (p) && warn_unused_label) { if (DECL_INITIAL (p)) - warning ("%Jlabel %qD defined but not used", p, p); + warning (0, "%Jlabel %qD defined but not used", p, p); else - warning ("%Jlabel %qD declared but not defined", p, p); + warning (0, "%Jlabel %qD declared but not defined", p, p); } /* Labels go in BLOCK_VARS. */ TREE_CHAIN (p) = BLOCK_VARS (block); @@ -758,18 +791,23 @@ pop_scope (void) && DECL_ABSTRACT_ORIGIN (p) != 0 && DECL_ABSTRACT_ORIGIN (p) != p) TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1; + if (!DECL_EXTERNAL (p) + && DECL_INITIAL (p) == 0) + { + error ("%Jnested function %qD declared but never defined", p, p); + undef_nested_function = true; + } goto common_symbol; 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 ("%Junused variable %qD", p, p); + warning (OPT_Wunused_variable, "%Junused variable %qD", p, p); if (b->inner_comp) { @@ -896,6 +934,8 @@ pop_file_scope (void) /* Pop off the file scope and close this translation unit. */ pop_scope (); file_scope = 0; + + maybe_apply_pending_pragma_weaks (); cgraph_finalize_compilation_unit (); } @@ -1029,8 +1069,7 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype) tree newargs, oldargs; int i; - /* ??? Elsewhere TYPE_MAIN_VARIANT is not used in this context. */ -#define END_OF_ARGLIST(t) (TYPE_MAIN_VARIANT (t) == void_type_node) +#define END_OF_ARGLIST(t) ((t) == void_type_node) oldargs = TYPE_ACTUAL_ARG_TYPES (oldtype); newargs = TYPE_ARG_TYPES (newtype); @@ -1038,8 +1077,8 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype) for (;;) { - tree oldargtype = TREE_VALUE (oldargs); - tree newargtype = TREE_VALUE (newargs); + tree oldargtype = TYPE_MAIN_VARIANT (TREE_VALUE (oldargs)); + tree newargtype = TYPE_MAIN_VARIANT (TREE_VALUE (newargs)); if (END_OF_ARGLIST (oldargtype) && END_OF_ARGLIST (newargtype)) break; @@ -1076,7 +1115,7 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype) /* If we get here, no errors were found, but do issue a warning for this poor-style construct. */ - warning ("%Jprototype for %qD follows non-prototype definition", + warning (0, "%Jprototype for %qD follows non-prototype definition", newdecl, newdecl); return true; #undef END_OF_ARGLIST @@ -1086,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. @@ -1113,6 +1152,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, tree newtype, oldtype; bool pedwarned = false; bool warned = false; + bool retval = true; /* If we have error_mark_node for either decl or type, just discard the previous decl - we're in an error cascade already. */ @@ -1136,11 +1176,11 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, locate_old_decl (olddecl, error); } else if (TREE_PUBLIC (newdecl)) - warning ("%Jbuilt-in function %qD declared as non-function", - newdecl, newdecl); - else if (warn_shadow) - warning ("%Jdeclaration of %qD shadows a built-in function", + warning (0, "%Jbuilt-in function %qD declared as non-function", newdecl, newdecl); + else + warning (OPT_Wshadow, "%Jdeclaration of %qD shadows " + "a built-in function", newdecl, newdecl); return false; } @@ -1169,7 +1209,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, /* If types don't match for a built-in, throw away the built-in. No point in calling locate_old_decl here, it won't print anything. */ - warning ("%Jconflicting types for built-in function %qD", + warning (0, "%Jconflicting types for built-in function %qD", newdecl, newdecl); return false; } @@ -1254,26 +1294,55 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, || (DECL_INITIAL (newdecl) && !TYPE_ARG_TYPES (TREE_TYPE (newdecl))))) { - if (warn_shadow) - warning ("%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; } if (DECL_INITIAL (newdecl)) { - if (DECL_INITIAL (olddecl) - && !(DECL_DECLARED_INLINE_P (olddecl) - && DECL_EXTERNAL (olddecl) - && !(DECL_DECLARED_INLINE_P (newdecl) - && DECL_EXTERNAL (newdecl) - && same_translation_unit_p (olddecl, newdecl)))) + if (DECL_INITIAL (olddecl)) { - error ("%Jredefinition of %qD", newdecl, newdecl); - locate_old_decl (olddecl, error); - return false; - } + /* If both decls have extern inline and are in the same TU, + reject the new decl. */ + if (DECL_DECLARED_INLINE_P (olddecl) + && DECL_EXTERNAL (olddecl) + && DECL_DECLARED_INLINE_P (newdecl) + && DECL_EXTERNAL (newdecl) + && same_translation_unit_p (newdecl, olddecl)) + { + error ("%Jredefinition of %qD", newdecl, newdecl); + locate_old_decl (olddecl, error); + return false; + } + /* If both decls have not extern inline, reject the new decl. */ + if (!DECL_DECLARED_INLINE_P (olddecl) + && !DECL_EXTERNAL (olddecl) + && !DECL_DECLARED_INLINE_P (newdecl) + && !DECL_EXTERNAL (newdecl)) + { + error ("%Jredefinition of %qD", newdecl, newdecl); + locate_old_decl (olddecl, error); + return false; + } + /* If the new decl is declared as extern inline, error if they are + in the same TU, otherwise retain the old decl. */ + if (!DECL_DECLARED_INLINE_P (olddecl) + && !DECL_EXTERNAL (olddecl) + && DECL_DECLARED_INLINE_P (newdecl) + && DECL_EXTERNAL (newdecl)) + { + if (same_translation_unit_p (newdecl, olddecl)) + { + error ("%Jredefinition of %qD", newdecl, newdecl); + locate_old_decl (olddecl, error); + return false; + } + else + retval = false; + } + } } /* If we have a prototype after an old-style function definition, the argument types must be checked specially. */ @@ -1322,8 +1391,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } else if (warn_traditional) { - warning ("%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; } } @@ -1375,8 +1444,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } else if (warn_traditional) { - warning ("%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; } } @@ -1424,7 +1493,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl) && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) { - warning ("%Jredeclaration of %qD with different visibility " + warning (0, "%Jredeclaration of %qD with different visibility " "(old visibility preserved)", newdecl, newdecl); warned = true; } @@ -1435,15 +1504,15 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (DECL_DECLARED_INLINE_P (newdecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) { - warning ("%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 ("%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; } @@ -1457,13 +1526,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { if (TREE_USED (olddecl)) { - warning ("%J%qD declared inline after being called", + warning (0, "%J%qD declared inline after being called", olddecl, olddecl); warned = true; } else if (DECL_INITIAL (olddecl)) { - warning ("%J%qD declared inline after its definition", + warning (0, "%J%qD declared inline after its definition", olddecl, olddecl); warned = true; } @@ -1507,15 +1576,16 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && !(TREE_CODE (newdecl) == PARM_DECL && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))) { - warning ("%Jredundant redeclaration of %qD", newdecl, newdecl); + warning (OPT_Wredundant_decls, "%Jredundant redeclaration of %qD", + newdecl, newdecl); warned = true; } /* Report location of previous decl/defn in a consistent manner. */ if (warned || pedwarned) - locate_old_decl (olddecl, pedwarned ? pedwarn : warning); + locate_old_decl (olddecl, pedwarned ? pedwarn : warning0); - return true; + return retval; } /* Subroutine of duplicate_decls. NEWDECL has been found to be @@ -1528,6 +1598,10 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) { int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0); + int new_is_prototype = (TREE_CODE (newdecl) == FUNCTION_DECL + && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0); + int old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL + && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0); /* For real parm decl following a forward decl, rechain the old decl in its new location and clear TREE_ASM_WRITTEN (it's not a @@ -1601,8 +1675,12 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) if (TREE_DEPRECATED (newdecl)) TREE_DEPRECATED (olddecl) = 1; - /* Keep source location of definition rather than declaration. */ - if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0) + /* Keep source location of definition rather than declaration and of + prototype rather than non-prototype unless that prototype is + built-in. */ + if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0) + || (old_is_prototype && !new_is_prototype + && !C_DECL_BUILTIN_PROTOTYPE (olddecl))) DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl); /* Merge the unused-warning information. */ @@ -1644,6 +1722,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl); + DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl); } /* Merge the storage class information. */ @@ -1717,6 +1796,11 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl); DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); C_DECL_DECLARED_BUILTIN (newdecl) = 1; + if (new_is_prototype) + C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0; + else + C_DECL_BUILTIN_PROTOTYPE (newdecl) + = C_DECL_BUILTIN_PROTOTYPE (olddecl); } /* Also preserve various other info from the definition. */ @@ -1816,23 +1900,30 @@ warn_if_shadowing (tree new_decl) { tree old_decl = b->decl; - if (TREE_CODE (old_decl) == PARM_DECL) - warning ("%Jdeclaration of %qD shadows a parameter", + if (old_decl == error_mark_node) + { + warning (0, "%Jdeclaration of %qD shadows previous non-variable", + new_decl, new_decl); + break; + } + else if (TREE_CODE (old_decl) == PARM_DECL) + warning (0, "%Jdeclaration of %qD shadows a parameter", new_decl, new_decl); else if (DECL_FILE_SCOPE_P (old_decl)) - warning ("%Jdeclaration of %qD shadows a global declaration", + warning (0, "%Jdeclaration of %qD shadows a global declaration", new_decl, new_decl); else if (TREE_CODE (old_decl) == FUNCTION_DECL && DECL_BUILT_IN (old_decl)) - warning ("%Jdeclaration of %qD shadows a built-in function", - new_decl, new_decl); + { + warning (0, "%Jdeclaration of %qD shadows a built-in function", + new_decl, new_decl); + break; + } else - warning ("%Jdeclaration of %qD shadows a previous local", + warning (0, "%Jdeclaration of %qD shadows a previous local", new_decl, new_decl); - if (TREE_CODE (old_decl) != FUNCTION_DECL - || !DECL_BUILT_IN (old_decl)) - warning ("%Jshadowed declaration is here", old_decl); + warning (0, "%Jshadowed declaration is here", old_decl); break; } @@ -1931,6 +2022,12 @@ pushdecl (tree x) || DECL_INITIAL (x) || !DECL_EXTERNAL (x))) DECL_CONTEXT (x) = current_function_decl; + /* If this is of variably modified type, prevent jumping into its + scope. */ + if ((TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == TYPE_DECL) + && variably_modified_type_p (TREE_TYPE (x), NULL_TREE)) + c_begin_vm_scope (scope->depth); + /* Anonymous decls are just inserted in the scope. */ if (!name) { @@ -1948,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; } @@ -1983,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 ("nested extern declaration of %qD", x); + warning (OPT_Wnested_externs, "nested extern declaration of %qD", x); while (b && !B_IN_EXTERNAL_SCOPE (b)) { @@ -1998,7 +2135,7 @@ pushdecl (tree x) its type saved; the others will already have had their proper types saved and the types will not have changed as their scopes will not have been re-entered. */ - if (DECL_FILE_SCOPE_P (b->decl) && !type_saved) + if (DECL_P (b->decl) && DECL_FILE_SCOPE_P (b->decl) && !type_saved) { b->type = TREE_TYPE (b->decl); type_saved = true; @@ -2039,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 @@ -2069,30 +2214,6 @@ pushdecl (tree x) } } } - /* Similarly, a declaration of a function with static linkage at - block scope must be checked against any existing declaration - of that function at file scope. */ - else if (TREE_CODE (x) == FUNCTION_DECL && scope != file_scope - && !TREE_PUBLIC (x) && !DECL_INITIAL (x)) - { - if (warn_nested_externs && !DECL_IN_SYSTEM_HEADER (x)) - warning ("nested static declaration of %qD", x); - - while (b && !B_IN_FILE_SCOPE (b)) - b = b->shadowed; - - if (b && same_translation_unit_p (x, b->decl) - && duplicate_decls (x, b->decl)) - { - bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true); - return b->decl; - } - else - { - bind (name, x, file_scope, /*invisible=*/true, /*nested=*/false); - nested = true; - } - } warn_if_shadowing (x); @@ -2161,16 +2282,16 @@ 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; - case 1: diag = warning; break; + case 1: diag = warning0; break; case 2: diag = error; break; 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); } @@ -2196,6 +2317,9 @@ implicitly_declare (tree functionid) if (decl) { + if (decl == error_mark_node) + return decl; + /* FIXME: Objective-C has weird not-really-builtin functions which are supposed to be visible automatically. They wind up in the external scope because they're pushed before the file @@ -2228,7 +2352,7 @@ implicitly_declare (tree functionid) (TREE_TYPE (decl))); if (!comptypes (newtype, TREE_TYPE (decl))) { - warning ("incompatible implicit declaration of built-in" + warning (0, "incompatible implicit declaration of built-in" " function %qD", decl); newtype = TREE_TYPE (decl); } @@ -2281,26 +2405,26 @@ implicitly_declare (tree functionid) ID, including a reference to a builtin outside of function-call context. Establish a binding of the identifier to error_mark_node in an appropriate scope, which will suppress further errors for the - same identifier. */ + same identifier. The error message should be given location LOC. */ void -undeclared_variable (tree id) +undeclared_variable (tree id, location_t loc) { static bool already = false; struct c_scope *scope; if (current_function_decl == 0) { - error ("%qE undeclared here (not in a function)", id); + error ("%H%qE undeclared here (not in a function)", &loc, id); scope = current_scope; } else { - error ("%qE undeclared (first use in this function)", id); + error ("%H%qE undeclared (first use in this function)", &loc, id); if (!already) { - error ("(Each undeclared identifier is reported only once"); - error ("for each function it appears in.)"); + error ("%H(Each undeclared identifier is reported only once", &loc); + error ("%Hfor each function it appears in.)", &loc); already = true; } @@ -2338,8 +2462,7 @@ lookup_label (tree name) if (current_function_decl == 0) { - error ("label %qs referenced outside of any function", - IDENTIFIER_POINTER (name)); + error ("label %qE referenced outside of any function", name); return 0; } @@ -2381,7 +2504,7 @@ declare_label (tree name) at this scope */ if (b && B_IN_CURRENT_SCOPE (b)) { - error ("duplicate label declaration %qs", IDENTIFIER_POINTER (name)); + error ("duplicate label declaration %qE", name); locate_old_decl (b->decl, error); /* Just use the previous declaration. */ @@ -2409,6 +2532,7 @@ define_label (location_t location, tree name) if there is a containing function with a declared label with the same name. */ tree label = I_LABEL_DECL (name); + struct c_label_list *nlist_se, *nlist_vm; if (label && ((DECL_CONTEXT (label) == current_function_decl @@ -2425,6 +2549,11 @@ define_label (location_t location, tree name) /* The label has been used or declared already in this function, but not defined. Update its location to point to this definition. */ + if (C_DECL_UNDEFINABLE_STMT_EXPR (label)) + error ("%Jjump into statement expression", label); + if (C_DECL_UNDEFINABLE_VM (label)) + error ("%Jjump into scope of identifier with variably modified type", + label); DECL_SOURCE_LOCATION (label) = location; } else @@ -2437,10 +2566,19 @@ define_label (location_t location, tree name) /*invisible=*/false, /*nested=*/false); } - if (warn_traditional && !in_system_header && lookup_name (name)) - warning ("%Htraditional C lacks a separate namespace for labels, " - "identifier %qs conflicts", &location, - IDENTIFIER_POINTER (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; + nlist_se->label = label; + label_context_stack_se->labels_def = nlist_se; + + nlist_vm = XOBNEW (&parser_obstack, struct c_label_list); + nlist_vm->next = label_context_stack_vm->labels_def; + nlist_vm->label = label; + label_context_stack_vm->labels_def = nlist_vm; /* Mark label as having been defined. */ DECL_INITIAL (label) = error_mark_node; @@ -2504,9 +2642,8 @@ void pending_xref_error (void) { if (pending_invalid_xref != 0) - error ("%H%qs defined as wrong kind of tag", - &pending_invalid_xref_location, - IDENTIFIER_POINTER (pending_invalid_xref)); + error ("%H%qE defined as wrong kind of tag", + &pending_invalid_xref_location, pending_invalid_xref); pending_invalid_xref = 0; } @@ -2546,11 +2683,9 @@ lookup_name_in_scope (tree name, struct c_scope *scope) void c_init_decl_processing (void) { - tree endlink; - tree ptr_ftype_void, ptr_ftype_ptr; location_t save_loc = input_location; - /* Adds some ggc roots, and reserved words for c-parse.in. */ + /* Initialize reserved words for parser. */ c_parse_init (); current_function_decl = 0; @@ -2584,12 +2719,6 @@ c_init_decl_processing (void) pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"), boolean_type_node)); - endlink = void_list_node; - ptr_ftype_void = build_function_type (ptr_type_node, endlink); - ptr_ftype_ptr - = build_function_type (ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, endlink)); - input_location = save_loc; pedantic_lvalues = true; @@ -2612,9 +2741,9 @@ c_make_fname_decl (tree id, int type_dep) tree decl, type, init; size_t length = strlen (name); - type = build_array_type - (build_qualified_type (char_type_node, TYPE_QUAL_CONST), - build_index_type (size_int (length))); + type = build_array_type (char_type_node, + build_index_type (size_int (length))); + type = c_build_qualified_type (type, TYPE_QUAL_CONST); decl = build_decl (VAR_DECL, id, type); @@ -2662,6 +2791,7 @@ builtin_function (const char *name, tree type, int function_code, DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl); DECL_BUILT_IN_CLASS (decl) = cl; DECL_FUNCTION_CODE (decl) = function_code; + C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0); if (library_name) SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name)); @@ -2800,13 +2930,13 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) if (!warned && !in_system_header && declspecs->storage_class != csc_none) { - warning ("useless storage class specifier in empty declaration"); + warning (0, "useless storage class specifier in empty declaration"); warned = 2; } if (!warned && !in_system_header && declspecs->thread_p) { - warning ("useless %<__thread%> in empty declaration"); + warning (0, "useless %<__thread%> in empty declaration"); warned = 2; } @@ -2814,7 +2944,7 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) || declspecs->volatile_p || declspecs->restrict_p)) { - warning ("useless type qualifier in empty declaration"); + warning (0, "useless type qualifier in empty declaration"); warned = 2; } @@ -2893,7 +3023,7 @@ build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p, pedwarn ("ISO C90 does not support %<[*]%> array declarators"); } if (vla_unspec_p) - warning ("GCC does not yet properly implement %<[*]%> array declarators"); + warning (0, "GCC does not yet properly implement %<[*]%> array declarators"); return declarator; } @@ -2971,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 ("%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? @@ -3019,11 +3149,6 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, error ("variable %qD has initializer but incomplete type", decl); initialized = 0; } - else if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))) - { - error ("elements of array %qD have incomplete type", decl); - initialized = 0; - } else if (C_DECL_VARIABLE_SIZE (decl)) { /* Although C99 is unclear about whether incomplete arrays @@ -3097,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 ("%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. */ @@ -3152,23 +3278,26 @@ finish_decl (tree decl, tree init, tree asmspec_tree) && TYPE_DOMAIN (type) == 0 && TREE_CODE (decl) != TYPE_DECL) { - int do_default + bool do_default = (TREE_STATIC (decl) /* Even if pedantic, an external linkage array may have incomplete type at first. */ ? pedantic && !TREE_PUBLIC (decl) : !DECL_EXTERNAL (decl)); int failure - = complete_array_type (type, DECL_INITIAL (decl), do_default); + = complete_array_type (&TREE_TYPE (decl), DECL_INITIAL (decl), + do_default); /* 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, @@ -3179,14 +3308,36 @@ 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 (); } - /* TYPE_MAX_VALUE is always one less than the number of elements - in the array, because we start counting at zero. Therefore, - warn only if the value is less than zero. */ - else if (pedantic && TYPE_DOMAIN (type) != 0 - && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0) - error ("%Jzero or negative size array %qD", decl, decl); + if (DECL_INITIAL (decl)) + TREE_TYPE (DECL_INITIAL (decl)) = type; layout_decl (decl, 0); } @@ -3240,8 +3391,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) } /* If #pragma weak was used, mark the decl weak now. */ - if (current_scope == file_scope) - maybe_apply_pragma_weak (decl); + maybe_apply_pragma_weak (decl); /* If this is a variable definition, determine its ELF visibility. */ if (TREE_CODE (decl) == VAR_DECL @@ -3270,7 +3420,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) && TREE_CODE (decl) == VAR_DECL && !C_DECL_REGISTER (decl) && !TREE_STATIC (decl)) - warning ("%Jignoring asm-specifier for non-static local " + warning (0, "%Jignoring asm-specifier for non-static local " "variable %qD", decl, decl); else if (C_DECL_REGISTER (decl)) change_decl_assembler_name (decl, get_identifier (asmspec)); @@ -3387,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 (); } @@ -3475,17 +3626,19 @@ build_compound_literal (tree type, tree init) if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type)) { - int failure = complete_array_type (type, DECL_INITIAL (decl), 1); - + int failure = complete_array_type (&TREE_TYPE (decl), + DECL_INITIAL (decl), true); gcc_assert (!failure); + + type = TREE_TYPE (decl); + TREE_TYPE (DECL_INITIAL (decl)) = type; } - type = TREE_TYPE (decl); if (type == error_mark_node || !COMPLETE_TYPE_P (type)) return error_mark_node; stmt = build_stmt (DECL_EXPR, decl); - complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt); + complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt); TREE_SIDE_EFFECTS (complit) = 1; layout_decl (decl, 0); @@ -3503,6 +3656,7 @@ build_compound_literal (tree type, tree init) DECL_DEFER_OUTPUT (decl) = 1; DECL_COMDAT (decl) = 1; DECL_ARTIFICIAL (decl) = 1; + DECL_IGNORED_P (decl) = 1; pushdecl (decl); rest_of_decl_compilation (decl, 1, 0); } @@ -3510,73 +3664,6 @@ build_compound_literal (tree type, tree init) return complit; } -/* Make TYPE a complete type based on INITIAL_VALUE. - Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, - 2 if there was no information (in which case assume 1 if DO_DEFAULT). */ - -int -complete_array_type (tree type, tree initial_value, int do_default) -{ - tree maxindex = NULL_TREE; - int value = 0; - - if (initial_value) - { - /* Note MAXINDEX is really the maximum index, - one less than the size. */ - if (TREE_CODE (initial_value) == STRING_CST) - { - int eltsize - = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); - maxindex = build_int_cst (NULL_TREE, - (TREE_STRING_LENGTH (initial_value) - / eltsize) - 1); - } - else if (TREE_CODE (initial_value) == CONSTRUCTOR) - { - tree elts = CONSTRUCTOR_ELTS (initial_value); - maxindex = build_int_cst (NULL_TREE, -1); - for (; elts; elts = TREE_CHAIN (elts)) - { - if (TREE_PURPOSE (elts)) - maxindex = TREE_PURPOSE (elts); - else - maxindex = fold (build2 (PLUS_EXPR, integer_type_node, - maxindex, integer_one_node)); - } - } - else - { - /* Make an error message unless that happened already. */ - if (initial_value != error_mark_node) - value = 1; - - /* Prevent further error messages. */ - maxindex = build_int_cst (NULL_TREE, 0); - } - } - - if (!maxindex) - { - if (do_default) - maxindex = build_int_cst (NULL_TREE, 0); - value = 2; - } - - if (maxindex) - { - TYPE_DOMAIN (type) = build_index_type (maxindex); - - gcc_assert (TREE_TYPE (maxindex)); - } - - /* Lay out the type now that we can get the real answer. */ - - layout_type (type); - - return value; -} - /* Determine whether TYPE is a structure with a flexible array member, or a union containing such a structure (possibly recursively). */ @@ -3620,12 +3707,10 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) unsigned HOST_WIDE_INT w; const char *name = orig_name ? orig_name: _(""); - /* Necessary? */ - STRIP_NOPS (*width); - /* Detect and ignore out of range field width and process valid field widths. */ - if (TREE_CODE (*width) != INTEGER_CST) + if (!INTEGRAL_TYPE_P (TREE_TYPE (*width)) + || TREE_CODE (*width) != INTEGER_CST) { error ("bit-field %qs width not an integer constant", name); *width = integer_one_node; @@ -3681,7 +3766,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) if (!lt || w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type)) || w < min_precision (lt->enum_max, TYPE_UNSIGNED (*type))) - warning ("%qs is narrower than values of its type", name); + warning (0, "%qs is narrower than values of its type", name); } } @@ -3840,7 +3925,7 @@ grokdeclarator (const struct c_declarator *declarator, if (volatilep > 1) pedwarn ("duplicate %"); } - if (!flag_gen_aux_info && (TYPE_QUALS (type))) + if (!flag_gen_aux_info && (TYPE_QUALS (element_type))) type = TYPE_MAIN_VARIANT (type); type_quals = ((constp ? TYPE_QUAL_CONST : 0) | (restrictp ? TYPE_QUAL_RESTRICT : 0) @@ -3899,7 +3984,7 @@ grokdeclarator (const struct c_declarator *declarator, { /* 'extern' with initialization is invalid if not at file scope. */ if (current_scope == file_scope) - warning ("%qs initialized and declared %", name); + warning (0, "%qs initialized and declared %", name); else error ("%qs has both % and initializer", name); } @@ -3925,7 +4010,13 @@ grokdeclarator (const struct c_declarator *declarator, /* Now figure out the structure of the declarator proper. Descend through it, creating more complex types, until we reach - the declared identifier (or NULL_TREE, in an absolute declarator). */ + the declared identifier (or NULL_TREE, in an absolute declarator). + At each stage we maintain an unqualified version of the type + together with any qualifiers that should be applied to it with + c_build_qualified_type; this way, array types including + multidimensional array types are first built up in unqualified + form and then the qualified form is created with + TYPE_MAIN_VARIANT pointing to the unqualified form. */ while (declarator && declarator->kind != cdk_id) { @@ -4089,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 @@ -4101,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; @@ -4121,17 +4213,14 @@ grokdeclarator (const struct c_declarator *declarator, itype = build_range_type (sizetype, size_zero_node, NULL_TREE); } - /* If pedantic, complain about arrays of incomplete types. */ - if (pedantic && !COMPLETE_TYPE_P (type)) - pedwarn ("array type has incomplete element type"); - - /* Build the array type itself, then merge any constancy - or volatility into the target type. We must do it in - this order to ensure that the TYPE_MAIN_VARIANT field - of the array type is set correctly. */ - type = build_array_type (type, itype); - if (type_quals) - type = c_build_qualified_type (type, type_quals); + /* Complain about arrays of incomplete types. */ + if (!COMPLETE_TYPE_P (type)) + { + error ("array type has incomplete element type"); + type = error_mark_node; + } + else + type = build_array_type (type, itype); if (size_varies) C_TYPE_VARIABLE_SIZE (type) = 1; @@ -4208,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 ("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); } @@ -4257,7 +4347,8 @@ grokdeclarator (const struct c_declarator *declarator, } } - /* Now TYPE has the actual type. */ + /* Now TYPE has the actual type, apart from any qualifiers in + TYPE_QUALS. */ /* Check the type and width of a bit-field. */ if (bitfield) @@ -4267,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); @@ -4369,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 ("attributes in parameter array declarator ignored"); + warning (OPT_Wattributes, + "attributes in parameter array declarator ignored"); size_varies = 0; } @@ -4426,11 +4519,7 @@ grokdeclarator (const struct c_declarator *declarator, error ("field %qs has incomplete type", name); type = error_mark_node; } - /* Move type qualifiers down to element of an array. */ - if (TREE_CODE (type) == ARRAY_TYPE && type_quals) - type = build_array_type (c_build_qualified_type (TREE_TYPE (type), - type_quals), - TYPE_DOMAIN (type)); + type = c_build_qualified_type (type, type_quals); decl = build_decl (FIELD_DECL, declarator->u.id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; @@ -4477,7 +4566,7 @@ grokdeclarator (const struct c_declarator *declarator, that the function does not return. */ if ((type_quals & TYPE_QUAL_VOLATILE) && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))) - warning ("% function returns non-void value"); + warning (0, "% function returns non-void value"); /* Every function declaration is an external reference (DECL_EXTERNAL) except for those which are not at file @@ -4535,17 +4624,7 @@ grokdeclarator (const struct c_declarator *declarator, /* An uninitialized decl with `extern' is a reference. */ int extern_ref = !initialized && storage_class == csc_extern; - /* Move type qualifiers down to element of an array. */ - if (TREE_CODE (type) == ARRAY_TYPE && type_quals) - { - int saved_align = TYPE_ALIGN(type); - type = build_array_type (c_build_qualified_type (TREE_TYPE (type), - type_quals), - TYPE_DOMAIN (type)); - TYPE_ALIGN (type) = saved_align; - } - else if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type (type, type_quals); /* C99 6.2.2p7: It is invalid (compile-time undefined behavior) to create an 'extern' declaration for a @@ -4567,6 +4646,7 @@ grokdeclarator (const struct c_declarator *declarator, } decl = build_decl (VAR_DECL, declarator->u.id, type); + DECL_SOURCE_LOCATION (decl) = declarator->id_loc; if (size_varies) C_DECL_VARIABLE_SIZE (decl) = 1; @@ -4662,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 ("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 */ @@ -4717,10 +4797,10 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) else if (VOID_TYPE_P (type)) { if (DECL_NAME (parm)) - warning ("%Jparameter %u (%qD) has void type", + warning (0, "%Jparameter %u (%qD) has void type", parm, parmno, parm); else - warning ("%Jparameter %u has void type", + warning (0, "%Jparameter %u has void type", parm, parmno); } } @@ -4855,16 +4935,16 @@ get_parm_info (bool ellipsis) { if (b->id) /* The %s will be one of 'struct', 'union', or 'enum'. */ - warning ("%<%s %E%> declared inside parameter list", + warning (0, "%<%s %E%> declared inside parameter list", keyword, b->id); else /* The %s will be one of 'struct', 'union', or 'enum'. */ - warning ("anonymous %s declared inside parameter list", + warning (0, "anonymous %s declared inside parameter list", keyword); if (!explained_incomplete_types) { - warning ("its scope is only this definition or declaration," + warning (0, "its scope is only this definition or declaration," " which is probably not what you want"); explained_incomplete_types = true; } @@ -4997,18 +5077,16 @@ start_struct (enum tree_code code, tree name) if (TYPE_SIZE (ref)) { if (code == UNION_TYPE) - error ("redefinition of %", IDENTIFIER_POINTER (name)); + error ("redefinition of %", name); else - error ("redefinition of %", IDENTIFIER_POINTER (name)); + error ("redefinition of %", name); } else if (C_TYPE_BEING_DEFINED (ref)) { if (code == UNION_TYPE) - error ("nested redefinition of %", - IDENTIFIER_POINTER (name)); + error ("nested redefinition of %", name); else - error ("nested redefinition of %", - IDENTIFIER_POINTER (name)); + error ("nested redefinition of %", name); } } else @@ -5290,8 +5368,11 @@ finish_struct (tree t, tree fieldlist, tree attributes) = tree_low_cst (DECL_INITIAL (*fieldlistp), 1); tree type = TREE_TYPE (*fieldlistp); if (width != TYPE_PRECISION (type)) - TREE_TYPE (*fieldlistp) - = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type)); + { + TREE_TYPE (*fieldlistp) + = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type)); + DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp)); + } DECL_INITIAL (*fieldlistp) = 0; } else @@ -5366,10 +5447,10 @@ finish_struct (tree t, tree fieldlist, tree attributes) make it one, warn and turn off the flag. */ if (TREE_CODE (t) == UNION_TYPE && TYPE_TRANSPARENT_UNION (t) - && TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t))) + && (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t)))) { TYPE_TRANSPARENT_UNION (t) = 0; - warning ("union cannot be made transparent"); + warning (0, "union cannot be made transparent"); } /* If this structure or union completes the type of any previous @@ -5440,14 +5521,14 @@ start_enum (tree name) } if (C_TYPE_BEING_DEFINED (enumtype)) - error ("nested redefinition of %", IDENTIFIER_POINTER (name)); + error ("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 %", IDENTIFIER_POINTER (name)); + error ("redeclaration of %", name); /* Completely replace its old definition. The old enumerators remain defined, however. */ @@ -5510,7 +5591,7 @@ finish_enum (tree enumtype, tree values, tree attributes) tem = c_common_type_for_size (precision, unsign); if (tem == NULL) { - warning ("enumeration values exceed range of largest integer"); + warning (0, "enumeration values exceed range of largest integer"); tem = long_long_integer_type_node; } } @@ -5614,17 +5695,14 @@ build_enumerator (tree name, tree value) /* Validate and default VALUE. */ - /* Remove no-op casts from the value. */ - if (value) - STRIP_TYPE_NOPS (value); - if (value != 0) { /* Don't issue more errors for error_mark_node (i.e. an undeclared identifier) - just ignore the value expression. */ if (value == error_mark_node) value = 0; - else if (TREE_CODE (value) != INTEGER_CST) + else if (!INTEGRAL_TYPE_P (TREE_TYPE (value)) + || TREE_CODE (value) != INTEGER_CST) { error ("enumerator value for %qE is not an integer constant", name); value = 0; @@ -5693,6 +5771,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, { tree decl1, old_decl; tree restype, resdecl; + struct c_label_context_se *nstack_se; + struct c_label_context_vm *nstack_vm; current_function_returns_value = 0; /* Assume, until we see it does. */ current_function_returns_null = 0; @@ -5701,6 +5781,19 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, current_extern_inline = 0; c_switch_stack = NULL; + nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se); + nstack_se->labels_def = NULL; + nstack_se->labels_used = NULL; + nstack_se->next = label_context_stack_se; + label_context_stack_se = nstack_se; + + nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm); + nstack_vm->labels_def = NULL; + nstack_vm->labels_used = NULL; + nstack_vm->scope = 0; + nstack_vm->next = label_context_stack_vm; + label_context_stack_vm = nstack_vm; + /* Indicate no valid break/continue context by setting these variables to some non-null, non-label value. We'll notice and emit the proper error message in c_finish_bc_stmt. */ @@ -5711,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 ("%Jinline function %qD given attribute noinline", decl1, decl1); + warning (OPT_Wattributes, "%Jinline function %qD given attribute noinline", + decl1, decl1); announce_function (decl1); @@ -5741,46 +5839,96 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, /* If this definition isn't a prototype and we had a prototype declaration before, copy the arg type info from that prototype. */ old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope); - if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE - && comptypes (TREE_TYPE (TREE_TYPE (decl1)), - TREE_TYPE (TREE_TYPE (old_decl))) - && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0) - { - TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl), - TREE_TYPE (decl1)); - current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl); + current_function_prototype_locus = UNKNOWN_LOCATION; + current_function_prototype_built_in = false; + current_function_prototype_arg_types = NULL_TREE; + if (TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0) + { + if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE + && comptypes (TREE_TYPE (TREE_TYPE (decl1)), + TREE_TYPE (TREE_TYPE (old_decl)))) + { + TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl), + TREE_TYPE (decl1)); + current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl); + current_function_prototype_built_in + = C_DECL_BUILTIN_PROTOTYPE (old_decl); + current_function_prototype_arg_types + = TYPE_ARG_TYPES (TREE_TYPE (decl1)); + } + if (TREE_PUBLIC (decl1)) + { + /* If there is an external prototype declaration of this + function, record its location but do not copy information + to this decl. This may be an invisible declaration + (built-in or in a scope which has finished) or simply + have more refined argument types than any declaration + found above. */ + struct c_binding *b; + for (b = I_SYMBOL_BINDING (DECL_NAME (decl1)); b; b = b->shadowed) + if (B_IN_SCOPE (b, external_scope)) + break; + if (b) + { + tree ext_decl, ext_type; + ext_decl = b->decl; + ext_type = b->type ? b->type : TREE_TYPE (ext_decl); + if (TREE_CODE (ext_type) == FUNCTION_TYPE + && comptypes (TREE_TYPE (TREE_TYPE (decl1)), + TREE_TYPE (ext_type))) + { + current_function_prototype_locus + = DECL_SOURCE_LOCATION (ext_decl); + current_function_prototype_built_in + = C_DECL_BUILTIN_PROTOTYPE (ext_decl); + current_function_prototype_arg_types + = TYPE_ARG_TYPES (ext_type); + } + } + } } /* Optionally warn of old-fashioned def with no previous prototype. */ if (warn_strict_prototypes + && old_decl != error_mark_node && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0 && C_DECL_ISNT_PROTOTYPE (old_decl)) - warning ("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 ("%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 - && old_decl != 0 && TREE_USED (old_decl) + && old_decl != 0 + && old_decl != error_mark_node + && TREE_USED (old_decl) && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0) - warning ("%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 ("%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 - && old_decl != 0 && TREE_USED (old_decl) + && old_decl != 0 + && old_decl != error_mark_node + && TREE_USED (old_decl) && C_DECL_IMPLICIT (old_decl)) - warning ("%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. @@ -5916,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 ("%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. @@ -5969,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 ("%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. */ @@ -6019,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 ("%Jtype of %qD defaults to %", decl, decl); + warning (OPT_Wextra, "%Jtype of %qD defaults to %", + decl, decl); } TREE_PURPOSE (parm) = decl; @@ -6082,11 +6233,11 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) set the DECL_ARG_TYPE of each argument according to the type previously specified, and report any mismatches. */ - if (TYPE_ARG_TYPES (TREE_TYPE (fndecl))) + if (current_function_prototype_arg_types) { tree type; for (parm = DECL_ARGUMENTS (fndecl), - type = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); + type = current_function_prototype_arg_types; parm || (type && (TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node)); parm = TREE_CHAIN (parm), type = TREE_CHAIN (type)) @@ -6094,9 +6245,15 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) if (parm == 0 || type == 0 || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node) { - error ("number of arguments doesn%'t match prototype"); - error ("%Hprototype declaration", - ¤t_function_prototype_locus); + if (current_function_prototype_built_in) + warning (0, "number of arguments doesn%'t match " + "built-in prototype"); + else + { + error ("number of arguments doesn%'t match prototype"); + error ("%Hprototype declaration", + ¤t_function_prototype_locus); + } break; } /* Type for passing arg must be consistent with that @@ -6123,17 +6280,33 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) if (pedantic) { - pedwarn ("promoted argument %qD " - "doesn%'t match prototype", parm); - pedwarn ("%Hprototype declaration", - ¤t_function_prototype_locus); + /* ??? Is it possible to get here with a + built-in prototype or will it always have + been diagnosed as conflicting with an + old-style definition and discarded? */ + if (current_function_prototype_built_in) + warning (0, "promoted argument %qD " + "doesn%'t match built-in prototype", parm); + else + { + pedwarn ("promoted argument %qD " + "doesn%'t match prototype", parm); + pedwarn ("%Hprototype declaration", + ¤t_function_prototype_locus); + } } } else { - error ("argument %qD doesn%'t match prototype", parm); - error ("%Hprototype declaration", - ¤t_function_prototype_locus); + if (current_function_prototype_built_in) + warning (0, "argument %qD doesn%'t match " + "built-in prototype", parm); + else + { + error ("argument %qD doesn%'t match prototype", parm); + error ("%Hprototype declaration", + ¤t_function_prototype_locus); + } } } } @@ -6276,6 +6449,9 @@ finish_function (void) { tree fndecl = current_function_decl; + label_context_stack_se = label_context_stack_se->next; + label_context_stack_vm = label_context_stack_vm->next; + if (TREE_CODE (fndecl) == FUNCTION_DECL && targetm.calls.promote_prototypes (TREE_TYPE (fndecl))) { @@ -6310,7 +6486,23 @@ finish_function (void) else { if (flag_isoc99) - c_finish_return (integer_zero_node); + { + tree stmt = c_finish_return (integer_zero_node); +#ifdef USE_MAPPED_LOCATION + /* 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 + annotate_one_with_locus. A cleaner solution might be to + ensure ! should_carry_locus_p (stmt), but that needs a flag. + */ + SET_EXPR_LOCATION (stmt, BUILTINS_LOCATION); +#else + /* Hack. We don't want the middle-end to warn that this + return is unreachable, so put the statement on the + special line 0. */ + annotate_with_file_line (stmt, input_filename, 0); +#endif + } } } @@ -6323,7 +6515,7 @@ finish_function (void) if (warn_return_type && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE && !current_function_returns_value && !current_function_returns_null - /* Don't complain if we abort. */ + /* Don't complain if we are no-return. */ && !current_function_returns_abnormally /* Don't warn for main(). */ && !MAIN_NAME_P (DECL_NAME (fndecl)) @@ -6332,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 ("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 ("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. */ @@ -6361,7 +6557,8 @@ finish_function (void) until their parent function is genericized. Since finalizing requires GENERIC, delay that as well. */ - if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node) + if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node + && !undef_nested_function) { if (!decl_function_context (fndecl)) { @@ -6387,6 +6584,9 @@ finish_function (void) } } + if (!decl_function_context (fndecl)) + undef_nested_function = false; + /* We're leaving the context of this function, so zap cfun. It's still in DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation. */ @@ -6556,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. */ @@ -6675,6 +6865,8 @@ build_id_declarator (tree ident) ret->kind = cdk_id; ret->declarator = 0; ret->u.id = ident; + /* Default value - may get reset to a more precise location. */ + ret->id_loc = input_location; return ret; } @@ -6716,6 +6908,8 @@ build_null_declspecs (void) ret->attrs = 0; ret->typespec_word = cts_none; ret->storage_class = csc_none; + ret->declspecs_seen_p = false; + ret->type_seen_p = false; ret->non_sc_seen_p = false; ret->typedef_p = false; ret->tag_defined_p = false; @@ -6745,6 +6939,7 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual) enum rid i; bool dupe = false; specs->non_sc_seen_p = true; + specs->declspecs_seen_p = true; gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (qual)); i = C_RID_CODE (qual); @@ -6766,7 +6961,7 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual) gcc_unreachable (); } if (dupe && pedantic && !flag_isoc99) - pedwarn ("duplicate %qs", IDENTIFIER_POINTER (qual)); + pedwarn ("duplicate %qE", qual); return specs; } @@ -6778,6 +6973,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) { tree type = spec.spec; specs->non_sc_seen_p = true; + specs->declspecs_seen_p = true; + specs->type_seen_p = true; if (TREE_DEPRECATED (type)) specs->deprecated_p = true; @@ -6915,7 +7112,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) } if (dupe) - error ("duplicate %qs", IDENTIFIER_POINTER (type)); + error ("duplicate %qE", type); return specs; } @@ -7044,8 +7241,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) { tree t = lookup_name (type); if (!t || TREE_CODE (t) != TYPE_DECL) - error ("%qs fails to be a typedef or built in type", - IDENTIFIER_POINTER (type)); + error ("%qE fails to be a typedef or built in type", type); else if (TREE_TYPE (t) == error_mark_node) ; else @@ -7072,12 +7268,12 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec) enum rid i; enum c_storage_class n = csc_none; bool dupe = false; + specs->declspecs_seen_p = true; gcc_assert (TREE_CODE (scspec) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (scspec)); i = C_RID_CODE (scspec); if (extra_warnings && specs->non_sc_seen_p) - warning ("%qs is not at beginning of declaration", - IDENTIFIER_POINTER (scspec)); + warning (OPT_Wextra, "%qE is not at beginning of declaration", scspec); switch (i) { case RID_INLINE: @@ -7126,7 +7322,7 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec) if (n != csc_none && n == specs->storage_class) dupe = true; if (dupe) - error ("duplicate %qs", IDENTIFIER_POINTER (scspec)); + error ("duplicate %qE", scspec); if (n != csc_none) { if (specs->storage_class != csc_none && n != specs->storage_class) @@ -7138,8 +7334,7 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec) specs->storage_class = n; if (n != csc_extern && n != csc_static && specs->thread_p) { - error ("%<__thread%> used with %qs", - IDENTIFIER_POINTER (scspec)); + error ("%<__thread%> used with %qE", scspec); specs->thread_p = false; } } @@ -7154,6 +7349,7 @@ struct c_declspecs * declspecs_add_attrs (struct c_declspecs *specs, tree attrs) { specs->attrs = chainon (attrs, specs->attrs); + specs->declspecs_seen_p = true; return specs; }