X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-decl.c;h=af038e1783aaa4b129b21efeb733d60b753ef03e;hb=9702264ef825c6e62581a8a2daf2c5405e480bbf;hp=b594767d04c48835f7570efc48d1c4f390c49f66;hpb=bfec3452cfb96a7546809ee1af3fffb9eba9d658;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-decl.c b/gcc/c-decl.c index b594767d04c..af038e1783a 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, 2009 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -38,10 +38,8 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "function.h" #include "output.h" -#include "expr.h" #include "c-tree.h" #include "toplev.h" -#include "ggc.h" #include "tm_p.h" #include "cpplib.h" #include "target.h" @@ -50,19 +48,16 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "c-common.h" #include "c-pragma.h" +#include "c-lang.h" #include "langhooks.h" #include "tree-mudflap.h" -#include "gimple.h" #include "tree-iterator.h" #include "diagnostic.h" #include "tree-dump.h" #include "cgraph.h" #include "hashtab.h" -#include "libfuncs.h" -#include "except.h" #include "langhooks-def.h" #include "pointer-set.h" -#include "gimple.h" #include "plugin.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ @@ -91,9 +86,6 @@ tree pending_invalid_xref; /* File and line to appear in the eventual error message. */ location_t pending_invalid_xref_location; -/* True means we've initialized exception handling. */ -bool c_eh_initialized_p; - /* The file and line that the prototype came from if this is an old-style definition; used for diagnostics in store_parm_decls_oldstyle. */ @@ -578,7 +570,7 @@ c_print_identifier (FILE *file, tree node, int indent) { tree rid = ridpointers[C_RID_CODE (node)]; indent_to (file, indent + 4); - fprintf (file, "rid %p \"%s\"", + fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"", (void *) rid, IDENTIFIER_POINTER (rid)); } } @@ -1104,7 +1096,7 @@ pop_scope (void) error ("label %q+D used but not defined", p); DECL_INITIAL (p) = error_mark_node; } - else + else warn_for_unused_label (p); /* Labels go in BLOCK_VARS. */ @@ -1166,14 +1158,21 @@ pop_scope (void) case VAR_DECL: /* Warnings for unused variables. */ - if (!TREE_USED (p) + if ((!TREE_USED (p) || !DECL_READ_P (p)) && !TREE_NO_WARNING (p) && !DECL_IN_SYSTEM_HEADER (p) && DECL_NAME (p) && !DECL_ARTIFICIAL (p) && scope != file_scope && scope != external_scope) - warning (OPT_Wunused_variable, "unused variable %q+D", p); + { + if (!TREE_USED (p)) + warning (OPT_Wunused_variable, "unused variable %q+D", p); + else if (DECL_CONTEXT (p) == current_function_decl) + warning_at (DECL_SOURCE_LOCATION (p), + OPT_Wunused_but_set_variable, + "variable %qD set but not used", p); + } if (b->inner_comp) { @@ -1748,8 +1747,35 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } else { - if (TYPE_QUALS (newtype) != TYPE_QUALS (oldtype)) - error ("conflicting type qualifiers for %q+D", newdecl); + int new_quals = TYPE_QUALS (newtype); + int old_quals = TYPE_QUALS (oldtype); + + if (new_quals != old_quals) + { + addr_space_t new_addr = DECODE_QUAL_ADDR_SPACE (new_quals); + addr_space_t old_addr = DECODE_QUAL_ADDR_SPACE (old_quals); + if (new_addr != old_addr) + { + if (ADDR_SPACE_GENERIC_P (new_addr)) + error ("conflicting named address spaces (generic vs %s) " + "for %q+D", + c_addr_space_name (old_addr), newdecl); + else if (ADDR_SPACE_GENERIC_P (old_addr)) + error ("conflicting named address spaces (%s vs generic) " + "for %q+D", + c_addr_space_name (new_addr), newdecl); + else + error ("conflicting named address spaces (%s vs %s) " + "for %q+D", + c_addr_space_name (new_addr), + c_addr_space_name (old_addr), + newdecl); + } + + if (CLEAR_QUAL_ADDR_SPACE (new_quals) + != CLEAR_QUAL_ADDR_SPACE (old_quals)) + error ("conflicting type qualifiers for %q+D", newdecl); + } else error ("conflicting types for %q+D", newdecl); diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype); @@ -1872,7 +1898,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } else if (warn_traditional) { - warned |= warning (OPT_Wtraditional, + warned |= warning (OPT_Wtraditional, "non-static declaration of %q+D " "follows static declaration", newdecl); } @@ -1950,7 +1976,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } else if (warn_traditional) { - warned |= warning (OPT_Wtraditional, + warned |= warning (OPT_Wtraditional, "non-static declaration of %q+D " "follows static declaration", newdecl); } @@ -2021,14 +2047,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (DECL_DECLARED_INLINE_P (newdecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) { - warned |= warning (OPT_Wattributes, + warned |= warning (OPT_Wattributes, "inline declaration of %qD follows " "declaration with attribute noinline", newdecl); } else if (DECL_DECLARED_INLINE_P (olddecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) { - warned |= warning (OPT_Wattributes, + warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute " "noinline follows inline declaration ", newdecl); } @@ -2343,7 +2369,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) 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) = copy_list (DECL_ARGUMENTS (olddecl)); for (t = DECL_ARGUMENTS (newdecl); t ; t = TREE_CHAIN (t)) DECL_CONTEXT (t) = newdecl; @@ -2362,9 +2387,16 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) TREE_USED (newdecl) = 1; else if (TREE_USED (newdecl)) TREE_USED (olddecl) = 1; + if (TREE_CODE (olddecl) == VAR_DECL || TREE_CODE (olddecl) == PARM_DECL) + DECL_READ_P (newdecl) |= DECL_READ_P (olddecl); + if (DECL_PRESERVE_P (olddecl)) + DECL_PRESERVE_P (newdecl) = 1; + else if (DECL_PRESERVE_P (newdecl)) + DECL_PRESERVE_P (olddecl) = 1; /* Copy most of the decl-specific fields of NEWDECL into OLDDECL. - But preserve OLDDECL's DECL_UID and DECL_CONTEXT. */ + But preserve OLDDECL's DECL_UID, DECL_CONTEXT and + DECL_ARGUMENTS (if appropriate). */ { unsigned olddecl_uid = DECL_UID (olddecl); tree olddecl_context = DECL_CONTEXT (olddecl); @@ -2378,9 +2410,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) switch (TREE_CODE (olddecl)) { case FUNCTION_DECL: - gimple_set_body (olddecl, gimple_body (newdecl)); - /* fall through */ - case FIELD_DECL: case VAR_DECL: case PARM_DECL: @@ -2786,8 +2815,8 @@ implicit_decl_warning (tree id, tree olddecl) if (flag_isoc99) warned = pedwarn (input_location, OPT_Wimplicit_function_declaration, "implicit declaration of function %qE", id); - else - warned = warning (OPT_Wimplicit_function_declaration, + else + warned = warning (OPT_Wimplicit_function_declaration, G_("implicit declaration of function %qE"), id); if (olddecl && warned) locate_old_decl (olddecl); @@ -2919,11 +2948,10 @@ undeclared_variable (location_t loc, tree id) else { error_at (loc, "%qE undeclared (first use in this function)", id); - if (!already) { - error_at (loc, "(Each undeclared identifier is reported only once"); - error_at (loc, "for each function it appears in.)"); + inform (loc, "each undeclared identifier is reported only" + " once for each function it appears in"); already = true; } @@ -3416,7 +3444,7 @@ c_init_decl_processing (void) using preprocessed headers. */ input_location = BUILTINS_LOCATION; - build_common_tree_nodes (flag_signed_char, false); + build_common_tree_nodes (flag_signed_char); c_common_nodes_and_builtins (); @@ -3471,10 +3499,10 @@ c_make_fname_decl (location_t loc, tree id, int type_dep) if (current_function_decl /* For invalid programs like this: - + void foo() const char* p = __FUNCTION__; - + the __FUNCTION__ is believed to appear in K&R style function parameter declarator. In that case we still don't have function_scope. */ @@ -3606,7 +3634,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) else if (!declspecs->tag_defined_p && (declspecs->const_p || declspecs->volatile_p - || declspecs->restrict_p)) + || declspecs->restrict_p + || declspecs->address_space)) { if (warned != 1) pedwarn (input_location, 0, @@ -3677,7 +3706,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) if (!warned && !in_system_header && (declspecs->const_p || declspecs->volatile_p - || declspecs->restrict_p)) + || declspecs->restrict_p + || declspecs->address_space)) { warning (0, "useless type qualifier in empty declaration"); warned = 2; @@ -3700,7 +3730,8 @@ quals_from_declspecs (const struct c_declspecs *specs) { int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0) | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0) - | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0)); + | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0) + | (ENCODE_QUAL_ADDR_SPACE (specs->address_space))); gcc_assert (!specs->type && !specs->decl_attr && specs->typespec_word == cts_none @@ -4042,23 +4073,6 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, return tem; } -/* Initialize EH if not initialized yet and exceptions are enabled. */ - -void -c_maybe_initialize_eh (void) -{ - if (!flag_exceptions || c_eh_initialized_p) - return; - - c_eh_initialized_p = true; - eh_personality_libfunc - = init_one_libfunc (USING_SJLJ_EXCEPTIONS - ? "__gcc_personality_sj0" - : "__gcc_personality_v0"); - default_init_unwind_resume_libfunc (); - using_eh_for_cleanups (); -} - /* Finish processing of a declaration; install its initial value. If ORIGTYPE is not NULL_TREE, it is the original type of INIT. @@ -4082,6 +4096,13 @@ finish_decl (tree decl, location_t init_loc, tree init, if (asmspec_tree) asmspec = TREE_STRING_POINTER (asmspec_tree); + if (TREE_CODE (decl) == VAR_DECL + && TREE_STATIC (decl) + && global_bindings_p ()) + /* So decl is a global variable. Record the types it uses + so that we can decide later to emit debug info for them. */ + record_types_used_by_current_var_decl (decl); + /* If `start_decl' didn't like having an initialization, ignore it now. */ if (init != 0 && DECL_INITIAL (decl) == 0) init = 0; @@ -4210,7 +4231,10 @@ finish_decl (tree decl, location_t init_loc, tree init, } if (TREE_USED (type)) - TREE_USED (decl) = 1; + { + TREE_USED (decl) = 1; + DECL_READ_P (decl) = 1; + } } /* If this is a function and an assembler name is specified, reset DECL_RTL @@ -4358,9 +4382,7 @@ finish_decl (tree decl, location_t init_loc, tree init, /* Don't warn about decl unused; the cleanup uses it. */ TREE_USED (decl) = 1; TREE_USED (cleanup_decl) = 1; - - /* Initialize EH, if we've been told to do so. */ - c_maybe_initialize_eh (); + DECL_READ_P (decl) = 1; push_cleanup (decl, cleanup, false); } @@ -4443,7 +4465,8 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const) tree complit; tree stmt; - if (type == error_mark_node) + if (type == error_mark_node + || init == error_mark_node) return error_mark_node; decl = build_decl (loc, VAR_DECL, NULL_TREE, type); @@ -4452,6 +4475,7 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const) TREE_STATIC (decl) = (current_scope == file_scope); DECL_CONTEXT (decl) = current_function_decl; TREE_USED (decl) = 1; + DECL_READ_P (decl) = 1; TREE_TYPE (decl) = type; TREE_READONLY (decl) = TYPE_READONLY (type); store_init_value (loc, decl, init, NULL_TREE); @@ -4554,14 +4578,26 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name) /* Detect and ignore out of range field width and process valid field widths. */ - if (!INTEGRAL_TYPE_P (TREE_TYPE (*width)) - || TREE_CODE (*width) != INTEGER_CST) + if (!INTEGRAL_TYPE_P (TREE_TYPE (*width))) { error ("bit-field %qs width not an integer constant", name); *width = integer_one_node; } else { + if (TREE_CODE (*width) != INTEGER_CST) + { + *width = c_fully_fold (*width, false, NULL); + if (TREE_CODE (*width) == INTEGER_CST) + pedwarn (input_location, OPT_pedantic, + "bit-field %qs width not an integer constant expression", + name); + } + if (TREE_CODE (*width) != INTEGER_CST) + { + error ("bit-field %qs width not an integer constant", name); + *width = integer_one_node; + } constant_expression_warning (*width); if (tree_int_cst_sgn (*width) < 0) { @@ -4637,7 +4673,7 @@ warn_variable_length_array (tree name, tree size) } else { - if (name) + if (name) pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array %qE", name); @@ -4764,6 +4800,7 @@ grokdeclarator (const struct c_declarator *declarator, bool bitfield = width != NULL; tree element_type; struct c_arg_info *arg_info = 0; + addr_space_t as1, as2, address_space; location_t loc = UNKNOWN_LOCATION; const char *errmsg; tree expr_dummy; @@ -4863,11 +4900,11 @@ grokdeclarator (const struct c_declarator *declarator, else { if (name) - pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wimplicit_int, + pedwarn_c99 (loc, 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, + pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, "type defaults to % in type name"); } } @@ -4894,6 +4931,10 @@ grokdeclarator (const struct c_declarator *declarator, constp = declspecs->const_p + TYPE_READONLY (element_type); restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type); volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type); + as1 = declspecs->address_space; + as2 = TYPE_ADDR_SPACE (element_type); + address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1; + if (pedantic && !flag_isoc99) { if (constp > 1) @@ -4903,11 +4944,17 @@ grokdeclarator (const struct c_declarator *declarator, if (volatilep > 1) pedwarn (loc, OPT_pedantic, "duplicate %"); } + + if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2) + error_at (loc, "conflicting named address spaces (%s vs %s)", + c_addr_space_name (as1), c_addr_space_name (as2)); + 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) - | (volatilep ? TYPE_QUAL_VOLATILE : 0)); + | (volatilep ? TYPE_QUAL_VOLATILE : 0) + | ENCODE_QUAL_ADDR_SPACE (address_space)); /* Warn about storage classes that are invalid for certain kinds of declarations (parameters, typenames, etc.). */ @@ -4919,8 +4966,8 @@ grokdeclarator (const struct c_declarator *declarator, || storage_class == csc_typedef)) { if (storage_class == csc_auto) - pedwarn (loc, - (current_scope == file_scope) ? 0 : OPT_pedantic, + pedwarn (loc, + (current_scope == file_scope) ? 0 : OPT_pedantic, "function definition declared %"); if (storage_class == csc_register) error_at (loc, "function definition declared %"); @@ -5323,7 +5370,14 @@ grokdeclarator (const struct c_declarator *declarator, it, but here we want to make sure we don't ever modify the shared type, so we gcc_assert (itype) below. */ - type = build_array_type (type, itype); + { + addr_space_t as = DECODE_QUAL_ADDR_SPACE (type_quals); + if (!ADDR_SPACE_GENERIC_P (as) && as != TYPE_ADDR_SPACE (type)) + type = build_qualified_type (type, + ENCODE_QUAL_ADDR_SPACE (as)); + + type = build_array_type (type, itype); + } if (type != error_mark_node) { @@ -5348,6 +5402,7 @@ grokdeclarator (const struct c_declarator *declarator, gcc_assert (itype); TYPE_SIZE (type) = bitsize_zero_node; TYPE_SIZE_UNIT (type) = size_zero_node; + SET_TYPE_STRUCTURAL_EQUALITY (type); } if (array_parm_vla_unspec_p) { @@ -5355,6 +5410,7 @@ grokdeclarator (const struct c_declarator *declarator, /* The type is complete. C99 6.7.5.2p4 */ TYPE_SIZE (type) = bitsize_zero_node; TYPE_SIZE_UNIT (type) = size_zero_node; + SET_TYPE_STRUCTURAL_EQUALITY (type); } } @@ -5529,6 +5585,59 @@ grokdeclarator (const struct c_declarator *declarator, /* Now TYPE has the actual type, apart from any qualifiers in TYPE_QUALS. */ + /* Warn about address space used for things other than static memory or + pointers. */ + address_space = DECODE_QUAL_ADDR_SPACE (type_quals); + if (!ADDR_SPACE_GENERIC_P (address_space)) + { + if (decl_context == NORMAL) + { + switch (storage_class) + { + case csc_auto: + error ("%qs combined with % qualifier for %qE", + c_addr_space_name (address_space), name); + break; + case csc_register: + error ("%qs combined with % qualifier for %qE", + c_addr_space_name (address_space), name); + break; + case csc_none: + if (current_function_scope) + { + error ("%qs specified for auto variable %qE", + c_addr_space_name (address_space), name); + break; + } + break; + case csc_static: + case csc_extern: + case csc_typedef: + break; + default: + gcc_unreachable (); + } + } + else if (decl_context == PARM && TREE_CODE (type) != ARRAY_TYPE) + { + if (name) + error ("%qs specified for parameter %qE", + c_addr_space_name (address_space), name); + else + error ("%qs specified for unnamed parameter", + c_addr_space_name (address_space)); + } + else if (decl_context == FIELD) + { + if (name) + error ("%qs specified for structure field %qE", + c_addr_space_name (address_space), name); + else + error ("%qs specified for structure field", + c_addr_space_name (address_space)); + } + } + /* Check the type and width of a bit-field. */ if (bitfield) check_bitfield_type_and_width (&type, width, name); @@ -6013,6 +6122,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) TREE_VALUE (typelt) = error_mark_node; TREE_TYPE (parm) = error_mark_node; + arg_types = NULL_TREE; } else if (VOID_TYPE_P (type)) { @@ -6033,6 +6143,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) error (errmsg); TREE_VALUE (typelt) = error_mark_node; TREE_TYPE (parm) = error_mark_node; + arg_types = NULL_TREE; } if (DECL_NAME (parm) && TREE_USED (parm)) @@ -6196,6 +6307,11 @@ get_parm_info (bool ellipsis) type itself. FUNCTION_DECLs appear when there is an implicit function declaration in the parameter list. */ + /* When we reinsert this decl in the function body, we need + to reconstruct whether it was marked as nested. */ + gcc_assert (TREE_CODE (decl) == FUNCTION_DECL + ? b->nested + : !b->nested); TREE_CHAIN (decl) = others; others = decl; /* fall through */ @@ -6441,6 +6557,8 @@ grokfield (location_t loc, Otherwise this is a forward declaration of a structure tag. If this is something of the form "foo;" and foo is a TYPE_DECL, then + If foo names a structure or union without a tag, then this + is an anonymous struct (this is permitted by C1X). If MS extensions are enabled and foo names a structure, then again this is an anonymous struct. Otherwise this is an error. @@ -6454,14 +6572,11 @@ grokfield (location_t loc, || TREE_CODE (type) == UNION_TYPE); bool ok = false; - if (type_ok - && (flag_ms_extensions || !declspecs->typedef_p)) + if (type_ok) { if (flag_ms_extensions) ok = true; - else if (flag_iso) - ok = false; - else if (TYPE_NAME (type) == NULL) + else if (TYPE_NAME (TYPE_MAIN_VARIANT (type)) == NULL) ok = true; else ok = false; @@ -6471,7 +6586,15 @@ grokfield (location_t loc, pedwarn (loc, 0, "declaration does not declare anything"); return NULL_TREE; } - pedwarn (loc, OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions"); + if (!flag_isoc1x) + { + if (flag_isoc99) + pedwarn (loc, OPT_pedantic, + "ISO C99 doesn%'t support unnamed structs/unions"); + else + pedwarn (loc, OPT_pedantic, + "ISO C90 doesn%'t support unnamed structs/unions"); + } } value = grokdeclarator (declarator, declspecs, FIELD, false, @@ -6503,6 +6626,31 @@ grokfield (location_t loc, return value; } +/* Subroutine of detect_field_duplicates: add the fields of FIELDLIST + to HTAB, giving errors for any duplicates. */ + +static void +detect_field_duplicates_hash (tree fieldlist, htab_t htab) +{ + tree x, y; + void **slot; + + for (x = fieldlist; x ; x = TREE_CHAIN (x)) + if ((y = DECL_NAME (x)) != 0) + { + slot = htab_find_slot (htab, y, INSERT); + if (*slot) + { + error ("duplicate member %q+D", x); + DECL_NAME (x) = NULL_TREE; + } + *slot = y; + } + else if (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE) + detect_field_duplicates_hash (TYPE_FIELDS (TREE_TYPE (x)), htab); +} + /* Generate an error for any duplicate field names in FIELDLIST. Munge the list such that this does not present a problem later. */ @@ -6521,11 +6669,16 @@ detect_field_duplicates (tree fieldlist) return; do { timeout--; + if (DECL_NAME (x) == NULL_TREE + && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)) + timeout = 0; x = TREE_CHAIN (x); } while (timeout > 0 && x); - /* If there were "few" fields, avoid the overhead of allocating - a hash table. Instead just do the nested traversal thing. */ + /* If there were "few" fields and no anonymous structures or unions, + avoid the overhead of allocating a hash table. Instead just do + the nested traversal thing. */ if (timeout > 0) { for (x = TREE_CHAIN (fieldlist); x ; x = TREE_CHAIN (x)) @@ -6542,20 +6695,8 @@ detect_field_duplicates (tree fieldlist) else { htab_t htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL); - void **slot; - - for (x = fieldlist; x ; x = TREE_CHAIN (x)) - if ((y = DECL_NAME (x)) != 0) - { - slot = htab_find_slot (htab, y, INSERT); - if (*slot) - { - error ("duplicate member %q+D", x); - DECL_NAME (x) = NULL_TREE; - } - *slot = y; - } + detect_field_duplicates_hash (fieldlist, htab); htab_delete (htab); } } @@ -6645,8 +6786,14 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, if (pedantic) { for (x = fieldlist; x; x = TREE_CHAIN (x)) - if (DECL_NAME (x) != 0) - break; + { + if (DECL_NAME (x) != 0) + break; + if (flag_isoc1x + && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)) + break; + } if (x == 0) { @@ -6746,10 +6893,12 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, if (pedantic && TREE_CODE (t) == RECORD_TYPE && flexible_array_type_p (TREE_TYPE (x))) - pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic, + pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic, "invalid use of structure with flexible array member"); - if (DECL_NAME (x)) + if (DECL_NAME (x) + || TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE) saw_named_field = 1; } @@ -6852,10 +7001,10 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, /* If this was supposed to be a transparent union, but we can't make it one, warn and turn off the flag. */ if (TREE_CODE (t) == UNION_TYPE - && TYPE_TRANSPARENT_UNION (t) + && TYPE_TRANSPARENT_AGGR (t) && (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t)))) { - TYPE_TRANSPARENT_UNION (t) = 0; + TYPE_TRANSPARENT_AGGR (t) = 0; warning_at (loc, 0, "union cannot be made transparent"); } @@ -6880,6 +7029,11 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, } C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0; + /* Update type location to the one of the definition, instead of e.g. + a forward declaration. */ + if (TYPE_STUB_DECL (t)) + DECL_SOURCE_LOCATION (TYPE_STUB_DECL (t)) = loc; + /* Finish debugging output for this type. */ rest_of_type_compilation (t, toplevel); @@ -7192,7 +7346,7 @@ build_enumerator (location_t loc, (6.4.4.3/2 in the C99 Standard). GCC allows any integer type as an extension. */ else if (!int_fits_type_p (value, integer_type_node)) - pedwarn (loc, OPT_pedantic, + pedwarn (loc, OPT_pedantic, "ISO C restricts enumerator values to range of %"); /* The ISO C Standard mandates enumerators to have type int, even @@ -7304,7 +7458,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, } if (warn_about_return_type) - pedwarn_c99 (loc, flag_isoc99 ? 0 + pedwarn_c99 (loc, flag_isoc99 ? 0 : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int), "return type defaults to %"); @@ -7312,6 +7466,10 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, error_mark_node is replaced below (in pop_scope) with the BLOCK. */ DECL_INITIAL (decl1) = error_mark_node; + /* A nested function is not global. */ + if (current_function_decl != 0) + TREE_PUBLIC (decl1) = 0; + /* 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); @@ -7412,10 +7570,6 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, (This does not mean `static' in the C sense!) */ TREE_STATIC (decl1) = 1; - /* A nested function is not global. */ - if (current_function_decl != 0) - TREE_PUBLIC (decl1) = 0; - /* This is the earliest point at which we might know the assembler name of the function. Thus, if it's set before this, die horribly. */ gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl1)); @@ -7512,7 +7666,9 @@ 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, UNKNOWN_LOCATION); + /*invisible=*/false, + /*nested=*/(TREE_CODE (decl) == FUNCTION_DECL), + UNKNOWN_LOCATION); } /* And all the tag declarations. */ @@ -7601,7 +7757,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) if (flag_isoc99) pedwarn (DECL_SOURCE_LOCATION (decl), 0, "type of %qD defaults to %", decl); - else + else warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wmissing_parameter_type, "type of %qD defaults to %", decl); @@ -7857,9 +8013,12 @@ store_parm_decls (void) thus won't naturally see the SAVE_EXPR containing the increment. All other pending sizes would be handled by gimplify_parameters. */ { + VEC(tree,gc) *pending_sizes = get_pending_sizes (); tree t; - for (t = nreverse (get_pending_sizes ()); t ; t = TREE_CHAIN (t)) - add_stmt (TREE_VALUE (t)); + int i; + + for (i = 0; VEC_iterate (tree, pending_sizes, i, t); i++) + add_stmt (t); } /* Even though we're inside a function body, we still don't want to @@ -7926,6 +8085,8 @@ finish_function (void) && !current_function_returns_value && !current_function_returns_null /* Don't complain if we are no-return. */ && !current_function_returns_abnormally + /* Don't complain if we are declared noreturn. */ + && !TREE_THIS_VOLATILE (fndecl) /* Don't warn for main(). */ && !MAIN_NAME_P (DECL_NAME (fndecl)) /* Or if they didn't actually specify a return type. */ @@ -7939,6 +8100,25 @@ finish_function (void) TREE_NO_WARNING (fndecl) = 1; } + /* Complain about parameters that are only set, but never otherwise used. */ + if (warn_unused_but_set_parameter) + { + tree decl; + + for (decl = DECL_ARGUMENTS (fndecl); + decl; + decl = TREE_CHAIN (decl)) + if (TREE_USED (decl) + && TREE_CODE (decl) == PARM_DECL + && !DECL_READ_P (decl) + && DECL_NAME (decl) + && !DECL_ARTIFICIAL (decl) + && !TREE_NO_WARNING (decl)) + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wunused_but_set_parameter, + "parameter %qD set but not used", decl); + } + /* Store the end of the function, so that we get good line number info for the epilogue. */ cfun->function_end_locus = input_location; @@ -7947,7 +8127,7 @@ finish_function (void) c_determine_visibility (fndecl); /* For GNU C extern inline functions disregard inline limits. */ - if (DECL_EXTERNAL (fndecl) + if (DECL_EXTERNAL (fndecl) && DECL_DECLARED_INLINE_P (fndecl)) DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1; @@ -7960,6 +8140,7 @@ finish_function (void) { if (!decl_function_context (fndecl)) { + invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl); c_genericize (fndecl); /* ??? Objc emits functions after finalizing the compilation unit. @@ -8136,21 +8317,6 @@ c_pop_function_context (void) warn_about_return_type = p->warn_about_return_type; } -/* Copy the DECL_LANG_SPECIFIC data associated with DECL. */ - -void -c_dup_lang_specific_decl (tree decl) -{ - struct lang_decl *ld; - - if (!DECL_LANG_SPECIFIC (decl)) - return; - - ld = GGC_NEW (struct lang_decl); - memcpy (ld, DECL_LANG_SPECIFIC (decl), sizeof (struct lang_decl)); - DECL_LANG_SPECIFIC (decl) = ld; -} - /* The functions below are required for functionality of doing function at once processing in the C front end. Currently these functions are not called from anywhere in the C front end, but as @@ -8321,9 +8487,29 @@ build_null_declspecs (void) ret->volatile_p = false; ret->restrict_p = false; ret->saturating_p = false; + ret->address_space = ADDR_SPACE_GENERIC; return ret; } +/* Add the address space ADDRSPACE to the declaration specifiers + SPECS, returning SPECS. */ + +struct c_declspecs * +declspecs_add_addrspace (struct c_declspecs *specs, addr_space_t as) +{ + specs->non_sc_seen_p = true; + specs->declspecs_seen_p = true; + + if (!ADDR_SPACE_GENERIC_P (specs->address_space) + && specs->address_space != as) + error ("incompatible address space qualifiers %qs and %qs", + c_addr_space_name (as), + c_addr_space_name (specs->address_space)); + else + specs->address_space = as; + return specs; +} + /* Add the type qualifier QUAL to the declaration specifiers SPECS, returning SPECS. */ @@ -8799,7 +8985,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, case RID_DFLOAT32: case RID_DFLOAT64: case RID_DFLOAT128: - { + { const char *str; if (i == RID_DFLOAT32) str = "_Decimal32"; @@ -8968,7 +9154,7 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec) && C_IS_RESERVED_WORD (scspec)); i = C_RID_CODE (scspec); if (specs->non_sc_seen_p) - warning (OPT_Wold_style_declaration, + warning (OPT_Wold_style_declaration, "%qE is not at beginning of declaration", scspec); switch (i) { @@ -9090,7 +9276,7 @@ finish_declspecs (struct c_declspecs *specs) else if (specs->complex_p) { specs->typespec_word = cts_double; - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "ISO C does not support plain % meaning " "%"); } @@ -9135,7 +9321,7 @@ finish_declspecs (struct c_declspecs *specs) specs->type = char_type_node; if (specs->complex_p) { - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "ISO C does not support complex integer types"); specs->type = build_complex_type (specs->type); } @@ -9161,7 +9347,7 @@ finish_declspecs (struct c_declspecs *specs) : integer_type_node); if (specs->complex_p) { - pedwarn (input_location, OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "ISO C does not support complex integer types"); specs->type = build_complex_type (specs->type); }