/* Process declarations and variables for C compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
#include "c-family/c-pragma.h"
#include "c-lang.h"
#include "langhooks.h"
-#include "tree-mudflap.h"
#include "tree-iterator.h"
#include "diagnostic-core.h"
#include "tree-dump.h"
static bool undef_nested_function;
+/* Mode used to build pointers (VOIDmode means ptr_mode). */
+
+enum machine_mode c_default_pointer_mode = VOIDmode;
+
\f
/* Each c_binding structure describes one binding of an identifier to
a decl. All the decls in a scope - irrespective of namespace - are
return t;
}
+\f
+/* Build a pointer type using the default pointer mode. */
+
+static tree
+c_build_pointer_type (tree to_type)
+{
+ addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
+ : TYPE_ADDR_SPACE (to_type);
+ enum machine_mode pointer_mode;
+
+ if (as != ADDR_SPACE_GENERIC || c_default_pointer_mode == VOIDmode)
+ pointer_mode = targetm.addr_space.pointer_mode (as);
+ else
+ pointer_mode = c_default_pointer_mode;
+ return build_pointer_type_for_mode (to_type, pointer_mode, false);
+}
+
\f
/* Return true if we will want to say something if a goto statement
crosses DECL. */
complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
- layout_decl (decl, 0);
+ relayout_decl (decl);
}
}
}
DECL_CHAIN (p) = BLOCK_VARS (block);
BLOCK_VARS (block) = p;
}
- else if (VAR_OR_FUNCTION_DECL_P (p))
+ else if (VAR_OR_FUNCTION_DECL_P (p) && scope != file_scope)
{
/* For block local externs add a special
DECL_EXTERNAL decl for debug info generation. */
/* Redeclaration of a type is a constraint violation (6.7.2.3p1),
but silently ignore the redeclaration if either is in a system
header. (Conflicting redeclarations were handled above.) This
- is allowed for C1X if the types are the same, not just
+ is allowed for C11 if the types are the same, not just
compatible. */
if (TREE_CODE (newdecl) == TYPE_DECL)
{
newdecl);
locate_old_decl (olddecl);
}
- else if (pedantic && !flag_isoc1x)
+ else if (pedantic && !flag_isoc11)
{
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (input_location, OPT_Wpedantic,
"redefinition of typedef %q+D", newdecl);
locate_old_decl (olddecl);
}
&& prototype_p (TREE_TYPE (newdecl)));
bool old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL
&& prototype_p (TREE_TYPE (olddecl)));
- bool extern_changed = false;
/* For real parm decl following a forward decl, rechain the old decl
in its new location and clear TREE_ASM_WRITTEN (it's not a
DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
C_DECL_DECLARED_BUILTIN (newdecl) = 1;
if (new_is_prototype)
- C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0;
+ {
+ C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0;
+ if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
+ {
+ enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
+ switch (fncode)
+ {
+ /* If a compatible prototype of these builtin functions
+ is seen, assume the runtime implements it with the
+ expected semantics. */
+ case BUILT_IN_STPCPY:
+ if (builtin_decl_explicit_p (fncode))
+ set_builtin_decl_implicit_p (fncode, true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
else
C_DECL_BUILTIN_PROTOTYPE (newdecl)
= C_DECL_BUILTIN_PROTOTYPE (olddecl);
}
}
- extern_changed = DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl);
-
/* Merge the USED information. */
if (TREE_USED (olddecl))
TREE_USED (newdecl) = 1;
memcpy ((char *) olddecl + sizeof (struct tree_common),
(char *) newdecl + sizeof (struct tree_common),
sizeof (struct tree_decl_common) - sizeof (struct tree_common));
+ DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl);
switch (TREE_CODE (olddecl))
{
case FUNCTION_DECL:
|| (TREE_CODE (olddecl) == VAR_DECL
&& TREE_STATIC (olddecl))))
make_decl_rtl (olddecl);
-
- /* If we changed a function from DECL_EXTERNAL to !DECL_EXTERNAL,
- and the definition is coming from the old version, cgraph needs
- to be called again. */
- if (extern_changed && !new_is_definition
- && TREE_CODE (olddecl) == FUNCTION_DECL && DECL_INITIAL (olddecl))
- cgraph_mark_if_needed (olddecl);
}
/* Handle when a new declaration NEWDECL has the same name as an old
/* Is anything being shadowed? Invisible decls do not count. */
for (b = I_SYMBOL_BINDING (DECL_NAME (new_decl)); b; b = b->shadowed)
- if (b->decl && b->decl != new_decl && !b->invisible)
+ if (b->decl && b->decl != new_decl && !b->invisible
+ && (b->decl == error_mark_node
+ || diagnostic_report_warnings_p (global_dc,
+ DECL_SOURCE_LOCATION (b->decl))))
{
tree old_decl = b->decl;
skip_external_and_shadow_checks:
if (TREE_CODE (x) == TYPE_DECL)
- set_underlying_type (x);
+ {
+ /* So this is a typedef, set its underlying type. */
+ set_underlying_type (x);
+
+ /* If X is a typedef defined in the current function, record it
+ for the purpose of implementing the -Wunused-local-typedefs
+ warning. */
+ record_locally_defined_typedef (x);
+ }
bind (name, x, scope, /*invisible=*/false, nested, locus);
{
struct c_binding *b = I_SYMBOL_BINDING (name);
if (b && !b->invisible)
- return b->decl;
+ {
+ maybe_record_typedef_use (b->decl);
+ return b->decl;
+ }
return 0;
}
warned = 1;
pending_xref_error ();
}
+ else if (declspecs->typespec_kind != ctsk_tagdef
+ && declspecs->typespec_kind != ctsk_tagfirstref
+ && declspecs->alignas_p)
+ {
+ if (warned != 1)
+ pedwarn (input_location, 0,
+ "empty declaration with %<_Alignas%> "
+ "does not redeclare tag");
+ warned = 1;
+ pending_xref_error ();
+ }
else
{
pending_invalid_xref = 0;
warned = 1;
}
+ if (declspecs->noreturn_p)
+ {
+ error ("%<_Noreturn%> in empty declaration");
+ warned = 1;
+ }
+
if (current_scope == file_scope && declspecs->storage_class == csc_auto)
{
error ("%<auto%> in file-scope empty declaration");
warned = 2;
}
+ if (!warned && !in_system_header && declspecs->alignas_p)
+ {
+ warning (0, "useless %<_Alignas%> in empty declaration");
+ warned = 2;
+ }
+
if (warned != 1)
{
if (!found_tag)
&& !specs->unsigned_p
&& !specs->complex_p
&& !specs->inline_p
+ && !specs->noreturn_p
&& !specs->thread_p);
return quals;
}
if (!flag_isoc99)
{
if (static_p || quals != NULL)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C90 does not support %<static%> or type "
"qualifiers in parameter array declarators");
if (vla_unspec_p)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C90 does not support %<[*]%> array declarators");
}
if (vla_unspec_p)
if (DECL_INITIAL (decl))
TREE_TYPE (DECL_INITIAL (decl)) = type;
- layout_decl (decl, 0);
+ relayout_decl (decl);
}
if (TREE_CODE (decl) == VAR_DECL)
}
/* If this is a function and an assembler name is specified, reset DECL_RTL
- so we can give it its new name. Also, update built_in_decls if it
+ so we can give it its new name. Also, update builtin_decl if it
was a normal built-in. */
if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
{
&& C_TYPE_FIELDS_READONLY (type))
diagnose_uninitialized_cst_member (decl, type);
}
+
+ invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
}
/* Given a parsed parameter declaration, decode it into a PARM_DECL.
if (pedantic && !current_scope->warned_forward_parm_decls)
{
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (input_location, OPT_Wpedantic,
"ISO C forbids forward parameter declarations");
current_scope->warned_forward_parm_decls = true;
}
TREE_USED (decl) = 1;
DECL_READ_P (decl) = 1;
TREE_TYPE (decl) = type;
- TREE_READONLY (decl) = TYPE_READONLY (type);
+ TREE_READONLY (decl) = (TYPE_READONLY (type)
+ || (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_READONLY (TREE_TYPE (type))));
store_init_value (loc, decl, init, NULL_TREE);
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
{
*width = c_fully_fold (*width, false, NULL);
if (TREE_CODE (*width) == INTEGER_CST)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (input_location, OPT_Wpedantic,
"bit-field %qs width not an integer constant expression",
name);
}
&& type_mv != integer_type_node
&& type_mv != unsigned_type_node
&& type_mv != boolean_type_node)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (input_location, OPT_Wpedantic,
"type of bit-field %qs is a GCC extension", name);
max_width = TYPE_PRECISION (*type);
tree expr_dummy;
bool expr_const_operands_dummy;
enum c_declarator_kind first_non_attr_kind;
+ unsigned int alignas_align = 0;
if (TREE_CODE (type) == ERROR_MARK)
return error_mark_node;
if (pedantic && !flag_isoc99)
{
if (constp > 1)
- pedwarn (loc, OPT_pedantic, "duplicate %<const%>");
+ pedwarn (loc, OPT_Wpedantic, "duplicate %<const%>");
if (restrictp > 1)
- pedwarn (loc, OPT_pedantic, "duplicate %<restrict%>");
+ pedwarn (loc, OPT_Wpedantic, "duplicate %<restrict%>");
if (volatilep > 1)
- pedwarn (loc, OPT_pedantic, "duplicate %<volatile%>");
+ pedwarn (loc, OPT_Wpedantic, "duplicate %<volatile%>");
}
if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2)
{
if (storage_class == csc_auto)
pedwarn (loc,
- (current_scope == file_scope) ? 0 : OPT_pedantic,
+ (current_scope == file_scope) ? 0 : OPT_Wpedantic,
"function definition declared %<auto%>");
if (storage_class == csc_register)
error_at (loc, "function definition declared %<register%>");
error_at (loc, "file-scope declaration of %qE specifies %<auto%>",
name);
if (pedantic && storage_class == csc_register)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (input_location, OPT_Wpedantic,
"file-scope declaration of %qE specifies %<register%>", name);
}
else
}
if (pedantic && !in_system_header && flexible_array_type_p (type))
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"invalid use of structure with flexible array member");
if (size == error_mark_node)
if (pedantic && size_maybe_const && integer_zerop (size))
{
if (name)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C forbids zero-size array %qE", name);
else
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C forbids zero-size array");
}
}
if (flexible_array_member
&& pedantic && !flag_isoc99 && !in_system_header)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C90 does not support flexible array members");
/* ISO C99 Flexible array members are effectively
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
TYPE_NAME (type) = decl;
}
- type = build_pointer_type (type);
+ type = c_build_pointer_type (type);
/* Process type qualifiers (such as const or volatile)
that were given inside the `*'. */
if (bitfield)
check_bitfield_type_and_width (&type, width, name);
- /* Did array size calculations overflow? */
+ /* Reject invalid uses of _Alignas. */
+ if (declspecs->alignas_p)
+ {
+ if (storage_class == csc_typedef)
+ error_at (loc, "alignment specified for typedef %qE", name);
+ else if (storage_class == csc_register)
+ error_at (loc, "alignment specified for %<register%> object %qE",
+ name);
+ else if (decl_context == PARM)
+ {
+ if (name)
+ error_at (loc, "alignment specified for parameter %qE", name);
+ else
+ error_at (loc, "alignment specified for unnamed parameter");
+ }
+ else if (bitfield)
+ {
+ if (name)
+ error_at (loc, "alignment specified for bit-field %qE", name);
+ else
+ error_at (loc, "alignment specified for unnamed bit-field");
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE)
+ error_at (loc, "alignment specified for function %qE", name);
+ else if (declspecs->align_log != -1)
+ {
+ alignas_align = 1U << declspecs->align_log;
+ if (alignas_align < TYPE_ALIGN_UNIT (type))
+ {
+ if (name)
+ error_at (loc, "%<_Alignas%> specifiers cannot reduce "
+ "alignment of %qE", name);
+ else
+ error_at (loc, "%<_Alignas%> specifiers cannot reduce "
+ "alignment of unnamed field");
+ alignas_align = 0;
+ }
+ }
+ }
+ /* Did array size calculations overflow or does the array cover more
+ than half of the address-space? */
if (TREE_CODE (type) == ARRAY_TYPE
&& COMPLETE_TYPE_P (type)
&& TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
- && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
+ && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
{
if (name)
error_at (loc, "size of array %qE is too large", name);
tree decl;
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
if (declspecs->inline_p)
pedwarn (loc, 0,"typedef %q+D declared %<inline%>", decl);
+ if (declspecs->noreturn_p)
+ pedwarn (loc, 0,"typedef %q+D declared %<_Noreturn%>", decl);
if (warn_cxx_compat && declarator->u.id != NULL_TREE)
{
/* Note that the grammar rejects storage classes in typenames
and fields. */
gcc_assert (storage_class == csc_none && !threadp
- && !declspecs->inline_p);
+ && !declspecs->inline_p && !declspecs->noreturn_p);
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C forbids const or volatile function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
&& variably_modified_type_p (type, NULL_TREE))
{
/* C99 6.7.2.1p8 */
- pedwarn (loc, OPT_pedantic, "a member of a structure or union cannot "
+ pedwarn (loc, OPT_Wpedantic, "a member of a structure or union cannot "
"have a variably modified type");
}
type = TREE_TYPE (type);
if (type_quals)
type = c_build_qualified_type (type, type_quals);
- type = build_pointer_type (type);
+ type = c_build_pointer_type (type);
type_quals = array_ptr_quals;
if (type_quals)
type = c_build_qualified_type (type, type_quals);
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
if (type_quals)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
- type = build_pointer_type (type);
+ type = c_build_pointer_type (type);
type_quals = TYPE_UNQUALIFIED;
}
else if (type_quals)
DECL_ARG_TYPE (decl) = promoted_type;
if (declspecs->inline_p)
pedwarn (loc, 0, "parameter %q+D declared %<inline%>", decl);
+ if (declspecs->noreturn_p)
+ pedwarn (loc, 0, "parameter %q+D declared %<_Noreturn%>", decl);
}
else if (decl_context == FIELD)
{
/* Note that the grammar rejects storage classes in typenames
and fields. */
gcc_assert (storage_class == csc_none && !threadp
- && !declspecs->inline_p);
+ && !declspecs->inline_p && !declspecs->noreturn_p);
/* Structure field. It may not be a function. */
GCC allows 'auto', perhaps with 'inline', to support
nested functions. */
if (storage_class == csc_auto)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"invalid storage class for function %qE", name);
else if (storage_class == csc_static)
{
decl = build_decl_attribute_variant (decl, decl_attr);
if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C forbids qualified function types");
/* Every function declaration is an external reference
if (declspecs->default_int_p)
C_FUNCTION_IMPLICIT_INT (decl) = 1;
- /* Record presence of `inline', if it is reasonable. */
+ /* Record presence of `inline' and `_Noreturn', if it is
+ reasonable. */
if (flag_hosted && MAIN_NAME_P (declarator->u.id))
{
if (declspecs->inline_p)
pedwarn (loc, 0, "cannot inline function %<main%>");
+ if (declspecs->noreturn_p)
+ pedwarn (loc, 0, "%<main%> declared %<_Noreturn%>");
+ }
+ else
+ {
+ if (declspecs->inline_p)
+ /* Record that the function is declared `inline'. */
+ DECL_DECLARED_INLINE_P (decl) = 1;
+ if (declspecs->noreturn_p)
+ {
+ if (!flag_isoc11)
+ {
+ if (flag_isoc99)
+ pedwarn (loc, OPT_Wpedantic,
+ "ISO C99 does not support %<_Noreturn%>");
+ else
+ pedwarn (loc, OPT_Wpedantic,
+ "ISO C90 does not support %<_Noreturn%>");
+ }
+ TREE_THIS_VOLATILE (decl) = 1;
+ }
}
- else if (declspecs->inline_p)
- /* Record that the function is declared `inline'. */
- DECL_DECLARED_INLINE_P (decl) = 1;
}
else
{
if (declspecs->inline_p)
pedwarn (loc, 0, "variable %q+D declared %<inline%>", decl);
+ if (declspecs->noreturn_p)
+ pedwarn (loc, 0, "variable %q+D declared %<_Noreturn%>", decl);
/* At file scope, an initialized extern declaration may follow
a static declaration. In that case, DECL_EXTERNAL will be
/* Record constancy and volatility. */
c_apply_type_quals_to_decl (type_quals, decl);
+ /* Apply _Alignas specifiers. */
+ if (alignas_align)
+ {
+ DECL_ALIGN (decl) = alignas_align * BITS_PER_UNIT;
+ DECL_USER_ALIGN (decl) = 1;
+ }
+
/* If a type has volatile components, it should be stored in memory.
Otherwise, the fact that those components are volatile
will be ignored, and would even crash the compiler.
If this is something of the form "foo;" and foo is a TYPE_DECL, then
If foo names a structure or union without a tag, then this
- is an anonymous struct (this is permitted by C1X).
+ is an anonymous struct (this is permitted by C11).
If MS or Plan 9 extensions are enabled and foo names a
structure, then again this is an anonymous struct.
Otherwise this is an error.
pedwarn (loc, 0, "declaration does not declare anything");
return NULL_TREE;
}
- if (!flag_isoc1x)
+ if (!flag_isoc11)
{
if (flag_isoc99)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C99 doesn%'t support unnamed structs/unions");
else
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C90 doesn%'t support unnamed structs/unions");
}
}
{
if (DECL_NAME (x) != 0)
break;
- if (flag_isoc1x
+ if (flag_isoc11
&& (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
|| TREE_CODE (TREE_TYPE (x)) == UNION_TYPE))
break;
if (TREE_CODE (t) == UNION_TYPE)
{
if (fieldlist)
- pedwarn (loc, OPT_pedantic, "union has no named members");
+ pedwarn (loc, OPT_Wpedantic, "union has no named members");
else
- pedwarn (loc, OPT_pedantic, "union has no members");
+ pedwarn (loc, OPT_Wpedantic, "union has no members");
}
else
{
if (fieldlist)
- pedwarn (loc, OPT_pedantic, "struct has no named members");
+ pedwarn (loc, OPT_Wpedantic, "struct has no named members");
else
- pedwarn (loc, OPT_pedantic, "struct has no members");
+ pedwarn (loc, OPT_Wpedantic, "struct has no members");
}
}
}
if (pedantic && TREE_CODE (t) == RECORD_TYPE
&& flexible_array_type_p (TREE_TYPE (x)))
- pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic,
+ pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
"invalid use of structure with flexible array member");
if (DECL_NAME (x)
if (c_dialect_objc ())
objc_check_decl (decl);
rest_of_decl_compilation (decl, toplevel, 0);
- if (!toplevel)
- expand_decl (decl);
}
}
C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0;
{
value = c_fully_fold (value, false, NULL);
if (TREE_CODE (value) == INTEGER_CST)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"enumerator value for %qE is not an integer "
"constant expression", name);
}
(6.4.4.3/2 in the C99 Standard). GCC allows any integer type as
an extension. */
else if (!int_fits_type_p (value, integer_type_node))
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C restricts enumerator values to range of %<int%>");
/* The ISO C Standard mandates enumerators to have type int, even
/* If the declarator is not suitable for a function definition,
cause a syntax error. */
- if (decl1 == 0)
+ if (decl1 == 0
+ || TREE_CODE (decl1) != FUNCTION_DECL)
return 0;
loc = DECL_SOURCE_LOCATION (decl1);
old-style definition and discarded? */
if (current_function_prototype_built_in)
warning_at (DECL_SOURCE_LOCATION (parm),
- OPT_pedantic, "promoted argument %qD "
+ OPT_Wpedantic, "promoted argument %qD "
"doesn%'t match built-in prototype", parm);
else
{
pedwarn (DECL_SOURCE_LOCATION (parm),
- OPT_pedantic, "promoted argument %qD "
+ OPT_Wpedantic, "promoted argument %qD "
"doesn%'t match prototype", parm);
- pedwarn (current_function_prototype_locus, OPT_pedantic,
+ pedwarn (current_function_prototype_locus, OPT_Wpedantic,
"prototype declaration");
}
}
/* Initialize the RTL code for the function. */
allocate_struct_function (fndecl, false);
+ if (warn_unused_local_typedefs)
+ cfun->language = ggc_alloc_cleared_language_function ();
+
/* Begin the statement tree for this function. */
DECL_SAVED_TREE (fndecl) = push_stmt_list ();
"parameter %qD set but not used", decl);
}
+ /* Complain about locally defined typedefs that are not used in this
+ function. */
+ maybe_warn_unused_local_typedefs ();
+
/* Store the end of the function, so that we get good line number
info for the epilogue. */
cfun->function_end_locus = input_location;
if (!decl_function_context (fndecl))
undef_nested_function = false;
+ if (cfun->language != NULL)
+ {
+ ggc_free (cfun->language);
+ cfun->language = NULL;
+ }
+
/* We're leaving the context of this function, so zap cfun.
It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
tree_rest_of_compilation. */
build_null_declspecs (void)
{
struct c_declspecs *ret = XOBNEW (&parser_obstack, struct c_declspecs);
+ memset (&ret->locations, 0, cdw_number_of_elements);
ret->type = 0;
ret->expr = 0;
ret->decl_attr = 0;
ret->attrs = 0;
+ ret->align_log = -1;
ret->typespec_word = cts_none;
ret->storage_class = csc_none;
ret->expr_const_operands = true;
ret->unsigned_p = false;
ret->complex_p = false;
ret->inline_p = false;
+ ret->noreturn_p = false;
ret->thread_p = false;
ret->const_p = false;
ret->volatile_p = false;
ret->restrict_p = false;
ret->saturating_p = false;
+ ret->alignas_p = false;
ret->address_space = ADDR_SPACE_GENERIC;
return ret;
}
SPECS, returning SPECS. */
struct c_declspecs *
-declspecs_add_addrspace (struct c_declspecs *specs, addr_space_t as)
+declspecs_add_addrspace (source_location location,
+ struct c_declspecs *specs, addr_space_t as)
{
specs->non_sc_seen_p = true;
specs->declspecs_seen_p = true;
c_addr_space_name (as),
c_addr_space_name (specs->address_space));
else
- specs->address_space = as;
+ {
+ specs->address_space = as;
+ specs->locations[cdw_address_space] = location;
+ }
return specs;
}
returning SPECS. */
struct c_declspecs *
-declspecs_add_qual (struct c_declspecs *specs, tree qual)
+declspecs_add_qual (source_location loc,
+ struct c_declspecs *specs, tree qual)
{
enum rid i;
bool dupe = false;
case RID_CONST:
dupe = specs->const_p;
specs->const_p = true;
+ specs->locations[cdw_const] = loc;
break;
case RID_VOLATILE:
dupe = specs->volatile_p;
specs->volatile_p = true;
+ specs->locations[cdw_volatile] = loc;
break;
case RID_RESTRICT:
dupe = specs->restrict_p;
specs->restrict_p = true;
+ specs->locations[cdw_restrict] = loc;
break;
default:
gcc_unreachable ();
}
if (dupe && !flag_isoc99)
- pedwarn (input_location, OPT_pedantic, "duplicate %qE", qual);
+ pedwarn (loc, OPT_Wpedantic, "duplicate %qE", qual);
return specs;
}
pedwarn_c90 (loc, OPT_Wlong_long,
"ISO C90 does not support %<long long%>");
specs->long_long_p = 1;
+ specs->locations[cdw_long_long] = loc;
break;
}
if (specs->short_p)
("both %<long%> and %<_Decimal128%> in "
"declaration specifiers"));
else
- specs->long_p = true;
+ {
+ specs->long_p = true;
+ specs->locations[cdw_long] = loc;
+ }
break;
case RID_SHORT:
dupe = specs->short_p;
("both %<short%> and %<_Decimal128%> in "
"declaration specifiers"));
else
- specs->short_p = true;
+ {
+ specs->short_p = true;
+ specs->locations[cdw_short] = loc;
+ }
break;
case RID_SIGNED:
dupe = specs->signed_p;
("both %<signed%> and %<_Decimal128%> in "
"declaration specifiers"));
else
- specs->signed_p = true;
+ {
+ specs->signed_p = true;
+ specs->locations[cdw_signed] = loc;
+ }
break;
case RID_UNSIGNED:
dupe = specs->unsigned_p;
("both %<unsigned%> and %<_Decimal128%> in "
"declaration specifiers"));
else
- specs->unsigned_p = true;
+ {
+ specs->unsigned_p = true;
+ specs->locations[cdw_unsigned] = loc;
+ }
break;
case RID_COMPLEX:
dupe = specs->complex_p;
- if (!flag_isoc99 && !in_system_header)
- pedwarn (loc, OPT_pedantic,
+ if (!flag_isoc99 && !in_system_header_at (loc))
+ pedwarn (loc, OPT_Wpedantic,
"ISO C90 does not support complex types");
if (specs->typespec_word == cts_void)
error_at (loc,
("both %<complex%> and %<_Sat%> in "
"declaration specifiers"));
else
- specs->complex_p = true;
+ {
+ specs->complex_p = true;
+ specs->locations[cdw_complex] = loc;
+ }
break;
case RID_SAT:
dupe = specs->saturating_p;
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C does not support saturating types");
if (specs->typespec_word == cts_int128)
{
("both %<_Sat%> and %<complex%> in "
"declaration specifiers"));
else
- specs->saturating_p = true;
+ {
+ specs->saturating_p = true;
+ specs->locations[cdw_saturating] = loc;
+ }
break;
default:
gcc_unreachable ();
return specs;
}
if (!in_system_header)
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C does not support %<__int128%> type");
if (specs->long_p)
("both %<__int128%> and %<short%> in "
"declaration specifiers"));
else
- specs->typespec_word = cts_int128;
+ {
+ specs->typespec_word = cts_int128;
+ specs->locations[cdw_typespec] = loc;
+ }
return specs;
case RID_VOID:
if (specs->long_p)
("both %<_Sat%> and %<void%> in "
"declaration specifiers"));
else
- specs->typespec_word = cts_void;
+ {
+ specs->typespec_word = cts_void;
+ specs->locations[cdw_typespec] = loc;
+ }
return specs;
case RID_BOOL:
if (specs->long_p)
("both %<_Sat%> and %<_Bool%> in "
"declaration specifiers"));
else
- specs->typespec_word = cts_bool;
+ {
+ specs->typespec_word = cts_bool;
+ specs->locations[cdw_typespec] = loc;
+ }
return specs;
case RID_CHAR:
if (specs->long_p)
("both %<_Sat%> and %<char%> in "
"declaration specifiers"));
else
- specs->typespec_word = cts_char;
+ {
+ specs->typespec_word = cts_char;
+ specs->locations[cdw_typespec] = loc;
+ }
return specs;
case RID_INT:
if (specs->saturating_p)
("both %<_Sat%> and %<int%> in "
"declaration specifiers"));
else
- specs->typespec_word = cts_int;
+ {
+ specs->typespec_word = cts_int;
+ specs->locations[cdw_typespec] = loc;
+ }
return specs;
case RID_FLOAT:
if (specs->long_p)
("both %<_Sat%> and %<float%> in "
"declaration specifiers"));
else
- specs->typespec_word = cts_float;
+ {
+ specs->typespec_word = cts_float;
+ specs->locations[cdw_typespec] = loc;
+ }
return specs;
case RID_DOUBLE:
if (specs->long_long_p)
("both %<_Sat%> and %<double%> in "
"declaration specifiers"));
else
- specs->typespec_word = cts_double;
+ {
+ specs->typespec_word = cts_double;
+ specs->locations[cdw_typespec] = loc;
+ }
return specs;
case RID_DFLOAT32:
case RID_DFLOAT64:
specs->typespec_word = cts_dfloat64;
else
specs->typespec_word = cts_dfloat128;
+ specs->locations[cdw_typespec] = loc;
}
if (!targetm.decimal_float_supported_p ())
error_at (loc,
("decimal floating point not supported "
"for this target"));
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C does not support decimal floating point");
return specs;
case RID_FRACT:
specs->typespec_word = cts_fract;
else
specs->typespec_word = cts_accum;
+ specs->locations[cdw_typespec] = loc;
}
if (!targetm.fixed_point_supported_p ())
error_at (loc,
"fixed-point types not supported for this target");
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C does not support fixed-point types");
return specs;
default:
specs->decl_attr = DECL_ATTRIBUTES (type);
specs->typedef_p = true;
specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
+ specs->locations[cdw_typedef] = loc;
/* If this typedef name is defined in a struct, then a C++
lookup would return a different value. */
else if (TREE_TYPE (t) == error_mark_node)
;
else
- specs->type = TREE_TYPE (t);
+ {
+ specs->type = TREE_TYPE (t);
+ specs->locations[cdw_typespec] = loc;
+ }
}
else
{
if (TREE_CODE (type) != ERROR_MARK && spec.kind == ctsk_typeof)
{
specs->typedef_p = true;
+ specs->locations[cdw_typedef] = loc;
if (spec.expr)
{
if (specs->expr)
declaration specifiers SPECS, returning SPECS. */
struct c_declspecs *
-declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
+declspecs_add_scspec (source_location loc,
+ struct c_declspecs *specs,
+ tree scspec)
{
enum rid i;
enum c_storage_class n = csc_none;
difference between gnu89 and C99 inline. */
dupe = false;
specs->inline_p = true;
+ specs->locations[cdw_inline] = loc;
+ break;
+ case RID_NORETURN:
+ /* Duplicate _Noreturn is permitted. */
+ dupe = false;
+ specs->noreturn_p = true;
+ specs->locations[cdw_noreturn] = loc;
break;
case RID_THREAD:
dupe = specs->thread_p;
else if (specs->storage_class == csc_typedef)
error ("%<__thread%> used with %<typedef%>");
else
- specs->thread_p = true;
+ {
+ specs->thread_p = true;
+ specs->locations[cdw_thread] = loc;
+ }
break;
case RID_AUTO:
n = csc_auto;
else
{
specs->storage_class = n;
+ specs->locations[cdw_storage_class] = loc;
if (n != csc_extern && n != csc_static && specs->thread_p)
{
error ("%<__thread%> used with %qE", scspec);
returning SPECS. */
struct c_declspecs *
-declspecs_add_attrs (struct c_declspecs *specs, tree attrs)
+declspecs_add_attrs (source_location loc, struct c_declspecs *specs, tree attrs)
{
specs->attrs = chainon (attrs, specs->attrs);
+ specs->locations[cdw_attributes] = loc;
specs->declspecs_seen_p = true;
return specs;
}
+/* Add an _Alignas specifier (expression ALIGN, or type whose
+ alignment is ALIGN) to the declaration specifiers SPECS, returning
+ SPECS. */
+struct c_declspecs *
+declspecs_add_alignas (source_location loc,
+ struct c_declspecs *specs, tree align)
+{
+ int align_log;
+ specs->alignas_p = true;
+ specs->locations[cdw_alignas] = loc;
+ if (align == error_mark_node)
+ return specs;
+ align_log = check_user_alignment (align, true);
+ if (align_log > specs->align_log)
+ specs->align_log = align_log;
+ return specs;
+}
+
/* Combine "long", "short", "signed", "unsigned" and "_Complex" type
specifiers with any other type specifier to determine the resulting
type. This is where ISO C checks on complex types are made, since
{
if (specs->saturating_p)
{
- error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
+ error_at (specs->locations[cdw_saturating],
+ "%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
if (!targetm.fixed_point_supported_p ())
- error ("fixed-point types not supported for this target");
+ error_at (specs->locations[cdw_saturating],
+ "fixed-point types not supported for this target");
specs->typespec_word = cts_fract;
}
else if (specs->long_p || specs->short_p
else if (specs->complex_p)
{
specs->typespec_word = cts_double;
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
"ISO C does not support plain %<complex%> meaning "
"%<double complex%>");
}
specs->type = char_type_node;
if (specs->complex_p)
{
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
"ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
: int128_integer_type_node);
if (specs->complex_p)
{
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
"ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
: integer_type_node);
if (specs->complex_p)
{
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
"ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
collect_source_ref (LOCATION_FILE (decl_sloc (decl, false)));
}
+/* Preserve the external declarations scope across a garbage collect. */
+static GTY(()) tree ext_block;
+
/* Collect all references relevant to SOURCE_FILE. */
static void
FOR_EACH_VEC_ELT (tree, all_translation_units, i, t)
collect_ada_nodes (BLOCK_VARS (DECL_INITIAL (t)), source_file);
+
+ collect_ada_nodes (BLOCK_VARS (ext_block), source_file);
}
/* Iterate over all global declarations and call CALLBACK. */
for (decl = BLOCK_VARS (decls); decl; decl = TREE_CHAIN (decl))
callback (decl);
}
-}
-/* Preserve the external declarations scope across a garbage collect. */
-static GTY(()) tree ext_block;
+ for (decl = BLOCK_VARS (ext_block); decl; decl = TREE_CHAIN (decl))
+ callback (decl);
+}
void
c_write_global_declarations (void)
/* We're done parsing; proceed to optimize and emit assembly.
FIXME: shouldn't be the front end's responsibility to call this. */
- cgraph_finalize_compilation_unit ();
+ finalize_compilation_unit ();
timevar_stop (TV_PHASE_CGRAPH);
timevar_start (TV_PHASE_DBGINFO);