X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-decl.c;h=0c05b2438b91a64758e31d2455ddd3c895451cf4;hb=e80c6822beb7e2c86a1c4abf8658af24e68b8df2;hp=3c47c171a9e21ddc443507daee96de0485f6f740;hpb=8864917d6666af0c2929572fd255b1cbeb7be8ff;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 3c47c171a9e..0c05b2438b9 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -52,7 +52,8 @@ along with GCC; see the file COPYING3. If not see #include "c-pragma.h" #include "langhooks.h" #include "tree-mudflap.h" -#include "tree-gimple.h" +#include "gimple.h" +#include "tree-iterator.h" #include "diagnostic.h" #include "tree-dump.h" #include "cgraph.h" @@ -61,6 +62,8 @@ along with GCC; see the file COPYING3. If not see #include "except.h" #include "langhooks-def.h" #include "pointer-set.h" +#include "gimple.h" +#include "plugin.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -123,6 +126,15 @@ static GTY(()) struct stmt_tree_s c_stmt_tree; tree c_break_label; tree c_cont_label; +/* True if we are currently parsing the fields of a struct or + union. */ + +static bool in_struct; + +/* A list of types defined in the current struct or union. */ + +static VEC(tree,heap) *struct_types; + /* Linked list of TRANSLATION_UNIT_DECLS for the translation units included in this invocation. Note that the current translation unit is not included in this list. */ @@ -195,8 +207,7 @@ bool c_override_global_bindings_to_false; in all such cases, the binding in the outer scope will have its invisible bit true. */ -struct c_binding GTY((chain_next ("%h.prev"))) -{ +struct GTY((chain_next ("%h.prev"))) c_binding { tree decl; /* the decl bound */ tree type; /* the type in this scope */ tree id; /* the identifier it's bound to */ @@ -207,6 +218,7 @@ struct c_binding GTY((chain_next ("%h.prev"))) BOOL_BITFIELD nested : 1; /* do not set DECL_CONTEXT when popping */ BOOL_BITFIELD inner_comp : 1; /* incomplete array completed in inner scope */ /* one free bit */ + location_t locus; /* location for nested bindings */ }; #define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth) #define B_IN_CURRENT_SCOPE(b) ((b)->depth == current_scope->depth) @@ -232,8 +244,7 @@ struct c_binding GTY((chain_next ("%h.prev"))) These describe the values of the identifier in the three different namespaces defined by the language. */ -struct lang_identifier GTY(()) -{ +struct GTY(()) lang_identifier { struct c_common_identifier common_id; struct c_binding *symbol_binding; /* vars, funcs, constants, typedefs */ struct c_binding *tag_binding; /* struct/union/enum tags */ @@ -246,10 +257,9 @@ extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate /* The resulting tree type. */ -union lang_tree_node - GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), - chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) GENERIC_NEXT (&%h.generic))"))) -{ +union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), + chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))"))) lang_tree_node + { union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic; @@ -301,8 +311,7 @@ union lang_tree_node pop_scope relies on this. */ -struct c_scope GTY((chain_next ("%h.outer"))) -{ +struct GTY((chain_next ("%h.outer"))) c_scope { /* The scope containing this one. */ struct c_scope *outer; @@ -342,6 +351,9 @@ struct c_scope GTY((chain_next ("%h.outer"))) /* True means make a BLOCK for this scope no matter what. */ BOOL_BITFIELD keep : 1; + + /* True means that an unsuffixed float constant is _Decimal64. */ + BOOL_BITFIELD float_const_decimal64 : 1; }; /* The scope currently in effect. */ @@ -393,6 +405,32 @@ static GTY((deletable)) struct c_binding *binding_freelist; t_->to##_last = f_->from##_last; \ } while (0) +/* A c_inline_static structure stores details of a static identifier + referenced in a definition of a function that may be an inline + definition if no subsequent declaration of that function uses + "extern" or does not use "inline". */ + +struct GTY((chain_next ("%h.next"))) c_inline_static { + /* The location for a diagnostic. */ + location_t location; + + /* The function that may be an inline definition. */ + tree function; + + /* The object or function referenced. */ + tree static_decl; + + /* What sort of reference this is. */ + enum c_inline_static_type type; + + /* The next such structure or NULL. */ + struct c_inline_static *next; +}; + +/* List of static identifiers used or referenced in functions that may + be inline definitions. */ +static GTY(()) struct c_inline_static *c_inline_statics; + /* True means unconditionally make a BLOCK for the next scope pushed. */ static bool keep_next_level_flag; @@ -408,8 +446,8 @@ static tree lookup_name_in_scope (tree, struct c_scope *); static tree c_make_fname_decl (tree, int); static tree grokdeclarator (const struct c_declarator *, struct c_declspecs *, - enum decl_context, bool, tree *, tree *, - enum deprecated_states); + enum decl_context, bool, tree *, tree *, tree *, + bool *, enum deprecated_states); static tree grokparms (struct c_arg_info *, bool); static void layout_array_type (tree); @@ -458,7 +496,8 @@ c_print_identifier (FILE *file, tree node, int indent) which may be any of several kinds of DECL or TYPE or error_mark_node, in the scope SCOPE. */ static void -bind (tree name, tree decl, struct c_scope *scope, bool invisible, bool nested) +bind (tree name, tree decl, struct c_scope *scope, bool invisible, + bool nested, location_t locus) { struct c_binding *b, **here; @@ -477,6 +516,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible, bool nested) b->invisible = invisible; b->nested = nested; b->inner_comp = 0; + b->locus = locus; b->type = 0; @@ -553,6 +593,53 @@ c_finish_incomplete_decl (tree decl) } } +/* Record that inline function FUNC contains a reference (location + LOC) to static DECL (file-scope or function-local according to + TYPE). */ + +void +record_inline_static (location_t loc, tree func, tree decl, + enum c_inline_static_type type) +{ + struct c_inline_static *csi = GGC_NEW (struct c_inline_static); + csi->location = loc; + csi->function = func; + csi->static_decl = decl; + csi->type = type; + csi->next = c_inline_statics; + c_inline_statics = csi; +} + +/* Check for references to static declarations in inline functions at + the end of the translation unit and diagnose them if the functions + are still inline definitions. */ + +static void +check_inline_statics (void) +{ + struct c_inline_static *csi; + for (csi = c_inline_statics; csi; csi = csi->next) + { + if (DECL_EXTERNAL (csi->function)) + switch (csi->type) + { + case csi_internal: + pedwarn (csi->location, 0, + "%qD is static but used in inline function %qD " + "which is not static", csi->static_decl, csi->function); + break; + case csi_modifiable: + pedwarn (csi->location, 0, + "%q+D is static but declared in inline function %qD " + "which is not static", csi->static_decl, csi->function); + break; + default: + gcc_unreachable (); + } + } + c_inline_statics = NULL; +} + /* The Objective-C front-end often needs to determine the current scope. */ void * @@ -588,7 +675,9 @@ objc_mark_locals_volatile (void *enclosing_blk) int global_bindings_p (void) { - return current_scope == file_scope && !c_override_global_bindings_to_false; + return (current_scope == file_scope && !c_override_global_bindings_to_false + ? -1 + : 0); } void @@ -597,6 +686,30 @@ keep_next_level (void) keep_next_level_flag = true; } +/* Set the flag for the FLOAT_CONST_DECIMAL64 pragma being ON. */ + +void +set_float_const_decimal64 (void) +{ + current_scope->float_const_decimal64 = true; +} + +/* Clear the flag for the FLOAT_CONST_DECIMAL64 pragma. */ + +void +clear_float_const_decimal64 (void) +{ + current_scope->float_const_decimal64 = false; +} + +/* Return nonzero if an unsuffixed float constant is _Decimal64. */ + +bool +float_const_decimal64_p (void) +{ + return current_scope->float_const_decimal64; +} + /* Identify this scope as currently being filled with parameters. */ void @@ -628,6 +741,13 @@ push_scope (void) keep_next_level_flag = false; next_is_function_body = false; + + /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */ + if (current_scope->outer) + current_scope->float_const_decimal64 + = current_scope->outer->float_const_decimal64; + else + current_scope->float_const_decimal64 = false; } else { @@ -640,6 +760,12 @@ push_scope (void) else scope = GGC_CNEW (struct c_scope); + /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */ + if (current_scope) + scope->float_const_decimal64 = current_scope->float_const_decimal64; + else + scope->float_const_decimal64 = false; + scope->keep = keep_next_level_flag; scope->outer = current_scope; scope->depth = current_scope ? (current_scope->depth + 1) : 0; @@ -779,14 +905,18 @@ pop_scope (void) error ("nested function %q+D declared but never defined", p); undef_nested_function = true; } - /* C99 6.7.4p6: "a function with external linkage... declared - with an inline function specifier ... shall also be defined in the - same translation unit." */ else if (DECL_DECLARED_INLINE_P (p) && TREE_PUBLIC (p) - && !DECL_INITIAL (p) - && !flag_gnu89_inline) - pedwarn (0, "inline function %q+D declared but never defined", p); + && !DECL_INITIAL (p)) + { + /* C99 6.7.4p6: "a function with external linkage... declared + with an inline function specifier ... shall also be defined + in the same translation unit." */ + if (!flag_gnu89_inline) + pedwarn (input_location, 0, + "inline function %q+D declared but never defined", p); + DECL_EXTERNAL (p) = 1; + } goto common_symbol; @@ -818,6 +948,29 @@ pop_scope (void) TREE_CHAIN (p) = BLOCK_VARS (block); BLOCK_VARS (block) = p; } + else if (VAR_OR_FUNCTION_DECL_P (p)) + { + /* For block local externs add a special + DECL_EXTERNAL decl for debug info generation. */ + tree extp = copy_node (p); + + DECL_EXTERNAL (extp) = 1; + TREE_STATIC (extp) = 0; + TREE_PUBLIC (extp) = 1; + DECL_INITIAL (extp) = NULL_TREE; + DECL_LANG_SPECIFIC (extp) = NULL; + DECL_CONTEXT (extp) = current_function_decl; + if (TREE_CODE (p) == FUNCTION_DECL) + { + DECL_RESULT (extp) = NULL_TREE; + DECL_SAVED_TREE (extp) = NULL_TREE; + DECL_STRUCT_FUNCTION (extp) = NULL; + } + if (b->locus != UNKNOWN_LOCATION) + DECL_SOURCE_LOCATION (extp) = b->locus; + TREE_CHAIN (extp) = BLOCK_VARS (block); + BLOCK_VARS (block) = extp; + } /* If this is the file scope, and we are processing more than one translation unit in this compilation, set DECL_CONTEXT of each decl to the TRANSLATION_UNIT_DECL. @@ -899,7 +1052,7 @@ push_file_scope (void) for (decl = visible_builtins; decl; decl = TREE_CHAIN (decl)) bind (DECL_NAME (decl), decl, file_scope, - /*invisible=*/false, /*nested=*/true); + /*invisible=*/false, /*nested=*/true, DECL_SOURCE_LOCATION (decl)); } void @@ -915,6 +1068,8 @@ pop_file_scope (void) still works without it. */ finish_fname_decls (); + check_inline_statics (); + /* This is the point to write out a PCH if we're doing that. In that case we do not want to do anything else. */ if (pch_file) @@ -940,12 +1095,12 @@ pop_file_scope (void) In that case, the TYPE_SIZE will be zero. */ static void -pushtag (tree name, tree type) +pushtag (tree name, tree type, location_t loc) { /* Record the identifier as the type's name if it has none. */ if (name && !TYPE_NAME (type)) TYPE_NAME (type) = name; - bind (name, type, current_scope, /*invisible=*/false, /*nested=*/false); + bind (name, type, current_scope, /*invisible=*/false, /*nested=*/false, loc); /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the tagged type we just added to the current scope. This fake @@ -959,6 +1114,27 @@ pushtag (tree name, tree type) /* An approximation for now, so we can tell this is a function-scope tag. This will be updated in pop_scope. */ TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type)); + + if (warn_cxx_compat && name != NULL_TREE) + { + struct c_binding *b = I_SYMBOL_BINDING (name); + + if (b != NULL + && b->decl != NULL_TREE + && TREE_CODE (b->decl) == TYPE_DECL + && (B_IN_CURRENT_SCOPE (b) + || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b))) + && (TYPE_MAIN_VARIANT (TREE_TYPE (b->decl)) + != TYPE_MAIN_VARIANT (type))) + { + warning_at (loc, OPT_Wc___compat, + ("using %qD as both a typedef and a tag is " + "invalid in C++"), + b->decl); + if (b->locus != UNKNOWN_LOCATION) + inform (b->locus, "originally defined here"); + } + } } /* Subroutine of compare_decls. Allow harmless mismatches in return @@ -1027,14 +1203,14 @@ diagnose_arglist_conflict (tree newdecl, tree olddecl, if (TREE_CHAIN (t) == 0 && TYPE_MAIN_VARIANT (type) != void_type_node) { - inform ("a parameter list with an ellipsis can%'t match " + inform (input_location, "a parameter list with an ellipsis can%'t match " "an empty parameter name list declaration"); break; } if (c_type_promotes_to (type) != type) { - inform ("an argument type that has a default promotion can%'t match " + inform (input_location, "an argument type that has a default promotion can%'t match " "an empty parameter name list declaration"); break; } @@ -1113,16 +1289,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 *, ...) ATTRIBUTE_GCC_CDIAG(1,2)) +locate_old_decl (tree decl) { if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl)) ; else if (DECL_INITIAL (decl)) - diag (G_("previous definition of %q+D was here"), decl); + inform (input_location, "previous definition of %q+D was here", decl); else if (C_DECL_IMPLICIT (decl)) - diag (G_("previous implicit declaration of %q+D was here"), decl); + inform (input_location, "previous implicit declaration of %q+D was here", decl); else - diag (G_("previous declaration of %q+D was here"), decl); + inform (input_location, "previous declaration of %q+D was here", decl); } /* Subroutine of duplicate_decls. Compare NEWDECL to OLDDECL. @@ -1163,7 +1339,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && !C_DECL_DECLARED_BUILTIN (olddecl))) { error ("%q+D redeclared as different kind of symbol", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); } else if (TREE_PUBLIC (newdecl)) warning (0, "built-in function %q+D declared as non-function", @@ -1179,7 +1355,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (TREE_CODE (olddecl) == CONST_DECL) { error ("redeclaration of enumerator %q+D", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } @@ -1223,11 +1399,11 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node && C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl)) { - pedwarn (0, "conflicting types for %q+D", newdecl); + pedwarned = pedwarn (input_location, 0, + "conflicting types for %q+D", newdecl); /* Make sure we keep void as the return type. */ TREE_TYPE (newdecl) = *newtypep = newtype = oldtype; C_FUNCTION_IMPLICIT_INT (newdecl) = 0; - pedwarned = true; } /* Permit void foo (...) to match an earlier call to foo (...) with no declared type (thus, implicitly int). */ @@ -1236,10 +1412,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl)) { - pedwarn (0, "conflicting types for %q+D", newdecl); + pedwarned = pedwarn (input_location, 0, + "conflicting types for %q+D", newdecl); /* Make sure we keep void as the return type. */ TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype; - pedwarned = true; } else { @@ -1248,7 +1424,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, else error ("conflicting types for %q+D", newdecl); diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } } @@ -1265,7 +1441,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, return true; /* Allow OLDDECL to continue in use. */ error ("redefinition of typedef %q+D", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } @@ -1316,7 +1492,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && same_translation_unit_p (newdecl, olddecl)) { error ("redefinition of %q+D", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } } @@ -1328,7 +1504,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && TYPE_ACTUAL_ARG_TYPES (oldtype) && !validate_proto_after_old_defn (newdecl, newtype, oldtype)) { - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } /* A non-static declaration (even an "extern") followed by a @@ -1352,7 +1528,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { error ("static declaration of %q+D follows " "non-static declaration", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); } return false; } @@ -1362,14 +1538,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { error ("non-static declaration of %q+D follows " "static declaration", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } else if (warn_traditional) { - warning (OPT_Wtraditional, "non-static declaration of %q+D " - "follows static declaration", newdecl); - warned = true; + warned |= warning (OPT_Wtraditional, + "non-static declaration of %q+D " + "follows static declaration", newdecl); } } @@ -1410,7 +1586,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, error ("non-thread-local declaration of %q+D follows " "thread-local declaration", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } @@ -1418,7 +1594,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl)) { error ("redefinition of %q+D", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } @@ -1439,14 +1615,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { error ("extern declaration of %q+D follows " "declaration with no linkage", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } else if (warn_traditional) { - warning (OPT_Wtraditional, "non-static declaration of %q+D " - "follows static declaration", newdecl); - warned = true; + warned |= warning (OPT_Wtraditional, + "non-static declaration of %q+D " + "follows static declaration", newdecl); } } else @@ -1458,7 +1634,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, error ("static declaration of %q+D follows " "non-static declaration", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } } @@ -1475,12 +1651,12 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, { error ("declaration of %q+D with no linkage follows " "extern declaration", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); } else { error ("redeclaration of %q+D with no linkage", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); } return false; @@ -1493,9 +1669,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl) && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) { - warning (0, "redeclaration of %q+D with different visibility " - "(old visibility preserved)", newdecl); - warned = true; + warned |= warning (0, "redeclaration of %q+D with different visibility " + "(old visibility preserved)", newdecl); } if (TREE_CODE (newdecl) == FUNCTION_DECL) @@ -1504,40 +1679,16 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (DECL_DECLARED_INLINE_P (newdecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) { - warning (OPT_Wattributes, "inline declaration of %qD follows " - "declaration with attribute noinline", newdecl); - warned = true; + 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))) { - warning (OPT_Wattributes, "declaration of %q+D with attribute " - "noinline follows inline declaration ", newdecl); - warned = true; - } - - /* Inline declaration after use or definition. - ??? Should we still warn about this now we have unit-at-a-time - mode and can get it right? - Definitely don't complain if the decls are in different translation - units. - C99 permits this, so don't warn in that case. (The function - may not be inlined everywhere in function-at-a-time mode, but - we still shouldn't warn.) */ - if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl) - && same_translation_unit_p (olddecl, newdecl) - && flag_gnu89_inline) - { - if (TREE_USED (olddecl)) - { - warning (0, "%q+D declared inline after being called", olddecl); - warned = true; - } - else if (DECL_INITIAL (olddecl)) - { - warning (0, "%q+D declared inline after its definition", olddecl); - warned = true; - } + warned |= warning (OPT_Wattributes, + "declaration of %q+D with attribute " + "noinline follows inline declaration ", newdecl); } } else /* PARM_DECL, VAR_DECL */ @@ -1555,7 +1706,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl))) { error ("redefinition of parameter %q+D", newdecl); - locate_old_decl (olddecl, error); + locate_old_decl (olddecl); return false; } } @@ -1581,14 +1732,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && !(TREE_CODE (newdecl) == VAR_DECL && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))) { - warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D", - newdecl); - warned = true; + warned = warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D", + newdecl); } - /* Report location of previous decl/defn in a consistent manner. */ + /* Report location of previous decl/defn. */ if (warned || pedwarned) - locate_old_decl (olddecl, pedwarned ? pedwarn0 : warning0); + locate_old_decl (olddecl); #undef DECL_EXTERN_INLINE @@ -1799,18 +1949,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) throw it away, in case it was inlined into a function that hasn't been written out yet. */ if (new_is_definition && DECL_INITIAL (olddecl)) - { - if (TREE_USED (olddecl) - /* In unit-at-a-time mode we never inline re-defined extern - inline functions. */ - && !flag_unit_at_a_time - && cgraph_function_possibly_inlined_p (olddecl)) - (*debug_hooks->outlining_inline_function) (olddecl); - - /* The new defn must not be inline. */ - DECL_INLINE (newdecl) = 0; - DECL_UNINLINABLE (newdecl) = 1; - } + /* The new defn must not be inline. */ + DECL_UNINLINABLE (newdecl) = 1; else { /* If either decl says `inline', this fn is inline, unless @@ -1856,44 +1996,49 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) /* Also preserve various other info from the definition. */ if (!new_is_definition) { + tree t; DECL_RESULT (newdecl) = DECL_RESULT (olddecl); DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl); DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); - DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); - - /* Set DECL_INLINE on the declaration if we've got a body - from which to instantiate. */ - if (DECL_INLINE (olddecl) && !DECL_UNINLINABLE (newdecl)) - { - DECL_INLINE (newdecl) = 1; - DECL_ABSTRACT_ORIGIN (newdecl) - = DECL_ABSTRACT_ORIGIN (olddecl); - } - } - else - { - /* If a previous declaration said inline, mark the - definition as inlinable. */ - if (DECL_DECLARED_INLINE_P (newdecl) - && !DECL_UNINLINABLE (newdecl)) - DECL_INLINE (newdecl) = 1; + 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; + + /* See if we've got a function to instantiate from. */ + if (DECL_SAVED_TREE (olddecl)) + DECL_ABSTRACT_ORIGIN (newdecl) + = DECL_ABSTRACT_ORIGIN (olddecl); } } extern_changed = DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl); + /* Merge the USED information. */ + if (TREE_USED (olddecl)) + TREE_USED (newdecl) = 1; + else if (TREE_USED (newdecl)) + TREE_USED (olddecl) = 1; + /* Copy most of the decl-specific fields of NEWDECL into OLDDECL. But preserve OLDDECL's DECL_UID and DECL_CONTEXT. */ { unsigned olddecl_uid = DECL_UID (olddecl); tree olddecl_context = DECL_CONTEXT (olddecl); + tree olddecl_arguments = NULL; + if (TREE_CODE (olddecl) == FUNCTION_DECL) + olddecl_arguments = DECL_ARGUMENTS (olddecl); memcpy ((char *) olddecl + sizeof (struct tree_common), (char *) newdecl + sizeof (struct tree_common), sizeof (struct tree_decl_common) - sizeof (struct tree_common)); 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: @@ -1901,7 +2046,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) case RESULT_DECL: case CONST_DECL: case TYPE_DECL: - case FUNCTION_DECL: memcpy ((char *) olddecl + sizeof (struct tree_decl_common), (char *) newdecl + sizeof (struct tree_decl_common), tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common)); @@ -1915,6 +2059,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) } DECL_UID (olddecl) = olddecl_uid; DECL_CONTEXT (olddecl) = olddecl_context; + if (TREE_CODE (olddecl) == FUNCTION_DECL) + DECL_ARGUMENTS (olddecl) = olddecl_arguments; } /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl @@ -2007,67 +2153,6 @@ warn_if_shadowing (tree new_decl) } } - -/* Subroutine of pushdecl. - - X is a TYPE_DECL for a typedef statement. Create a brand new - ..._TYPE node (which will be just a variant of the existing - ..._TYPE node with identical properties) and then install X - as the TYPE_NAME of this brand new (duplicate) ..._TYPE node. - - The whole point here is to end up with a situation where each - and every ..._TYPE node the compiler creates will be uniquely - associated with AT MOST one node representing a typedef name. - This way, even though the compiler substitutes corresponding - ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very - early on, later parts of the compiler can always do the reverse - translation and get back the corresponding typedef name. For - example, given: - - typedef struct S MY_TYPE; - MY_TYPE object; - - Later parts of the compiler might only know that `object' was of - type `struct S' if it were not for code just below. With this - code however, later parts of the compiler see something like: - - struct S' == struct S - typedef struct S' MY_TYPE; - struct S' object; - - And they can then deduce (from the node for type struct S') that - the original object declaration was: - - MY_TYPE object; - - Being able to do this is important for proper support of protoize, - and also for generating precise symbolic debugging information - which takes full account of the programmer's (typedef) vocabulary. - - Obviously, we don't want to generate a duplicate ..._TYPE node if - the TYPE_DECL node that we are now processing really represents a - standard built-in type. */ - -static void -clone_underlying_type (tree x) -{ - if (DECL_IS_BUILTIN (x)) - { - if (TYPE_NAME (TREE_TYPE (x)) == 0) - TYPE_NAME (TREE_TYPE (x)) = x; - } - else if (TREE_TYPE (x) != error_mark_node - && DECL_ORIGINAL_TYPE (x) == NULL_TREE) - { - tree tt = TREE_TYPE (x); - DECL_ORIGINAL_TYPE (x) = tt; - tt = build_variant_type_copy (tt); - TYPE_NAME (tt) = x; - TREE_USED (tt) = TREE_USED (x); - TREE_TYPE (x) = tt; - } -} - /* Record a decl-node X as belonging to the current lexical scope. Check for errors (such as an incompatible declaration for the same name already seen in the same scope). @@ -2083,6 +2168,7 @@ pushdecl (tree x) struct c_scope *scope = current_scope; struct c_binding *b; bool nested = false; + location_t locus = DECL_SOURCE_LOCATION (x); /* Must set DECL_CONTEXT for everything not at file scope or DECL_FILE_SCOPE_P won't work. Local externs don't count @@ -2101,7 +2187,8 @@ pushdecl (tree x) /* Anonymous decls are just inserted in the scope. */ if (!name) { - bind (name, x, scope, /*invisible=*/false, /*nested=*/false); + bind (name, x, scope, /*invisible=*/false, /*nested=*/false, + locus); return x; } @@ -2261,7 +2348,8 @@ pushdecl (tree x) = build_type_attribute_variant (thistype, TYPE_ATTRIBUTES (b->type)); TREE_TYPE (b->decl) = thistype; - bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true); + bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true, + locus); return b->decl; } else if (TREE_PUBLIC (x)) @@ -2279,7 +2367,7 @@ pushdecl (tree x) else { bind (name, x, external_scope, /*invisible=*/true, - /*nested=*/false); + /*nested=*/false, locus); nested = true; } } @@ -2290,9 +2378,9 @@ pushdecl (tree x) skip_external_and_shadow_checks: if (TREE_CODE (x) == TYPE_DECL) - clone_underlying_type (x); + set_underlying_type (x); - bind (name, x, scope, /*invisible=*/false, nested); + bind (name, x, scope, /*invisible=*/false, nested, locus); /* If x's type is incomplete because it's based on a structure or union which has not yet been fully declared, @@ -2341,11 +2429,12 @@ pushdecl_top_level (tree x) if (TREE_PUBLIC (x)) { - bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false); + bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false, + UNKNOWN_LOCATION); nested = true; } if (file_scope) - bind (name, x, file_scope, /*invisible=*/false, nested); + bind (name, x, file_scope, /*invisible=*/false, nested, UNKNOWN_LOCATION); return x; } @@ -2355,14 +2444,16 @@ implicit_decl_warning (tree id, tree olddecl) { if (warn_implicit_function_declaration) { + bool warned; + if (flag_isoc99) - pedwarn (OPT_Wimplicit_function_declaration, - G_("implicit declaration of function %qE"), id); + warned = pedwarn (input_location, OPT_Wimplicit_function_declaration, + "implicit declaration of function %qE", id); else - warning (OPT_Wimplicit_function_declaration, - G_("implicit declaration of function %qE"), id); - if (olddecl) - locate_old_decl (olddecl, inform); + warned = warning (OPT_Wimplicit_function_declaration, + G_("implicit declaration of function %qE"), id); + if (olddecl && warned) + locate_old_decl (olddecl); } } @@ -2398,7 +2489,8 @@ implicitly_declare (tree functionid) if (!DECL_BUILT_IN (decl) && DECL_IS_BUILTIN (decl)) { bind (functionid, decl, file_scope, - /*invisible=*/false, /*nested=*/true); + /*invisible=*/false, /*nested=*/true, + DECL_SOURCE_LOCATION (decl)); return decl; } else @@ -2433,13 +2525,14 @@ implicitly_declare (tree functionid) { error ("incompatible implicit declaration of function %qD", decl); - locate_old_decl (decl, error); + locate_old_decl (decl); } } b->type = TREE_TYPE (decl); TREE_TYPE (decl) = newtype; bind (functionid, decl, current_scope, - /*invisible=*/false, /*nested=*/true); + /*invisible=*/false, /*nested=*/true, + DECL_SOURCE_LOCATION (decl)); return decl; } } @@ -2502,7 +2595,8 @@ undeclared_variable (tree id, location_t loc) will be nonnull but current_function_scope will be null. */ scope = current_function_scope ? current_function_scope : current_scope; } - bind (id, error_mark_node, scope, /*invisible=*/false, /*nested=*/false); + bind (id, error_mark_node, scope, /*invisible=*/false, /*nested=*/false, + UNKNOWN_LOCATION); } /* Subroutine of lookup_label, declare_label, define_label: construct a @@ -2556,7 +2650,7 @@ lookup_label (tree name) /* Ordinary labels go in the current function scope. */ bind (name, label, current_function_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); return label; } @@ -2575,7 +2669,7 @@ declare_label (tree name) if (b && B_IN_CURRENT_SCOPE (b)) { error ("duplicate label declaration %qE", name); - locate_old_decl (b->decl, error); + locate_old_decl (b->decl); /* Just use the previous declaration. */ return b->decl; @@ -2586,7 +2680,7 @@ declare_label (tree name) /* Declared labels go in the current scope. */ bind (name, label, current_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); return label; } @@ -2611,7 +2705,7 @@ define_label (location_t location, tree name) && C_DECLARED_LABEL_FLAG (label)))) { error ("%Hduplicate label %qD", &location, label); - locate_old_decl (label, error); + locate_old_decl (label); return 0; } else if (label && DECL_CONTEXT (label) == current_function_decl) @@ -2633,7 +2727,7 @@ define_label (location_t location, tree name) /* Ordinary labels go in the current function scope. */ bind (name, label, current_function_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } if (!in_system_header && lookup_name (name)) @@ -2660,10 +2754,13 @@ define_label (location_t location, tree name) If THISLEVEL_ONLY is nonzero, searches only the current_scope. CODE says which kind of type the caller wants; it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE. + If PLOC is not NULL and this returns non-null, it sets *PLOC to the + location where the tag was defined. If the wrong kind of type is found, an error is reported. */ static tree -lookup_tag (enum tree_code code, tree name, int thislevel_only) +lookup_tag (enum tree_code code, tree name, int thislevel_only, + location_t *ploc) { struct c_binding *b = I_TAG_BINDING (name); int thislevel = 0; @@ -2700,6 +2797,10 @@ lookup_tag (enum tree_code code, tree name, int thislevel_only) if (thislevel) pending_xref_error (); } + + if (ploc != NULL) + *ploc = b->locus; + return b->decl; } @@ -2836,10 +2937,10 @@ c_make_fname_decl (tree id, int type_dep) { DECL_CONTEXT (decl) = current_function_decl; bind (id, decl, current_function_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } - finish_decl (decl, init, NULL_TREE); + finish_decl (decl, init, NULL_TREE, NULL_TREE); return decl; } @@ -2856,7 +2957,34 @@ c_builtin_function (tree decl) /* Should never be called on a symbol with a preexisting meaning. */ gcc_assert (!I_SYMBOL_BINDING (id)); - bind (id, decl, external_scope, /*invisible=*/true, /*nested=*/false); + bind (id, decl, external_scope, /*invisible=*/true, /*nested=*/false, + UNKNOWN_LOCATION); + + /* Builtins in the implementation namespace are made visible without + needing to be explicitly declared. See push_file_scope. */ + if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1]))) + { + TREE_CHAIN (decl) = visible_builtins; + visible_builtins = decl; + } + + return decl; +} + +tree +c_builtin_function_ext_scope (tree decl) +{ + tree type = TREE_TYPE (decl); + tree id = DECL_NAME (decl); + + const char *name = IDENTIFIER_POINTER (id); + C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0); + + /* Should never be called on a symbol with a preexisting meaning. */ + gcc_assert (!I_SYMBOL_BINDING (id)); + + bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false, + UNKNOWN_LOCATION); /* Builtins in the implementation namespace are made visible without needing to be explicitly declared. See push_file_scope. */ @@ -2904,12 +3032,19 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) found_tag = true; + if (declspecs->restrict_p) + { + error ("invalid use of %"); + warned = 1; + } + if (name == 0) { if (warned != 1 && code != ENUMERAL_TYPE) /* Empty unnamed enum OK */ { - pedwarn (0, "unnamed struct/union that defines no instances"); + pedwarn (input_location, 0, + "unnamed struct/union that defines no instances"); warned = 1; } } @@ -2917,8 +3052,9 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) && declspecs->storage_class != csc_none) { if (warned != 1) - pedwarn (0, "empty declaration with storage class specifier " - "does not redeclare tag"); + pedwarn (input_location, 0, + "empty declaration with storage class specifier " + "does not redeclare tag"); warned = 1; pending_xref_error (); } @@ -2928,7 +3064,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) || declspecs->restrict_p)) { if (warned != 1) - pedwarn (0, "empty declaration with type qualifier " + pedwarn (input_location, 0, + "empty declaration with type qualifier " "does not redeclare tag"); warned = 1; pending_xref_error (); @@ -2936,12 +3073,12 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) else { pending_invalid_xref = 0; - t = lookup_tag (code, name, 1); + t = lookup_tag (code, name, 1, NULL); if (t == 0) { t = make_node (code); - pushtag (name, t); + pushtag (name, t, input_location); } } } @@ -2949,14 +3086,15 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) { if (warned != 1 && !in_system_header) { - pedwarn (0, "useless type name in empty declaration"); + pedwarn (input_location, 0, + "useless type name in empty declaration"); warned = 1; } } } else if (warned != 1 && !in_system_header && declspecs->typedef_p) { - pedwarn (0, "useless type name in empty declaration"); + pedwarn (input_location, 0, "useless type name in empty declaration"); warned = 1; } @@ -3003,7 +3141,7 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) if (warned != 1) { if (!found_tag) - pedwarn (0, "empty declaration"); + pedwarn (input_location, 0, "empty declaration"); } } @@ -3069,10 +3207,12 @@ build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p, if (!flag_isoc99) { if (static_p || quals != NULL) - pedwarn (OPT_pedantic, "ISO C90 does not support % or type " + pedwarn (input_location, OPT_pedantic, + "ISO C90 does not support % or type " "qualifiers in parameter array declarators"); if (vla_unspec_p) - pedwarn (OPT_pedantic, "ISO C90 does not support %<[*]%> array declarators"); + pedwarn (input_location, OPT_pedantic, + "ISO C90 does not support %<[*]%> array declarators"); } if (vla_unspec_p) { @@ -3127,10 +3267,15 @@ add_flexible_array_elts_to_size (tree decl, tree init) } } -/* Decode a "typename", such as "int **", returning a ..._TYPE node. */ +/* Decode a "typename", such as "int **", returning a ..._TYPE node. + Set *EXPR, if EXPR not NULL, to any expression to be evaluated + before the type name, and set *EXPR_CONST_OPERANDS, if + EXPR_CONST_OPERANDS not NULL, to indicate whether the type name may + appear in a constant expression. */ tree -groktypename (struct c_type_name *type_name) +groktypename (struct c_type_name *type_name, tree *expr, + bool *expr_const_operands) { tree type; tree attrs = type_name->specs->attrs; @@ -3138,7 +3283,8 @@ groktypename (struct c_type_name *type_name) type_name->specs->attrs = NULL_TREE; type = grokdeclarator (type_name->declarator, type_name->specs, TYPENAME, - false, NULL, &attrs, DEPRECATED_NORMAL); + false, NULL, &attrs, expr, expr_const_operands, + DEPRECATED_NORMAL); /* Apply attributes. */ decl_attributes (&type, attrs, 0); @@ -3167,6 +3313,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, { tree decl; tree tem; + tree expr = NULL_TREE; enum deprecated_states deprecated_state = DEPRECATED_NORMAL; /* An object declared as __attribute__((deprecated)) suppresses @@ -3175,13 +3322,15 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, deprecated_state = DEPRECATED_SUPPRESS; decl = grokdeclarator (declarator, declspecs, - NORMAL, initialized, NULL, &attributes, + NORMAL, initialized, NULL, &attributes, &expr, NULL, deprecated_state); if (!decl) return 0; - if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL - && MAIN_NAME_P (DECL_NAME (decl))) + if (expr) + add_stmt (expr); + + if (TREE_CODE (decl) != FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (decl))) warning (OPT_Wmain, "%q+D is usually a function", decl); if (initialized) @@ -3328,8 +3477,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, && !TREE_READONLY (decl) && DECL_DECLARED_INLINE_P (current_function_decl) && DECL_EXTERNAL (current_function_decl)) - pedwarn (0, "%q+D is static but declared in inline function %qD " - "which is not static", decl, current_function_decl); + record_inline_static (input_location, current_function_decl, + decl, csi_modifiable); /* Add this decl to the current scope. TEM may equal DECL or it may be a previous decl of the same name. */ @@ -3363,11 +3512,12 @@ c_maybe_initialize_eh (void) /* Finish processing of a declaration; install its initial value. + If ORIGTYPE is not NULL_TREE, it is the original type of INIT. If the length of an array type is not known before, it must be determined now, from the initial value, or it is an error. */ void -finish_decl (tree decl, tree init, tree asmspec_tree) +finish_decl (tree decl, tree init, tree origtype, tree asmspec_tree) { tree type; int was_incomplete = (DECL_SIZE (decl) == 0); @@ -3389,7 +3539,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) init = 0; if (init) - store_init_value (decl, init); + store_init_value (decl, init, origtype); if (c_dialect_objc () && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL @@ -3618,10 +3768,6 @@ finish_decl (tree decl, tree init, tree asmspec_tree) } } - /* If this was marked 'used', be sure it will be output. */ - if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl))) - mark_decl_referenced (decl); - if (TREE_CODE (decl) == TYPE_DECL) { if (!DECL_FILE_SCOPE_P (decl) @@ -3646,11 +3792,14 @@ finish_decl (tree decl, tree init, tree asmspec_tree) tree cleanup_id = TREE_VALUE (TREE_VALUE (attr)); tree cleanup_decl = lookup_name (cleanup_id); tree cleanup; + VEC(tree,gc) *vec; /* Build "cleanup(&decl)" for the destructor. */ - cleanup = build_unary_op (ADDR_EXPR, decl, 0); - cleanup = build_tree_list (NULL_TREE, cleanup); - cleanup = build_function_call (cleanup_decl, cleanup); + cleanup = build_unary_op (input_location, ADDR_EXPR, decl, 0); + vec = VEC_alloc (tree, gc, 1); + VEC_quick_push (tree, vec, cleanup); + cleanup = build_function_call_vec (cleanup_decl, vec, NULL); + VEC_free (tree, gc, vec); /* Don't warn about decl unused; the cleanup uses it. */ TREE_USED (decl) = 1; @@ -3671,7 +3820,7 @@ grokparm (const struct c_parm *parm) { tree attrs = parm->attrs; tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, - NULL, &attrs, DEPRECATED_NORMAL); + NULL, &attrs, NULL, NULL, DEPRECATED_NORMAL); decl_attributes (&decl, attrs, 0); @@ -3688,12 +3837,12 @@ push_parm_decl (const struct c_parm *parm) tree decl; decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL, - &attrs, DEPRECATED_NORMAL); + &attrs, NULL, NULL, DEPRECATED_NORMAL); decl_attributes (&decl, attrs, 0); decl = pushdecl (decl); - finish_decl (decl, NULL_TREE, NULL_TREE); + finish_decl (decl, NULL_TREE, NULL_TREE, NULL_TREE); } /* Mark all the parameter declarations to date as forward decls. @@ -3706,7 +3855,8 @@ mark_forward_parm_decls (void) if (pedantic && !current_scope->warned_forward_parm_decls) { - pedwarn (OPT_pedantic, "ISO C forbids forward parameter declarations"); + pedwarn (input_location, OPT_pedantic, + "ISO C forbids forward parameter declarations"); current_scope->warned_forward_parm_decls = true; } @@ -3718,10 +3868,11 @@ mark_forward_parm_decls (void) /* Build a COMPOUND_LITERAL_EXPR. TYPE is the type given in the compound literal, which may be an incomplete array type completed by the initializer; INIT is a CONSTRUCTOR that initializes the compound - literal. */ + literal. NON_CONST is true if the initializers contain something + that cannot occur in a constant expression. */ tree -build_compound_literal (tree type, tree init) +build_compound_literal (tree type, tree init, bool non_const) { /* We do not use start_decl here because we have a type, not a declarator; and do not use finish_decl because the decl should be stored inside @@ -3741,7 +3892,7 @@ build_compound_literal (tree type, tree init) TREE_USED (decl) = 1; TREE_TYPE (decl) = type; TREE_READONLY (decl) = TYPE_READONLY (type); - store_init_value (decl, init); + store_init_value (decl, init, NULL_TREE); if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type)) { @@ -3774,8 +3925,25 @@ build_compound_literal (tree type, tree init) rest_of_decl_compilation (decl, 1, 0); } + if (non_const) + { + complit = build2 (C_MAYBE_CONST_EXPR, type, NULL, complit); + C_MAYBE_CONST_EXPR_NON_CONST (complit) = 1; + } + return complit; } + +/* Check the type of a compound literal. Here we just check that it + is valid for C++. */ + +void +check_compound_literal_type (struct c_type_name *type_name, location_t loc) +{ + if (warn_cxx_compat && type_name->specs->tag_defined_p) + warning_at (loc, OPT_Wc___compat, + "defining a type in a compound literal is invalid in C++"); +} /* Determine whether TYPE is a structure with a flexible array member, or a union containing such a structure (possibly recursively). */ @@ -3813,12 +3981,14 @@ flexible_array_type_p (tree type) /* Performs sanity checks on the TYPE and WIDTH of the bit-field NAME, replacing with appropriate values if they are invalid. */ static void -check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) +check_bitfield_type_and_width (tree *type, tree *width, tree orig_name) { tree type_mv; unsigned int max_width; unsigned HOST_WIDE_INT w; - const char *name = orig_name ? orig_name: _(""); + const char *name = (orig_name + ? identifier_to_locale (IDENTIFIER_POINTER (orig_name)) + : _("")); /* Detect and ignore out of range field width and process valid field widths. */ @@ -3857,7 +4027,8 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) && type_mv != integer_type_node && type_mv != unsigned_type_node && type_mv != boolean_type_node) - pedwarn (OPT_pedantic, "type of bit-field %qs is a GCC extension", name); + pedwarn (input_location, OPT_pedantic, + "type of bit-field %qs is a GCC extension", name); max_width = TYPE_PRECISION (*type); @@ -3874,8 +4045,8 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) { struct lang_type *lt = TYPE_LANG_SPECIFIC (*type); if (!lt - || w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type)) - || w < min_precision (lt->enum_max, TYPE_UNSIGNED (*type))) + || w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type)) + || w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type))) warning (0, "%qs is narrower than values of its type", name); } } @@ -3885,7 +4056,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name) /* Print warning about variable length array if necessary. */ static void -warn_variable_length_array (const char *name, tree size) +warn_variable_length_array (tree name, tree size) { int const_size = TREE_CONSTANT (size); @@ -3894,20 +4065,22 @@ warn_variable_length_array (const char *name, tree size) if (const_size) { if (name) - pedwarn (OPT_Wvla, "ISO C90 forbids array %qs whose size " + pedwarn (input_location, OPT_Wvla, + "ISO C90 forbids array %qE whose size " "can%'t be evaluated", name); else - pedwarn (OPT_Wvla, "ISO C90 forbids array whose size " + pedwarn (input_location, OPT_Wvla, "ISO C90 forbids array whose size " "can%'t be evaluated"); } else { if (name) - pedwarn (OPT_Wvla, "ISO C90 forbids variable length array %qs", + pedwarn (input_location, OPT_Wvla, + "ISO C90 forbids variable length array %qE", name); else - pedwarn (OPT_Wvla, "ISO C90 forbids variable length array"); + pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array"); } } else if (warn_vla > 0) @@ -3916,7 +4089,7 @@ warn_variable_length_array (const char *name, tree size) { if (name) warning (OPT_Wvla, - "the size of array %qs can" + "the size of array %qE can" "%'t be evaluated", name); else warning (OPT_Wvla, @@ -3926,7 +4099,7 @@ warn_variable_length_array (const char *name, tree size) { if (name) warning (OPT_Wvla, - "variable length array %qs is used", + "variable length array %qE is used", name); else warning (OPT_Wvla, @@ -3935,6 +4108,34 @@ warn_variable_length_array (const char *name, tree size) } } +/* Given a size SIZE that may not be a constant, return a SAVE_EXPR to + serve as the actual size-expression for a type or decl. This is + like variable_size in stor-layout.c, but we make global_bindings_p + return negative to avoid calls to that function from outside the + front end resulting in errors at file scope, then call this version + instead from front-end code. */ + +static tree +c_variable_size (tree size) +{ + tree save; + + if (TREE_CONSTANT (size)) + return size; + + size = save_expr (size); + + save = skip_simple_arithmetic (size); + + if (cfun && cfun->dont_save_pending_sizes_p) + return size; + + if (!global_bindings_p ()) + put_pending_size (save); + + return size; +} + /* Given declspecs and a declarator, determine the name and type of the object declared and construct a ..._DECL node for it. @@ -3959,6 +4160,11 @@ warn_variable_length_array (const char *name, tree size) DECL_ATTRS points to the list of attributes that should be added to this decl. Any nested attributes that belong on the decl itself will be added to this list. + If EXPR is not NULL, any expressions that need to be evaluated as + part of evaluating variably modified types will be stored in *EXPR. + If EXPR_CONST_OPERANDS is not NULL, *EXPR_CONST_OPERANDS will be + set to indicate whether operands in *EXPR can be used in constant + expressions. DEPRECATED_STATE is a deprecated_states value indicating whether deprecation warnings should be suppressed. @@ -3973,7 +4179,8 @@ static tree grokdeclarator (const struct c_declarator *declarator, struct c_declspecs *declspecs, enum decl_context decl_context, bool initialized, tree *width, - tree *decl_attrs, enum deprecated_states deprecated_state) + tree *decl_attrs, tree *expr, bool *expr_const_operands, + enum deprecated_states deprecated_state) { tree type = declspecs->type; bool threadp = declspecs->thread_p; @@ -3982,7 +4189,7 @@ grokdeclarator (const struct c_declarator *declarator, int restrictp; int volatilep; int type_quals = TYPE_UNQUALIFIED; - const char *name, *orig_name; + tree name = NULL_TREE; bool funcdef_flag = false; bool funcdef_syntax = false; int size_varies = 0; @@ -3995,15 +4202,24 @@ grokdeclarator (const struct c_declarator *declarator, bool bitfield = width != NULL; tree element_type; struct c_arg_info *arg_info = 0; + tree expr_dummy; + bool expr_const_operands_dummy; + + if (expr == NULL) + expr = &expr_dummy; + if (expr_const_operands == NULL) + expr_const_operands = &expr_const_operands_dummy; + + *expr = declspecs->expr; + *expr_const_operands = declspecs->expr_const_operands; if (decl_context == FUNCDEF) funcdef_flag = true, decl_context = NORMAL; /* Look inside a declarator for the name being declared - and get it as a string, for an error message. */ + and get it as an IDENTIFIER_NODE, for an error message. */ { const struct c_declarator *decl = declarator; - name = 0; while (decl) switch (decl->kind) @@ -4021,16 +4237,21 @@ grokdeclarator (const struct c_declarator *declarator, case cdk_id: if (decl->u.id) - name = IDENTIFIER_POINTER (decl->u.id); + name = decl->u.id; decl = 0; break; default: gcc_unreachable (); } - orig_name = name; if (name == 0) - name = "type name"; + { + gcc_assert (decl_context == PARM + || decl_context == TYPENAME + || (decl_context == FIELD + && declarator->kind == cdk_id)); + gcc_assert (!initialized); + } } /* A function definition's declarator must have the form of @@ -4046,13 +4267,16 @@ grokdeclarator (const struct c_declarator *declarator, decl_context = PARM; if (declspecs->deprecated_p && deprecated_state != DEPRECATED_SUPPRESS) - warn_deprecated_use (declspecs->type); + warn_deprecated_use (declspecs->type, declspecs->decl_attr); if ((decl_context == NORMAL || decl_context == FIELD) && current_scope == file_scope && variably_modified_type_p (type, NULL_TREE)) { - error ("variably modified %qs at file scope", name); + if (name) + error ("variably modified %qE at file scope", name); + else + error ("variably modified field at file scope"); type = integer_type_node; } @@ -4068,9 +4292,16 @@ grokdeclarator (const struct c_declarator *declarator, if ((warn_implicit_int || warn_return_type || flag_isoc99) && funcdef_flag) warn_about_return_type = 1; - else - pedwarn_c99 (flag_isoc99 ? 0 : OPT_Wimplicit_int, - "type defaults to % in declaration of %qs", name); + else + { + if (name) + pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, + "type defaults to % in declaration of %qE", + name); + else + pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, + "type defaults to % in type name"); + } } /* Adjust the type if a bit-field is being declared, @@ -4078,7 +4309,7 @@ grokdeclarator (const struct c_declarator *declarator, "signed". */ if (bitfield && !flag_signed_bitfields && !declspecs->explicit_signed_p && TREE_CODE (type) == INTEGER_TYPE) - type = c_common_unsigned_type (type); + type = unsigned_type_for (type); /* Figure out the type qualifiers for the declaration. There are two ways a declaration can become qualified. One is something @@ -4098,11 +4329,11 @@ grokdeclarator (const struct c_declarator *declarator, if (pedantic && !flag_isoc99) { if (constp > 1) - pedwarn (OPT_pedantic, "duplicate %"); + pedwarn (input_location, OPT_pedantic, "duplicate %"); if (restrictp > 1) - pedwarn (OPT_pedantic, "duplicate %"); + pedwarn (input_location, OPT_pedantic, "duplicate %"); if (volatilep > 1) - pedwarn (OPT_pedantic, "duplicate %"); + pedwarn (input_location, OPT_pedantic, "duplicate %"); } if (!flag_gen_aux_info && (TYPE_QUALS (element_type))) type = TYPE_MAIN_VARIANT (type); @@ -4120,7 +4351,8 @@ grokdeclarator (const struct c_declarator *declarator, || storage_class == csc_typedef)) { if (storage_class == csc_auto) - pedwarn ((current_scope == file_scope) ? 0 : OPT_pedantic, + pedwarn (input_location, + (current_scope == file_scope) ? 0 : OPT_pedantic, "function definition declared %"); if (storage_class == csc_register) error ("function definition declared %"); @@ -4143,11 +4375,17 @@ grokdeclarator (const struct c_declarator *declarator, switch (decl_context) { case FIELD: - error ("storage class specified for structure field %qs", - name); + if (name) + error ("storage class specified for structure field %qE", + name); + else + error ("storage class specified for structure field"); break; case PARM: - error ("storage class specified for parameter %qs", name); + if (name) + error ("storage class specified for parameter %qE", name); + else + error ("storage class specified for unnamed parameter"); break; default: error ("storage class specified for typename"); @@ -4167,25 +4405,26 @@ grokdeclarator (const struct c_declarator *declarator, /* It is fine to have 'extern const' when compiling at C and C++ intersection. */ if (!(warn_cxx_compat && constp)) - warning (0, "%qs initialized and declared %", name); + warning (0, "%qE initialized and declared %", name); } else - error ("%qs has both % and initializer", name); + error ("%qE has both % and initializer", name); } else if (current_scope == file_scope) { if (storage_class == csc_auto) - error ("file-scope declaration of %qs specifies %", name); + error ("file-scope declaration of %qE specifies %", name); if (pedantic && storage_class == csc_register) - pedwarn (OPT_pedantic, "file-scope declaration of %qs specifies %", name); + pedwarn (input_location, OPT_pedantic, + "file-scope declaration of %qE specifies %", name); } else { if (storage_class == csc_extern && funcdef_flag) - error ("nested function %qs declared %", name); + error ("nested function %qE declared %", name); else if (threadp && storage_class == csc_none) { - error ("function-scope %qs implicitly auto and declared " + error ("function-scope %qE implicitly auto and declared " "%<__thread%>", name); threadp = false; @@ -4279,18 +4518,25 @@ grokdeclarator (const struct c_declarator *declarator, if (VOID_TYPE_P (type)) { - error ("declaration of %qs as array of voids", name); + if (name) + error ("declaration of %qE as array of voids", name); + else + error ("declaration of type name as array of voids"); type = error_mark_node; } if (TREE_CODE (type) == FUNCTION_TYPE) { - error ("declaration of %qs as array of functions", name); + if (name) + error ("declaration of %qE as array of functions", name); + else + error ("declaration of type name as array of functions"); type = error_mark_node; } if (pedantic && !in_system_header && flexible_array_type_p (type)) - pedwarn (OPT_pedantic, "invalid use of structure with flexible array member"); + pedwarn (input_location, OPT_pedantic, + "invalid use of structure with flexible array member"); if (size == error_mark_node) type = error_mark_node; @@ -4304,32 +4550,70 @@ grokdeclarator (const struct c_declarator *declarator, if (size) { + bool size_maybe_const = true; + bool size_int_const = (TREE_CODE (size) == INTEGER_CST + && !TREE_OVERFLOW (size)); + bool this_size_varies = false; + /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ STRIP_TYPE_NOPS (size); if (!INTEGRAL_TYPE_P (TREE_TYPE (size))) { - error ("size of array %qs has non-integer type", name); + if (name) + error ("size of array %qE has non-integer type", name); + else + error ("size of unnamed array has non-integer type"); size = integer_one_node; } - if (pedantic && integer_zerop (size)) - pedwarn (OPT_pedantic, "ISO C forbids zero-size array %qs", name); + size = c_fully_fold (size, false, &size_maybe_const); - if (TREE_CODE (size) == INTEGER_CST) + if (pedantic && size_maybe_const && integer_zerop (size)) + { + if (name) + pedwarn (input_location, OPT_pedantic, + "ISO C forbids zero-size array %qE", name); + else + pedwarn (input_location, OPT_pedantic, + "ISO C forbids zero-size array"); + } + + if (TREE_CODE (size) == INTEGER_CST && size_maybe_const) { constant_expression_warning (size); if (tree_int_cst_sgn (size) < 0) { - error ("size of array %qs is negative", name); + if (name) + error ("size of array %qE is negative", name); + else + error ("size of unnamed array is negative"); size = integer_one_node; } + /* Handle a size folded to an integer constant but + not an integer constant expression. */ + if (!size_int_const) + { + /* If this is a file scope declaration of an + ordinary identifier, this is invalid code; + diagnosing it here and not subsequently + treating the type as variable-length avoids + more confusing diagnostics later. */ + if ((decl_context == NORMAL || decl_context == FIELD) + && current_scope == file_scope) + pedwarn (input_location, 0, + "variably modified %qE at file scope", + name); + else + this_size_varies = size_varies = 1; + warn_variable_length_array (name, size); + } } else if ((decl_context == NORMAL || decl_context == FIELD) && current_scope == file_scope) { - error ("variably modified %qs at file scope", name); + error ("variably modified %qE at file scope", name); size = integer_one_node; } else @@ -4337,11 +4621,11 @@ grokdeclarator (const struct c_declarator *declarator, /* Make sure the array size remains visibly nonconstant even if it is (eg) a const variable with known value. */ - size_varies = 1; - warn_variable_length_array (orig_name, size); + this_size_varies = size_varies = 1; + warn_variable_length_array (name, size); } - if (integer_zerop (size)) + if (integer_zerop (size) && !this_size_varies) { /* A zero-length array cannot be represented with an unsigned index type, which is what we'll @@ -4355,7 +4639,10 @@ grokdeclarator (const struct c_declarator *declarator, MINUS_EXPR, which allows the -1 to get folded with the +1 that happens when building TYPE_SIZE. */ if (size_varies) - size = variable_size (size); + size = c_variable_size (size); + if (this_size_varies && TREE_CODE (size) == INTEGER_CST) + size = build2 (COMPOUND_EXPR, TREE_TYPE (size), + integer_zero_node, size); /* Compute the maximum valid index, that is, size - 1. Do the calculation in index_type, so that @@ -4376,33 +4663,58 @@ grokdeclarator (const struct c_declarator *declarator, if (TREE_CODE (itype) == INTEGER_CST && TREE_OVERFLOW (itype)) { - error ("size of array %qs is too large", name); + if (name) + error ("size of array %qE is too large", name); + else + error ("size of unnamed array is too large"); type = error_mark_node; continue; } itype = build_index_type (itype); } + if (this_size_varies) + { + if (*expr) + *expr = build2 (COMPOUND_EXPR, TREE_TYPE (size), + *expr, size); + else + *expr = size; + *expr_const_operands &= size_maybe_const; + } } else if (decl_context == FIELD) { - if (pedantic && !flag_isoc99 && !in_system_header) - pedwarn (OPT_pedantic, "ISO C90 does not support flexible array members"); + bool flexible_array_member = false; + if (array_parm_vla_unspec_p) + /* Field names can in fact have function prototype + scope so [*] is disallowed here through making + the field variably modified, not through being + something other than a declaration with function + prototype scope. */ + size_varies = 1; + else + { + const struct c_declarator *t = declarator; + while (t->kind == cdk_attrs) + t = t->declarator; + flexible_array_member = (t->kind == cdk_id); + } + if (flexible_array_member + && pedantic && !flag_isoc99 && !in_system_header) + pedwarn (input_location, OPT_pedantic, + "ISO C90 does not support flexible array members"); /* ISO C99 Flexible array members are effectively identical to GCC's zero-length array extension. */ - itype = build_range_type (sizetype, size_zero_node, NULL_TREE); + if (flexible_array_member || array_parm_vla_unspec_p) + itype = build_range_type (sizetype, size_zero_node, + NULL_TREE); } else if (decl_context == PARM) { if (array_parm_vla_unspec_p) { - if (! orig_name) - { - /* C99 6.7.5.2p4 */ - error ("%<[*]%> not allowed in other than a declaration"); - } - itype = build_range_type (sizetype, size_zero_node, NULL_TREE); size_varies = 1; } @@ -4411,12 +4723,14 @@ grokdeclarator (const struct c_declarator *declarator, { if (array_parm_vla_unspec_p) { - /* The error is printed elsewhere. We use this to - avoid messing up with incomplete array types of - the same type, that would otherwise be modified - below. */ + /* C99 6.7.5.2p4 */ + warning (0, "%<[*]%> not in a declaration"); + /* We use this to avoid messing up with incomplete + array types of the same type, that would + otherwise be modified below. */ itype = build_range_type (sizetype, size_zero_node, NULL_TREE); + size_varies = 1; } } @@ -4505,12 +4819,20 @@ grokdeclarator (const struct c_declarator *declarator, /* Warn about some types functions can't return. */ if (TREE_CODE (type) == FUNCTION_TYPE) { - error ("%qs declared as function returning a function", name); + if (name) + error ("%qE declared as function returning a function", + name); + else + error ("type name declared as function " + "returning a function"); type = integer_type_node; } if (TREE_CODE (type) == ARRAY_TYPE) { - error ("%qs declared as function returning an array", name); + if (name) + error ("%qE declared as function returning an array", name); + else + error ("type name declared as function returning an array"); type = integer_type_node; } @@ -4532,7 +4854,8 @@ grokdeclarator (const struct c_declarator *declarator, function definitions in ISO C; GCC used to used them for noreturn functions. */ if (VOID_TYPE_P (type) && really_funcdef) - pedwarn (0, "function definition has qualified void return type"); + pedwarn (input_location, 0, + "function definition has qualified void return type"); else warning (OPT_Wignored_qualifiers, "type qualifiers ignored on function return type"); @@ -4564,7 +4887,8 @@ grokdeclarator (const struct c_declarator *declarator, if (pedantic && TREE_CODE (type) == FUNCTION_TYPE && type_quals) - pedwarn (OPT_pedantic, "ISO C forbids qualified function types"); + pedwarn (input_location, OPT_pedantic, + "ISO C forbids qualified function types"); if (type_quals) type = c_build_qualified_type (type, type_quals); size_varies = 0; @@ -4599,7 +4923,7 @@ grokdeclarator (const struct c_declarator *declarator, tree decl = build_decl (TYPE_DECL, NULL_TREE, type); DECL_ARTIFICIAL (decl) = 1; pushdecl (decl); - finish_decl (decl, NULL_TREE, NULL_TREE); + finish_decl (decl, NULL_TREE, NULL_TREE, NULL_TREE); TYPE_NAME (type) = decl; } @@ -4623,7 +4947,7 @@ grokdeclarator (const struct c_declarator *declarator, /* Check the type and width of a bit-field. */ if (bitfield) - check_bitfield_type_and_width (&type, width, orig_name); + check_bitfield_type_and_width (&type, width, name); /* Did array size calculations overflow? */ @@ -4632,7 +4956,10 @@ grokdeclarator (const struct c_declarator *declarator, && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST && TREE_OVERFLOW (TYPE_SIZE_UNIT (type))) { - error ("size of array %qs is too large", name); + if (name) + error ("size of array %qE is too large", name); + else + error ("size of unnamed array is too large"); /* If we proceed with the array type as it is, we'll eventually crash in tree_low_cst(). */ type = error_mark_node; @@ -4645,7 +4972,8 @@ grokdeclarator (const struct c_declarator *declarator, tree decl; if (pedantic && TREE_CODE (type) == FUNCTION_TYPE && type_quals) - pedwarn (OPT_pedantic, "ISO C forbids qualified function types"); + pedwarn (input_location, OPT_pedantic, + "ISO C forbids qualified function types"); if (type_quals) type = c_build_qualified_type (type, type_quals); decl = build_decl (TYPE_DECL, declarator->u.id, type); @@ -4653,7 +4981,27 @@ grokdeclarator (const struct c_declarator *declarator, if (declspecs->explicit_signed_p) C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; if (declspecs->inline_p) - pedwarn (0, "typedef %q+D declared %", decl); + pedwarn (input_location, 0,"typedef %q+D declared %", decl); + + if (warn_cxx_compat && declarator->u.id != NULL_TREE) + { + struct c_binding *b = I_TAG_BINDING (declarator->u.id); + + if (b != NULL + && b->decl != NULL_TREE + && (B_IN_CURRENT_SCOPE (b) + || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b))) + && TYPE_MAIN_VARIANT (b->decl) != TYPE_MAIN_VARIANT (type)) + { + warning_at (declarator->id_loc, OPT_Wc___compat, + ("using %qD as both a typedef and a tag is " + "invalid in C++"), + decl); + if (b->locus != UNKNOWN_LOCATION) + inform (b->locus, "originally defined here"); + } + } + return decl; } @@ -4668,7 +5016,8 @@ grokdeclarator (const struct c_declarator *declarator, && !declspecs->inline_p); if (pedantic && TREE_CODE (type) == FUNCTION_TYPE && type_quals) - pedwarn (OPT_pedantic, "ISO C forbids const or volatile function types"); + pedwarn (input_location, OPT_pedantic, + "ISO C forbids const or volatile function types"); if (type_quals) type = c_build_qualified_type (type, type_quals); return type; @@ -4678,7 +5027,7 @@ grokdeclarator (const struct c_declarator *declarator, && variably_modified_type_p (type, NULL_TREE)) { /* C99 6.7.2.1p8 */ - pedwarn (OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "a member of a structure or union cannot have a variably modified type"); } @@ -4695,7 +5044,7 @@ grokdeclarator (const struct c_declarator *declarator, && !(storage_class == csc_static || storage_class == csc_register))))) { - error ("variable or field %qs declared void", name); + error ("variable or field %qE declared void", name); type = integer_type_node; } @@ -4733,7 +5082,8 @@ grokdeclarator (const struct c_declarator *declarator, else if (TREE_CODE (type) == FUNCTION_TYPE) { if (type_quals) - pedwarn (OPT_pedantic, "ISO C forbids qualified function types"); + pedwarn (input_location, OPT_pedantic, + "ISO C forbids qualified function types"); if (type_quals) type = c_build_qualified_type (type, type_quals); type = build_pointer_type (type); @@ -4759,7 +5109,7 @@ grokdeclarator (const struct c_declarator *declarator, DECL_ARG_TYPE (decl) = promoted_type; if (declspecs->inline_p) - pedwarn (0, "parameter %q+D declared %", decl); + pedwarn (input_location, 0, "parameter %q+D declared %", decl); } else if (decl_context == FIELD) { @@ -4772,13 +5122,16 @@ grokdeclarator (const struct c_declarator *declarator, if (TREE_CODE (type) == FUNCTION_TYPE) { - error ("field %qs declared as a function", name); + error ("field %qE declared as a function", name); type = build_pointer_type (type); } else if (TREE_CODE (type) != ERROR_MARK && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type)) { - error ("field %qs has incomplete type", name); + if (name) + error ("field %qE has incomplete type", name); + else + error ("unnamed field has incomplete type"); type = error_mark_node; } type = c_build_qualified_type (type, type_quals); @@ -4795,7 +5148,7 @@ grokdeclarator (const struct c_declarator *declarator, { if (storage_class == csc_register || threadp) { - error ("invalid storage class for function %qs", name); + error ("invalid storage class for function %qE", name); } else if (current_scope != file_scope) { @@ -4805,10 +5158,11 @@ grokdeclarator (const struct c_declarator *declarator, GCC allows 'auto', perhaps with 'inline', to support nested functions. */ if (storage_class == csc_auto) - pedwarn (OPT_pedantic, "invalid storage class for function %qs", name); + pedwarn (input_location, OPT_pedantic, + "invalid storage class for function %qE", name); else if (storage_class == csc_static) { - error ("invalid storage class for function %qs", name); + error ("invalid storage class for function %qE", name); if (funcdef_flag) storage_class = declspecs->storage_class = csc_none; else @@ -4821,7 +5175,7 @@ grokdeclarator (const struct c_declarator *declarator, decl = build_decl_attribute_variant (decl, decl_attr); if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl)) - pedwarn (OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "ISO C forbids qualified function types"); /* GNU C interprets a volatile-qualified function type to indicate @@ -4864,25 +5218,11 @@ grokdeclarator (const struct c_declarator *declarator, if (flag_hosted && MAIN_NAME_P (declarator->u.id)) { if (declspecs->inline_p) - pedwarn (0, "cannot inline function %"); + pedwarn (input_location, 0, "cannot inline function %"); } else if (declspecs->inline_p) - { - /* Record that the function is declared `inline'. */ - DECL_DECLARED_INLINE_P (decl) = 1; - - /* Do not mark bare declarations as DECL_INLINE. Doing so - in the presence of multiple declarations can result in - the abstract origin pointing between the declarations, - which will confuse dwarf2out. */ - if (initialized) - DECL_INLINE (decl) = 1; - } - /* If -finline-functions, assume it can be inlined. This does - two things: let the function be deferred until it is actually - needed, and let dwarf2 know that the function is inlinable. */ - else if (flag_inline_trees == 2 && initialized) - DECL_INLINE (decl) = 1; + /* Record that the function is declared `inline'. */ + DECL_DECLARED_INLINE_P (decl) = 1; } else { @@ -4917,7 +5257,7 @@ grokdeclarator (const struct c_declarator *declarator, C_DECL_VARIABLE_SIZE (decl) = 1; if (declspecs->inline_p) - pedwarn (0, "variable %q+D declared %", decl); + pedwarn (input_location, 0, "variable %q+D declared %", decl); /* At file scope, an initialized extern declaration may follow a static declaration. In that case, DECL_EXTERNAL will be @@ -4944,11 +5284,17 @@ grokdeclarator (const struct c_declarator *declarator, DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); } - if (storage_class == csc_extern + if ((storage_class == csc_extern + || (storage_class == csc_none + && TREE_CODE (type) == FUNCTION_TYPE + && !funcdef_flag)) && variably_modified_type_p (type, NULL_TREE)) { /* C99 6.7.5.2p2 */ - error ("object with variably modified type must have no linkage"); + if (TREE_CODE (type) == FUNCTION_TYPE) + error ("non-nested function with variably modified type"); + else + error ("object with variably modified type must have no linkage"); } /* Record `register' declaration for warnings on & @@ -5025,7 +5371,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE) { if (!funcdef_flag) - pedwarn (0, "parameter names (without types) in function declaration"); + pedwarn (input_location, 0, "parameter names (without types) in function declaration"); arg_info->parms = arg_info->types; arg_info->types = 0; @@ -5276,13 +5622,19 @@ get_parm_info (bool ellipsis) Return a c_typespec structure for the type specifier. */ struct c_typespec -parser_xref_tag (enum tree_code code, tree name) +parser_xref_tag (enum tree_code code, tree name, location_t loc) { struct c_typespec ret; + tree ref; + location_t refloc; + + ret.expr = NULL_TREE; + ret.expr_const_operands = true; + /* If a cross reference is requested, look up the type already defined for this tag and return it. */ - tree ref = lookup_tag (code, name, 0); + ref = lookup_tag (code, name, 0, &refloc); /* If this is the right type of tag, return what we found. (This reference will be shadowed by shadow_tag later if appropriate.) If this is the wrong type of tag, do not return it. If it was the @@ -5297,6 +5649,35 @@ parser_xref_tag (enum tree_code code, tree name) ret.kind = (ref ? ctsk_tagref : ctsk_tagfirstref); if (ref && TREE_CODE (ref) == code) { + if (C_TYPE_DEFINED_IN_STRUCT (ref) + && loc != UNKNOWN_LOCATION + && warn_cxx_compat) + { + switch (code) + { + case ENUMERAL_TYPE: + warning_at (loc, OPT_Wc___compat, + ("enum type defined in struct or union " + "is not visible in C++")); + inform (refloc, "enum type defined here"); + break; + case RECORD_TYPE: + warning_at (loc, OPT_Wc___compat, + ("struct defined in struct or union " + "is not visible in C++")); + inform (refloc, "struct defined here"); + break; + case UNION_TYPE: + warning_at (loc, OPT_Wc___compat, + ("union defined in struct or union " + "is not visible in C++")); + inform (refloc, "union defined here"); + break; + default: + gcc_unreachable(); + } + } + ret.spec = ref; return ret; } @@ -5311,7 +5692,7 @@ parser_xref_tag (enum tree_code code, tree name) { /* Give the type a default layout like unsigned int to avoid crashing if it does not get defined. */ - TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); + SET_TYPE_MODE (ref, TYPE_MODE (unsigned_type_node)); TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); TYPE_USER_ALIGN (ref) = 0; TYPE_UNSIGNED (ref) = 1; @@ -5320,7 +5701,7 @@ parser_xref_tag (enum tree_code code, tree name) TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node); } - pushtag (name, ref); + pushtag (name, ref, loc); ret.spec = ref; return ret; @@ -5333,38 +5714,53 @@ parser_xref_tag (enum tree_code code, tree name) tree xref_tag (enum tree_code code, tree name) { - return parser_xref_tag (code, name).spec; + return parser_xref_tag (code, name, UNKNOWN_LOCATION).spec; } /* Make sure that the tag NAME is defined *in the current scope* at least as a forward reference. - CODE says which kind of tag NAME ought to be. */ + CODE says which kind of tag NAME ought to be. + + This stores the current value of the file static IN_STRUCT in + *ENCLOSING_IN_STRUCT, and sets IN_STRUCT to true. Similarly, this + sets STRUCT_TYPES in *ENCLOSING_STRUCT_TYPES, and sets STRUCT_TYPES + to an empty vector. The old values are restored in + finish_struct. */ tree -start_struct (enum tree_code code, tree name) +start_struct (enum tree_code code, tree name, bool *enclosing_in_struct, + VEC(tree,heap) **enclosing_struct_types, location_t loc) { /* If there is already a tag defined at this scope (as a forward reference), just return it. */ - tree ref = 0; + tree ref = NULL_TREE; + location_t refloc = UNKNOWN_LOCATION; - if (name != 0) - ref = lookup_tag (code, name, 1); + if (name != NULL_TREE) + ref = lookup_tag (code, name, 1, &refloc); if (ref && TREE_CODE (ref) == code) { if (TYPE_SIZE (ref)) { if (code == UNION_TYPE) - error ("redefinition of %", name); + error_at (loc, "redefinition of %", name); else - error ("redefinition of %", name); + error_at (loc, "redefinition of %", name); + if (refloc != UNKNOWN_LOCATION) + inform (refloc, "originally defined here"); + /* Don't create structures using a name already in use. */ + ref = NULL_TREE; } else if (C_TYPE_BEING_DEFINED (ref)) { if (code == UNION_TYPE) - error ("nested redefinition of %", name); + error_at (loc, "nested redefinition of %", name); else - error ("nested redefinition of %", name); + error_at (loc, "nested redefinition of %", name); + /* Don't bother to report "originally defined here" for a + nested redefinition; the original definition should be + obvious. */ /* Don't create structures that contain themselves. */ ref = NULL_TREE; } @@ -5375,11 +5771,28 @@ start_struct (enum tree_code code, tree name) if (ref == NULL_TREE || TREE_CODE (ref) != code) { ref = make_node (code); - pushtag (name, ref); + pushtag (name, ref, loc); } C_TYPE_BEING_DEFINED (ref) = 1; TYPE_PACKED (ref) = flag_pack_struct; + + *enclosing_in_struct = in_struct; + *enclosing_struct_types = struct_types; + in_struct = true; + struct_types = VEC_alloc(tree, heap, 0); + + /* FIXME: This will issue a warning for a use of a type defined + within a statement expr used within sizeof, et. al. This is not + terribly serious as C++ doesn't permit statement exprs within + sizeof anyhow. */ + if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof)) + warning_at (loc, OPT_Wc___compat, + "defining type in %qs expression is invalid in C++", + (in_sizeof + ? "sizeof" + : (in_typeof ? "typeof" : "alignof"))); + return ref; } @@ -5388,12 +5801,15 @@ start_struct (enum tree_code code, tree name) WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node. DECL_ATTRS is as for grokdeclarator. + LOC is the location of the structure component. + This is done during the parsing of the struct declaration. The FIELD_DECL nodes are chained together and the lot of them are ultimately passed to `build_struct' to make the RECORD_TYPE node. */ tree -grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs, +grokfield (location_t loc, + struct c_declarator *declarator, struct c_declspecs *declspecs, tree width, tree *decl_attrs) { tree value; @@ -5439,17 +5855,17 @@ grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs, } if (!ok) { - pedwarn (0, "declaration does not declare anything"); + pedwarn (loc, 0, "declaration does not declare anything"); return NULL_TREE; } - pedwarn (OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions"); + pedwarn (loc, OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions"); } value = grokdeclarator (declarator, declspecs, FIELD, false, - width ? &width : NULL, decl_attrs, + width ? &width : NULL, decl_attrs, NULL, NULL, DEPRECATED_NORMAL); - finish_decl (value, NULL_TREE, NULL_TREE); + finish_decl (value, NULL_TREE, NULL_TREE, NULL_TREE); DECL_INITIAL (value) = width; return value; @@ -5514,14 +5930,22 @@ detect_field_duplicates (tree fieldlist) /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T. FIELDLIST is a chain of FIELD_DECL nodes for the fields. - ATTRIBUTES are attributes to be applied to the structure. */ + ATTRIBUTES are attributes to be applied to the structure. + + ENCLOSING_IN_STRUCT is the value of IN_STRUCT, and + ENCLOSING_STRUCT_TYPES is the value of STRUCT_TYPES, when the + struct was started. This sets the C_TYPE_DEFINED_IN_STRUCT flag + for any type defined in the current struct. */ tree -finish_struct (tree t, tree fieldlist, tree attributes) +finish_struct (tree t, tree fieldlist, tree attributes, + bool enclosing_in_struct, + VEC(tree,heap) *enclosing_struct_types) { tree x; bool toplevel = file_scope == current_scope; int saw_named_field; + unsigned int ix; /* If this type was previously laid out as a forward reference, make sure we lay it out again. */ @@ -5541,16 +5965,16 @@ finish_struct (tree t, tree fieldlist, tree attributes) if (TREE_CODE (t) == UNION_TYPE) { if (fieldlist) - pedwarn (OPT_pedantic, "union has no named members"); + pedwarn (input_location, OPT_pedantic, "union has no named members"); else - pedwarn (OPT_pedantic, "union has no members"); + pedwarn (input_location, OPT_pedantic, "union has no members"); } else { if (fieldlist) - pedwarn (OPT_pedantic, "struct has no named members"); + pedwarn (input_location, OPT_pedantic, "struct has no named members"); else - pedwarn (OPT_pedantic, "struct has no members"); + pedwarn (input_location, OPT_pedantic, "struct has no members"); } } } @@ -5570,9 +5994,6 @@ finish_struct (tree t, tree fieldlist, tree attributes) DECL_CONTEXT (x) = t; - if (TYPE_PACKED (t) && TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT) - DECL_PACKED (x) = 1; - /* If any field is const, the structure type is pseudo-const. */ if (TREE_READONLY (x)) C_TYPE_FIELDS_READONLY (t) = 1; @@ -5604,6 +6025,11 @@ finish_struct (tree t, tree fieldlist, tree attributes) SET_DECL_C_BIT_FIELD (x); } + if (TYPE_PACKED (t) + && (DECL_BIT_FIELD (x) + || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)) + DECL_PACKED (x) = 1; + /* Detect flexible array member in an invalid context. */ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE @@ -5629,7 +6055,7 @@ finish_struct (tree t, tree fieldlist, tree attributes) if (pedantic && !in_system_header && TREE_CODE (t) == RECORD_TYPE && flexible_array_type_p (TREE_TYPE (x))) - pedwarn (OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "%Jinvalid use of structure with flexible array member", x); if (DECL_NAME (x)) @@ -5772,6 +6198,24 @@ finish_struct (tree t, tree fieldlist, tree attributes) if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE)) add_stmt (build_stmt (DECL_EXPR, build_decl (TYPE_DECL, NULL, t))); + /* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in + the current struct. We do this now at the end of the struct + because the flag is used to issue visibility warnings when using + -Wc++-compat, and we only want to issue those warnings if the + type is referenced outside of the struct declaration. */ + for (ix = 0; VEC_iterate (tree, struct_types, ix, x); ++ix) + C_TYPE_DEFINED_IN_STRUCT (x) = 1; + + VEC_free (tree, heap, struct_types); + + in_struct = enclosing_in_struct; + struct_types = enclosing_struct_types; + + /* If this struct is defined inside a struct, add it to + STRUCT_TYPES. */ + if (in_struct && !in_sizeof && !in_typeof && !in_alignof) + VEC_safe_push (tree, heap, struct_types, t); + return t; } @@ -5792,32 +6236,35 @@ layout_array_type (tree t) may be used to declare the individual values as they are read. */ tree -start_enum (struct c_enum_contents *the_enum, tree name) +start_enum (struct c_enum_contents *the_enum, tree name, location_t loc) { - tree enumtype = 0; + tree enumtype = NULL_TREE; + location_t enumloc = UNKNOWN_LOCATION; /* If this is the real definition for a previous forward reference, fill in the contents in the same object that used to be the forward reference. */ - if (name != 0) - enumtype = lookup_tag (ENUMERAL_TYPE, name, 1); + if (name != NULL_TREE) + enumtype = lookup_tag (ENUMERAL_TYPE, name, 1, &enumloc); if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE) { enumtype = make_node (ENUMERAL_TYPE); - pushtag (name, enumtype); + pushtag (name, enumtype, loc); } if (C_TYPE_BEING_DEFINED (enumtype)) - error ("nested redefinition of %", name); + error_at (loc, "nested redefinition of %", name); C_TYPE_BEING_DEFINED (enumtype) = 1; if (TYPE_VALUES (enumtype) != 0) { /* This enum is a named one that has been declared already. */ - error ("redeclaration of %", name); + error_at (loc, "redeclaration of %", name); + if (enumloc != UNKNOWN_LOCATION) + inform (enumloc, "originally defined here"); /* Completely replace its old definition. The old enumerators remain defined, however. */ @@ -5830,6 +6277,16 @@ start_enum (struct c_enum_contents *the_enum, tree name) if (flag_short_enums) TYPE_PACKED (enumtype) = 1; + /* FIXME: This will issue a warning for a use of a type defined + within sizeof in a statement expr. This is not terribly serious + as C++ doesn't permit statement exprs within sizeof anyhow. */ + if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof)) + warning_at (loc, OPT_Wc___compat, + "defining type in %qs expression is invalid in C++", + (in_sizeof + ? "sizeof" + : (in_typeof ? "typeof" : "alignof"))); + return enumtype; } @@ -5872,8 +6329,8 @@ finish_enum (tree enumtype, tree values, tree attributes) that normally we only go as narrow as int - and signed iff any of the values are negative. */ unsign = (tree_int_cst_sgn (minnode) >= 0); - precision = MAX (min_precision (minnode, unsign), - min_precision (maxnode, unsign)); + precision = MAX (tree_int_cst_min_precision (minnode, unsign), + tree_int_cst_min_precision (maxnode, unsign)); if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node)) { @@ -5922,16 +6379,16 @@ finish_enum (tree enumtype, tree values, tree attributes) /* The ISO C Standard mandates enumerators to have type int, even though the underlying type of an enum type is - unspecified. Here we convert any enumerators that fit in - an int to type int, to avoid promotions to unsigned types - when comparing integers with enumerators that fit in the - int range. When -pedantic is given, build_enumerator() - would have already taken care of those that don't fit. */ - if (int_fits_type_p (ini, integer_type_node)) - tem = integer_type_node; - else - tem = enumtype; - ini = convert (tem, ini); + unspecified. However, GCC allows enumerators of any + integer type as an extensions. build_enumerator() + converts any enumerators that fit in an int to type int, + to avoid promotions to unsigned types when comparing + integers with enumerators that fit in the int range. + When -pedantic is given, build_enumerator() would have + already warned about those that don't fit. Here we + convert the rest to the enumerator type. */ + if (TREE_TYPE (ini) != integer_type_node) + ini = convert (enumtype, ini); DECL_INITIAL (enu) = ini; TREE_PURPOSE (pair) = DECL_NAME (enu); @@ -5958,7 +6415,7 @@ finish_enum (tree enumtype, tree values, tree attributes) TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); TYPE_SIZE (tem) = TYPE_SIZE (enumtype); TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype); - TYPE_MODE (tem) = TYPE_MODE (enumtype); + SET_TYPE_MODE (tem, TYPE_MODE (enumtype)); TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype); @@ -5969,6 +6426,11 @@ finish_enum (tree enumtype, tree values, tree attributes) /* Finish debugging output for this type. */ rest_of_type_compilation (enumtype, toplevel); + /* If this enum is defined inside a struct, add it to + STRUCT_TYPES. */ + if (in_struct && !in_sizeof && !in_typeof && !in_alignof) + VEC_safe_push (tree, heap, struct_types, enumtype); + return enumtype; } @@ -5978,7 +6440,8 @@ finish_enum (tree enumtype, tree values, tree attributes) Assignment of sequential values by default is handled here. */ tree -build_enumerator (struct c_enum_contents *the_enum, tree name, tree value) +build_enumerator (struct c_enum_contents *the_enum, tree name, tree value, + location_t value_loc) { tree decl, type; @@ -5990,16 +6453,32 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value) undeclared identifier) - just ignore the value expression. */ if (value == error_mark_node) value = 0; - else if (!INTEGRAL_TYPE_P (TREE_TYPE (value)) - || TREE_CODE (value) != INTEGER_CST) + else if (!INTEGRAL_TYPE_P (TREE_TYPE (value))) { error ("enumerator value for %qE is not an integer constant", name); value = 0; } else { - value = default_conversion (value); - constant_expression_warning (value); + if (TREE_CODE (value) != INTEGER_CST) + { + value = c_fully_fold (value, false, NULL); + if (TREE_CODE (value) == INTEGER_CST) + pedwarn (value_loc, OPT_pedantic, + "enumerator value for %qE is not an integer " + "constant expression", name); + } + if (TREE_CODE (value) != INTEGER_CST) + { + error ("enumerator value for %qE is not an integer constant", + name); + value = 0; + } + else + { + value = default_conversion (value); + constant_expression_warning (value); + } } } @@ -6012,18 +6491,31 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value) if (the_enum->enum_overflow) error ("overflow in enumeration values"); } - - if (pedantic && !int_fits_type_p (value, integer_type_node)) - { - pedwarn (OPT_pedantic, "ISO C restricts enumerator values to range of %"); - /* XXX This causes -pedantic to change the meaning of the program. - Remove? -zw 2004-03-15 */ - value = convert (integer_type_node, value); - } + /* Even though the underlying type of an enum is unspecified, the + type of enumeration constants is explicitly defined as int + (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 (value_loc, OPT_pedantic, + "ISO C restricts enumerator values to range of %"); + + /* The ISO C Standard mandates enumerators to have type int, even + though the underlying type of an enum type is unspecified. + However, GCC allows enumerators of any integer type as an + extensions. Here we convert any enumerators that fit in an int + to type int, to avoid promotions to unsigned types when comparing + integers with enumerators that fit in the int range. When + -pedantic is given, we would have already warned about those that + don't fit. We have to do this here rather than in finish_enum + because this value may be used to define more enumerators. */ + if (int_fits_type_p (value, integer_type_node)) + value = convert (integer_type_node, value); /* Set basis for default for next value. */ - the_enum->enum_next_value = build_binary_op (PLUS_EXPR, value, - integer_one_node, 0); + the_enum->enum_next_value + = build_binary_op + (EXPR_HAS_LOCATION (value) ? EXPR_LOCATION (value) : input_location, + PLUS_EXPR, value, integer_one_node, 0); the_enum->enum_overflow = tree_int_cst_lt (the_enum->enum_next_value, value); /* Now create a declaration for the enum value name. */ @@ -6089,7 +6581,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, c_break_label = c_cont_label = size_zero_node; decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL, - &attributes, DEPRECATED_NORMAL); + &attributes, NULL, NULL, DEPRECATED_NORMAL); /* If the declarator is not suitable for a function definition, cause a syntax error. */ @@ -6131,7 +6623,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, } if (warn_about_return_type) - pedwarn_c99 (flag_isoc99 ? 0 + pedwarn_c99 (input_location, flag_isoc99 ? 0 : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int), "return type defaults to %"); @@ -6250,16 +6742,16 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, maybe_apply_pragma_weak (decl1); /* Warn for unlikely, improbable, or stupid declarations of `main'. */ - if (warn_main > 0 && MAIN_NAME_P (DECL_NAME (decl1))) + if (warn_main && MAIN_NAME_P (DECL_NAME (decl1))) { if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1))) != integer_type_node) - pedwarn (OPT_Wmain, "return type of %q+D is not %", decl1); + pedwarn (input_location, OPT_Wmain, "return type of %q+D is not %", decl1); - check_main_parameter_types(decl1); + check_main_parameter_types (decl1); if (!TREE_PUBLIC (decl1)) - pedwarn (OPT_Wmain, "%q+D is normally a non-static function", decl1); + pedwarn (input_location, OPT_Wmain, "%q+D is normally a non-static function", decl1); } /* Record the decl so that the function name is defined. @@ -6318,7 +6810,8 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info) if (DECL_NAME (decl)) { bind (DECL_NAME (decl), decl, current_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, + UNKNOWN_LOCATION); if (!TREE_USED (decl)) warn_if_shadowing (decl); } @@ -6335,14 +6828,14 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info) DECL_CONTEXT (decl) = current_function_decl; if (DECL_NAME (decl)) bind (DECL_NAME (decl), decl, current_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } /* And all the tag declarations. */ for (decl = arg_info->tags; decl; decl = TREE_CHAIN (decl)) if (TREE_PURPOSE (decl)) bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope, - /*invisible=*/false, /*nested=*/false); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } /* Subroutine of store_parm_decls which handles old-style function @@ -6407,7 +6900,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) warn_if_shadowing (decl); if (flag_isoc99) - pedwarn (0, "type of %q+D defaults to %", decl); + pedwarn (input_location, 0, "type of %q+D defaults to %", decl); else warning (OPT_Wmissing_parameter_type, "type of %q+D defaults to %", decl); } @@ -6527,10 +7020,10 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) "doesn%'t match built-in prototype", parm); else { - pedwarn (OPT_pedantic, "promoted argument %qD " + pedwarn (input_location, OPT_pedantic, "promoted argument %qD " "doesn%'t match prototype", parm); - pedwarn (OPT_pedantic, "%Hprototype declaration", - ¤t_function_prototype_locus); + pedwarn (current_function_prototype_locus, OPT_pedantic, + "prototype declaration"); } } else @@ -6665,9 +7158,10 @@ static void c_gimple_diagnostics_recursively (tree fndecl) { struct cgraph_node *cgn; + gimple_seq body = gimple_body (fndecl); /* Handle attribute((warn_unused_result)). Relies on gimple input. */ - c_warn_unused_result (&DECL_SAVED_TREE (fndecl)); + c_warn_unused_result (body); /* Notice when OpenMP structured block constraints are violated. */ if (flag_openmp) @@ -6714,30 +7208,18 @@ finish_function (void) if (DECL_RESULT (fndecl) && DECL_RESULT (fndecl) != error_mark_node) DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; - if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted) + if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted + && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) + == integer_type_node && flag_isoc99) { - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) - != integer_type_node) - { - /* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned. - If warn_main is -1 (-Wno-main) we don't want to be warned. */ - if (!warn_main) - pedwarn (0, "return type of %q+D is not %", fndecl); - } - else - { - if (flag_isoc99) - { - tree stmt = c_finish_return (integer_zero_node); - /* 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); - } - } + tree stmt = c_finish_return (integer_zero_node, NULL_TREE); + /* Hack. We don't want the middle-end to warn that this return + is unreachable, so we mark its location as special. Using + UNKNOWN_LOCATION has the problem that it gets clobbered in + 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); } /* Tie off the statement tree for this function. */ @@ -6755,9 +7237,9 @@ finish_function (void) && !MAIN_NAME_P (DECL_NAME (fndecl)) /* Or if they didn't actually specify a return type. */ && !C_FUNCTION_IMPLICIT_INT (fndecl) - /* Normally, with -Wreturn-type, flow will complain. Unless we're an - inline function, as we might never be compiled separately. */ - && DECL_INLINE (fndecl)) + /* Normally, with -Wreturn-type, flow will complain, but we might + optimize out static functions. */ + && !TREE_PUBLIC (fndecl)) { warning (OPT_Wreturn_type, "no return statement in function returning non-void"); @@ -6827,13 +7309,19 @@ check_for_loop_decls (void) tree one_decl = NULL_TREE; int n_decls = 0; - if (!flag_isoc99) { + static bool hint = true; /* If we get here, declarations have been used in a for loop without the C99 for loop scope. This doesn't make much sense, so don't allow it. */ - error ("% loop initial declaration used outside C99 mode"); + error ("% loop initial declarations are only allowed in C99 mode"); + if (hint) + { + inform (input_location, + "use option -std=c99 or -std=gnu99 to compile your code"); + hint = false; + } return NULL_TREE; } /* C99 subclause 6.8.5 paragraph 3: @@ -6978,15 +7466,6 @@ current_stmt_tree (void) return &c_stmt_tree; } -/* Nonzero if TYPE is an anonymous union or struct type. Always 0 in - C. */ - -int -anon_aggr_type_p (const_tree ARG_UNUSED (node)) -{ - return 0; -} - /* Return the global value of T as a symbol. */ tree @@ -7116,10 +7595,12 @@ build_null_declspecs (void) { struct c_declspecs *ret = XOBNEW (&parser_obstack, struct c_declspecs); ret->type = 0; + ret->expr = 0; ret->decl_attr = 0; ret->attrs = 0; ret->typespec_word = cts_none; ret->storage_class = csc_none; + ret->expr_const_operands = true; ret->declspecs_seen_p = false; ret->type_seen_p = false; ret->non_sc_seen_p = false; @@ -7174,7 +7655,7 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual) gcc_unreachable (); } if (dupe && !flag_isoc99) - pedwarn (OPT_pedantic, "duplicate %qE", qual); + pedwarn (input_location, OPT_pedantic, "duplicate %qE", qual); return specs; } @@ -7222,8 +7703,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) "declaration specifiers"); break; } - if (pedantic && !flag_isoc99 && !in_system_header) - pedwarn (OPT_Wlong_long, "ISO C90 does not support %"); + pedwarn_c90 (input_location, OPT_Wlong_long, + "ISO C90 does not support %"); specs->long_long_p = 1; break; } @@ -7347,7 +7828,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) case RID_COMPLEX: dupe = specs->complex_p; if (!flag_isoc99 && !in_system_header) - pedwarn (OPT_pedantic, "ISO C90 does not support complex types"); + pedwarn (input_location, OPT_pedantic, "ISO C90 does not support complex types"); if (specs->typespec_word == cts_void) error ("both % and % in " "declaration specifiers"); @@ -7377,7 +7858,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) break; case RID_SAT: dupe = specs->saturating_p; - pedwarn (OPT_pedantic, "ISO C does not support saturating types"); + pedwarn (input_location, OPT_pedantic, "ISO C does not support saturating types"); if (specs->typespec_word == cts_void) error ("both %<_Sat%> and % in " "declaration specifiers"); @@ -7574,7 +8055,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) } if (!targetm.decimal_float_supported_p ()) error ("decimal floating point not supported for this target"); - pedwarn (OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "ISO C does not support decimal floating point"); return specs; case RID_FRACT: @@ -7595,7 +8076,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) } if (!targetm.fixed_point_supported_p ()) error ("fixed-point types not supported for this target"); - pedwarn (OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "ISO C does not support fixed-point types"); return specs; default: @@ -7641,7 +8122,18 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) if (spec.kind == ctsk_tagdef || spec.kind == ctsk_tagfirstref) specs->tag_defined_p = true; if (spec.kind == ctsk_typeof) - specs->typedef_p = true; + { + specs->typedef_p = true; + if (spec.expr) + { + if (specs->expr) + specs->expr = build2 (COMPOUND_EXPR, TREE_TYPE (spec.expr), + specs->expr, spec.expr); + else + specs->expr = spec.expr; + specs->expr_const_operands &= spec.expr_const_operands; + } + } specs->type = type; } @@ -7772,6 +8264,8 @@ finish_declspecs (struct c_declspecs *specs) if (specs->saturating_p) { error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>"); + if (!targetm.fixed_point_supported_p ()) + error ("fixed-point types not supported for this target"); specs->typespec_word = cts_fract; } else if (specs->long_p || specs->short_p @@ -7782,7 +8276,7 @@ finish_declspecs (struct c_declspecs *specs) else if (specs->complex_p) { specs->typespec_word = cts_double; - pedwarn (OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "ISO C does not support plain % meaning " "%"); } @@ -7827,7 +8321,7 @@ finish_declspecs (struct c_declspecs *specs) specs->type = char_type_node; if (specs->complex_p) { - pedwarn (OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "ISO C does not support complex integer types"); specs->type = build_complex_type (specs->type); } @@ -7853,7 +8347,7 @@ finish_declspecs (struct c_declspecs *specs) : integer_type_node); if (specs->complex_p) { - pedwarn (OPT_pedantic, + pedwarn (input_location, OPT_pedantic, "ISO C does not support complex integer types"); specs->type = build_complex_type (specs->type); } @@ -7894,8 +8388,10 @@ finish_declspecs (struct c_declspecs *specs) specs->type = dfloat128_type_node; break; case cts_fract: - gcc_assert (!specs->complex_p); - if (specs->saturating_p) + gcc_assert (!specs->complex_p); + if (!targetm.fixed_point_supported_p ()) + specs->type = integer_type_node; + else if (specs->saturating_p) { if (specs->long_long_p) specs->type = specs->unsigned_p @@ -7913,7 +8409,7 @@ finish_declspecs (struct c_declspecs *specs) specs->type = specs->unsigned_p ? sat_unsigned_fract_type_node : sat_fract_type_node; - } + } else { if (specs->long_long_p) @@ -7932,11 +8428,13 @@ finish_declspecs (struct c_declspecs *specs) specs->type = specs->unsigned_p ? unsigned_fract_type_node : fract_type_node; - } + } break; case cts_accum: - gcc_assert (!specs->complex_p); - if (specs->saturating_p) + gcc_assert (!specs->complex_p); + if (!targetm.fixed_point_supported_p ()) + specs->type = integer_type_node; + else if (specs->saturating_p) { if (specs->long_long_p) specs->type = specs->unsigned_p @@ -7954,7 +8452,7 @@ finish_declspecs (struct c_declspecs *specs) specs->type = specs->unsigned_p ? sat_unsigned_accum_type_node : sat_accum_type_node; - } + } else { if (specs->long_long_p) @@ -7973,7 +8471,7 @@ finish_declspecs (struct c_declspecs *specs) specs->type = specs->unsigned_p ? unsigned_accum_type_node : accum_type_node; - } + } break; default: gcc_unreachable (); @@ -8004,7 +8502,7 @@ c_write_global_declarations_1 (tree globals) && !TREE_PUBLIC (decl) && C_DECL_USED (decl)) { - pedwarn (0, "%q+F used but never defined", decl); + pedwarn (input_location, 0, "%q+F used but never defined", decl); TREE_NO_WARNING (decl) = 1; } @@ -8049,7 +8547,7 @@ c_write_global_declarations (void) /* Don't waste time on further processing if -fsyntax-only or we've encountered errors. */ - if (flag_syntax_only || errorcount || sorrycount || cpp_errors (parse_in)) + if (flag_syntax_only || errorcount || sorrycount) return; /* Close the external scope. */