summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/c-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/c-decl.c')
-rw-r--r--contrib/gcc/c-decl.c351
1 files changed, 196 insertions, 155 deletions
diff --git a/contrib/gcc/c-decl.c b/contrib/gcc/c-decl.c
index 4153f50..2628257 100644
--- a/contrib/gcc/c-decl.c
+++ b/contrib/gcc/c-decl.c
@@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "debug.h"
#include "timevar.h"
#include "c-common.h"
+#include "c-pragma.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
@@ -53,6 +54,7 @@ enum decl_context
FUNCDEF, /* Function definition */
PARM, /* Declaration of parm before function body */
FIELD, /* Declaration inside struct or union */
+ BITFIELD, /* Likewise but with specified width */
TYPENAME}; /* Typename (inside cast or sizeof) */
@@ -133,6 +135,11 @@ int current_function_returns_value;
int current_function_returns_null;
+/* Set to 0 at beginning of a function definition, set to 1 if
+ a call to a noreturn function is seen. */
+
+int current_function_returns_abnormally;
+
/* Set to nonzero by `grokdeclarator' for a function
whose return type is defaulted, if warnings for this are desired. */
@@ -275,13 +282,12 @@ static tree lookup_tag PARAMS ((enum tree_code, tree,
struct binding_level *, int));
static tree lookup_tag_reverse PARAMS ((tree));
static tree grokdeclarator PARAMS ((tree, tree, enum decl_context,
- int, tree));
+ int));
static tree grokparms PARAMS ((tree, int));
static void layout_array_type PARAMS ((tree));
static tree c_make_fname_decl PARAMS ((tree, int));
static void c_expand_body PARAMS ((tree, int, int));
static void warn_if_shadowing PARAMS ((tree, tree));
-static tree build_bitfield_integer_type PARAMS ((tree, tree, const char *));
/* C-specific option variables. */
@@ -319,7 +325,7 @@ int flag_noniso_default_format_attributes = 1;
being traditional. */
int flag_allow_single_precision = 0;
-/* Nonzero means to treat bit-fields as signed unless they say `unsigned'. */
+/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */
int flag_signed_bitfields = 1;
int explicit_flag_signed_bitfields = 0;
@@ -1543,6 +1549,22 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
if (! different_binding_level)
TREE_TYPE (olddecl) = oldtype;
}
+ else if (TYPE_ARG_TYPES (oldtype) == NULL
+ && TYPE_ARG_TYPES (newtype) != NULL)
+ {
+ /* For bcmp, bzero, fputs the builtin type has arguments not
+ specified. Use the ones from the prototype so that type checking
+ is done for them. */
+ tree trytype
+ = build_function_type (TREE_TYPE (oldtype),
+ TYPE_ARG_TYPES (newtype));
+ trytype = build_type_attribute_variant (trytype,
+ TYPE_ATTRIBUTES (oldtype));
+
+ oldtype = trytype;
+ if (! different_binding_level)
+ TREE_TYPE (olddecl) = oldtype;
+ }
if (!types_match)
{
/* If types don't match for a built-in, throw away the built-in. */
@@ -1669,6 +1691,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
&& current_binding_level == global_binding_level)
? "`%s' previously defined here"
: "`%s' previously declared here"));
+ return 0;
}
else if (TREE_CODE (newdecl) == TYPE_DECL
&& (DECL_IN_SYSTEM_HEADER (olddecl)
@@ -1932,7 +1955,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
}
/* Merge the storage class information. */
- DECL_WEAK (newdecl) |= DECL_WEAK (olddecl);
+ merge_weak (newdecl, olddecl);
+
/* For functions, static overrides non-static. */
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
@@ -2177,11 +2201,13 @@ pushdecl (x)
not errors. X11 for instance depends on this. */
if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional)
{
- t = lookup_name (name);
+ t = IDENTIFIER_GLOBAL_VALUE (name);
/* Type decls at global scope don't conflict with externs declared
inside lexical blocks. */
- if (t && TREE_CODE (t) == TYPE_DECL)
- t = 0;
+ if (! t || TREE_CODE (t) == TYPE_DECL)
+ /* If there's no visible global declaration, try for an
+ invisible one. */
+ t = IDENTIFIER_LIMBO_VALUE (name);
different_binding_level = 1;
}
if (t != 0 && t == error_mark_node)
@@ -3053,8 +3079,7 @@ c_init_decl_processing ()
boolean_true_node = integer_one_node;
boolean_false_node = integer_zero_node;
- /* With GCC, C99's _Bool is always of size 1. */
- c_bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+ c_bool_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
@@ -3214,6 +3239,10 @@ builtin_function (name, type, function_code, class, library_name)
DECL_BUILT_IN_CLASS (decl) = class;
DECL_FUNCTION_CODE (decl) = function_code;
+ /* The return builtins leave the current function. */
+ if (function_code == BUILT_IN_RETURN || function_code == BUILT_IN_EH_RETURN)
+ TREE_THIS_VOLATILE (decl) = 1;
+
/* Warn if a function in the namespace for users
is used without an occasion to consider it declared. */
if (name[0] != '_' || name[1] != '_')
@@ -3390,8 +3419,7 @@ groktypename (typename)
split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
- typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0,
- NULL_TREE);
+ typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0);
/* Apply attributes. */
decl_attributes (&typename, attrs, 0);
@@ -3409,7 +3437,7 @@ groktypename_in_parm_context (typename)
return typename;
return grokdeclarator (TREE_VALUE (typename),
TREE_PURPOSE (typename),
- PARM, 0, NULL_TREE);
+ PARM, 0);
}
/* Decode a declarator in an ordinary declaration or data definition.
@@ -3442,7 +3470,7 @@ start_decl (declarator, declspecs, initialized, attributes)
deprecated_state = DEPRECATED_SUPPRESS;
decl = grokdeclarator (declarator, declspecs,
- NORMAL, initialized, NULL_TREE);
+ NORMAL, initialized);
deprecated_state = DEPRECATED_NORMAL;
@@ -3551,6 +3579,10 @@ start_decl (declarator, declspecs, initialized, attributes)
/* Set attributes here so if duplicate decl, will have proper attributes. */
decl_attributes (&decl, attributes, 0);
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_binding_level == global_binding_level)
+ maybe_apply_pragma_weak (decl);
+
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
@@ -3596,6 +3628,8 @@ finish_decl (decl, init, asmspec_tree)
const char *asmspec = 0;
/* If a name was specified, get the string. */
+ if (current_binding_level == global_binding_level)
+ asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
@@ -3820,8 +3854,7 @@ push_parm_decl (parm)
immediate_size_expand = 0;
decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
- TREE_PURPOSE (TREE_PURPOSE (parm)),
- PARM, 0, NULL_TREE);
+ TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
decl_attributes (&decl, TREE_VALUE (parm), 0);
#if 0
@@ -3981,92 +4014,6 @@ complete_array_type (type, initial_value, do_default)
return value;
}
-/* A bit-field NAME should have an integer type whose precision
- accurately reflects its WIDTH. If TYPE is good for that, return
- it, otherwise create and return the appropriate type.
-
- This routine also performs sanity checks on the bit-field's type
- and width, and uses appropriate values if they are invalid. */
-static tree
-build_bitfield_integer_type (type, width, orig_name)
- tree type, width;
- const char *orig_name;
-{
- tree type_mv;
- unsigned int max_width;
- unsigned HOST_WIDE_INT w;
- const char *name = orig_name ? orig_name: _("<anonymous>");
-
- /* Necessary? */
- STRIP_NOPS (width);
-
- /* Detect and ignore out of range field width and process valid
- field widths. */
- if (TREE_CODE (width) != INTEGER_CST)
- {
- error ("bit-field `%s' width not an integer constant", name);
- width = integer_one_node;
- }
- else
- {
- constant_expression_warning (width);
- if (tree_int_cst_sgn (width) < 0)
- {
- error ("negative width in bit-field `%s'", name);
- width = integer_one_node;
- }
- else if (integer_zerop (width) && orig_name)
- {
- error ("zero width for bit-field `%s'", name);
- width = integer_one_node;
- }
- }
-
- /* Detect invalid bit-field type. */
- if (TREE_CODE (type) != INTEGER_TYPE
- && TREE_CODE (type) != BOOLEAN_TYPE
- && TREE_CODE (type) != ENUMERAL_TYPE)
- {
- error ("bit-field `%s' has invalid type", name);
- type = unsigned_type_node;
- }
-
- type_mv = TYPE_MAIN_VARIANT (type);
- if (pedantic
- && type_mv != integer_type_node
- && type_mv != unsigned_type_node
- && type_mv != c_bool_type_node
- /* Accept an enum that's equivalent to int or unsigned int. */
- && (TREE_CODE (type) != ENUMERAL_TYPE
- || TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)))
- pedwarn ("type of bit-field `%s' is a GCC extension", name);
-
- if (type_mv == c_bool_type_node)
- max_width = CHAR_TYPE_SIZE;
- else
- max_width = TYPE_PRECISION (type);
-
- if (0 < compare_tree_int (width, max_width))
- {
- error ("width of `%s' exceeds its type", name);
- w = max_width;
- }
- else
- w = tree_low_cst (width, 1);
-
- if (TREE_CODE (type) == ENUMERAL_TYPE
- && (w < min_precision (TYPE_MIN_VALUE (type), TREE_UNSIGNED (type))
- || w < min_precision (TYPE_MAX_VALUE (type), TREE_UNSIGNED (type))))
- warning ("`%s' is narrower than values of its type", name);
-
- /* The type of a bit-field should have precision the same as the
- bit-field's width. */
- if (w != TYPE_PRECISION (type))
- type = build_nonstandard_integer_type (w, TREE_UNSIGNED (type));
-
- return type;
-}
-
/* Given declspecs and a declarator,
determine the name and type of the object declared
and construct a ..._DECL node for it.
@@ -4086,9 +4033,8 @@ build_bitfield_integer_type (type, width, orig_name)
TYPENAME if for a typename (in a cast or sizeof).
Don't make a DECL node; just return the ..._TYPE node.
FIELD for a struct or union field; make a FIELD_DECL.
+ BITFIELD for a field with specified width.
INITIALIZED is 1 if the decl has an initializer.
- WIDTH is non-NULL for bit-fields, and is an INTEGER_CST node representing
- the width of the bit-field.
In the TYPENAME case, DECLARATOR is really an absolute declarator.
It may also be so in the PARM case, for a prototype where the
@@ -4098,12 +4044,11 @@ build_bitfield_integer_type (type, width, orig_name)
and `extern' are interpreted. */
static tree
-grokdeclarator (declarator, declspecs, decl_context, initialized, width)
+grokdeclarator (declarator, declspecs, decl_context, initialized)
tree declspecs;
tree declarator;
enum decl_context decl_context;
int initialized;
- tree width;
{
int specbits = 0;
tree spec;
@@ -4118,16 +4063,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
int explicit_char = 0;
int defaulted_int = 0;
tree typedef_decl = 0;
- const char *name, *orig_name;
+ const char *name;
tree typedef_type = 0;
int funcdef_flag = 0;
enum tree_code innermost_code = ERROR_MARK;
+ int bitfield = 0;
int size_varies = 0;
tree decl_attr = NULL_TREE;
tree array_ptr_quals = NULL_TREE;
int array_parm_static = 0;
tree returned_attrs = NULL_TREE;
- bool bitfield = width != NULL_TREE;
+
+ if (decl_context == BITFIELD)
+ bitfield = 1, decl_context = FIELD;
if (decl_context == FUNCDEF)
funcdef_flag = 1, decl_context = NORMAL;
@@ -4160,7 +4108,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
default:
abort ();
}
- orig_name = name;
if (name == 0)
name = "type name";
}
@@ -4377,9 +4324,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
}
/* Decide whether an integer type is signed or not.
- Optionally treat bit-fields as signed by default. */
+ Optionally treat bitfields as signed by default. */
if (specbits & 1 << (int) RID_UNSIGNED
- /* Traditionally, all bit-fields are unsigned. */
+ /* Traditionally, all bitfields are unsigned. */
|| (bitfield && flag_traditional
&& (! explicit_flag_signed_bitfields || !flag_signed_bitfields))
|| (bitfield && ! flag_signed_bitfields
@@ -4452,11 +4399,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
}
}
- /* A bit-field needs its type to have precision equal to its width,
- rather than the precision of the specified standard type. */
- if (bitfield)
- type = build_bitfield_integer_type (type, width, orig_name);
-
/* Figure out the type qualifiers for the declaration. There are
two ways a declaration can become qualified. One is something
like `const int i' where the `const' is explicit. Another is
@@ -4602,9 +4544,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
if (inner_decl == NULL_TREE
|| TREE_CODE (inner_decl) == IDENTIFIER_NODE)
attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
- if (TREE_CODE (inner_decl) == CALL_EXPR)
+ else if (TREE_CODE (inner_decl) == CALL_EXPR)
attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
- if (TREE_CODE (inner_decl) == ARRAY_REF)
+ else if (TREE_CODE (inner_decl) == ARRAY_REF)
attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
returned_attrs = decl_attributes (&type,
chainon (returned_attrs, attrs),
@@ -4723,10 +4665,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
}
else if (decl_context == FIELD)
{
- /* ??? Need to check somewhere that this is a structure
- and not a union, that this field is last, and that
- this structure has at least one other named member. */
-
if (pedantic && !flag_isoc99 && !in_system_header)
pedwarn ("ISO C89 does not support flexible array members");
@@ -5106,6 +5044,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
else if (decl_context == FIELD)
{
/* Structure field. It may not be a function. */
+
if (TREE_CODE (type) == FUNCTION_TYPE)
{
error ("field `%s' declared as a function", name);
@@ -5129,29 +5068,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
#endif
}
decl = build_decl (FIELD_DECL, declarator, type);
- if (bitfield)
- {
- DECL_SIZE (decl) = bitsize_int (TYPE_PRECISION (type));
- DECL_BIT_FIELD (decl) = 1;
- SET_DECL_C_BIT_FIELD (decl);
-
- /* Bit-field width 0 => force desired amount of alignment. */
- if (TYPE_PRECISION (type) == 0)
- {
-#ifdef EMPTY_FIELD_BOUNDARY
- DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
- EMPTY_FIELD_BOUNDARY);
-#endif
-#ifdef PCC_BITFIELD_TYPE_MATTERS
- if (PCC_BITFIELD_TYPE_MATTERS)
- {
- DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
- TYPE_ALIGN (type));
- DECL_USER_ALIGN (decl) |= TYPE_USER_ALIGN (type);
- }
-#endif
- }
- }
DECL_NONADDRESSABLE_P (decl) = bitfield;
if (size_varies)
@@ -5201,6 +5117,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
TREE_PUBLIC (decl)
= !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
+ if (defaulted_int)
+ C_FUNCTION_IMPLICIT_INT (decl) = 1;
+
/* Record presence of `inline', if it is reasonable. */
if (MAIN_NAME_P (declarator))
{
@@ -5654,7 +5573,7 @@ start_struct (code, name)
/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
of a structure component, returning a FIELD_DECL node.
- WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
+ WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.
This is done during the parsing of the struct declaration.
The FIELD_DECL nodes are chained together and the lot of them
@@ -5680,9 +5599,10 @@ grokfield (filename, line, declarator, declspecs, width)
}
}
- value = grokdeclarator (declarator, declspecs, FIELD, 0, width);
+ value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
finish_decl (value, NULL_TREE, NULL_TREE);
+ DECL_INITIAL (value) = width;
maybe_objc_check_decl (value);
return value;
@@ -5734,7 +5654,10 @@ finish_struct (t, fieldlist, attributes)
fieldlist ? _("named members") : _("members"));
}
- /* Install struct as DECL_CONTEXT of each field decl. */
+ /* Install struct as DECL_CONTEXT of each field decl.
+ Also process specified field sizes,m which is found in the DECL_INITIAL.
+ Store 0 there, except for ": 0" fields (so we can find them
+ and delete them, below). */
saw_named_field = 0;
for (x = fieldlist; x; x = TREE_CHAIN (x))
@@ -5770,7 +5693,94 @@ finish_struct (t, fieldlist, attributes)
error ("nested redefinition of `%s'",
IDENTIFIER_POINTER (TYPE_NAME (t)));
- if (TREE_TYPE (x) != error_mark_node && !DECL_BIT_FIELD (x))
+ /* Detect invalid bit-field size. */
+ if (DECL_INITIAL (x))
+ STRIP_NOPS (DECL_INITIAL (x));
+ if (DECL_INITIAL (x))
+ {
+ if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
+ constant_expression_warning (DECL_INITIAL (x));
+ else
+ {
+ error_with_decl (x,
+ "bit-field `%s' width not an integer constant");
+ DECL_INITIAL (x) = NULL;
+ }
+ }
+
+ /* Detect invalid bit-field type. */
+ if (DECL_INITIAL (x)
+ && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
+ && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
+ {
+ error_with_decl (x, "bit-field `%s' has invalid type");
+ DECL_INITIAL (x) = NULL;
+ }
+
+ if (DECL_INITIAL (x) && pedantic
+ && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
+ && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
+ && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
+ /* Accept an enum that's equivalent to int or unsigned int. */
+ && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
+ && (TYPE_PRECISION (TREE_TYPE (x))
+ == TYPE_PRECISION (integer_type_node))))
+ pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C");
+
+ /* Detect and ignore out of range field width and process valid
+ field widths. */
+ if (DECL_INITIAL (x))
+ {
+ int max_width
+ = (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node
+ ? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
+
+ if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
+ error_with_decl (x, "negative width in bit-field `%s'");
+ else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
+ pedwarn_with_decl (x, "width of `%s' exceeds its type");
+ else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
+ error_with_decl (x, "zero width for bit-field `%s'");
+ else
+ {
+ /* The test above has assured us that TREE_INT_CST_HIGH is 0. */
+ unsigned HOST_WIDE_INT width
+ = tree_low_cst (DECL_INITIAL (x), 1);
+
+ if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
+ && (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
+ TREE_UNSIGNED (TREE_TYPE (x)))
+ || (width
+ < min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
+ TREE_UNSIGNED (TREE_TYPE (x))))))
+ warning_with_decl (x,
+ "`%s' is narrower than values of its type");
+
+ DECL_SIZE (x) = bitsize_int (width);
+ DECL_BIT_FIELD (x) = 1;
+ SET_DECL_C_BIT_FIELD (x);
+
+ if (width == 0
+ && ! (* targetm.ms_bitfield_layout_p) (t))
+ {
+ /* field size 0 => force desired amount of alignment. */
+#ifdef EMPTY_FIELD_BOUNDARY
+ DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
+#endif
+#ifdef PCC_BITFIELD_TYPE_MATTERS
+ if (PCC_BITFIELD_TYPE_MATTERS)
+ {
+ DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
+ TYPE_ALIGN (TREE_TYPE (x)));
+ DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
+ }
+#endif
+ }
+ }
+ }
+
+ else if (TREE_TYPE (x) != error_mark_node)
{
unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
: TYPE_ALIGN (TREE_TYPE (x)));
@@ -5782,6 +5792,8 @@ finish_struct (t, fieldlist, attributes)
DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
}
+ DECL_INITIAL (x) = 0;
+
/* Detect flexible array member in an invalid context. */
if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
&& TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
@@ -6197,6 +6209,7 @@ start_function (declspecs, declarator, attributes)
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
+ current_function_returns_abnormally = 0;
warn_about_return_type = 0;
current_extern_inline = 0;
c_function_varargs = 0;
@@ -6206,7 +6219,7 @@ start_function (declspecs, declarator, attributes)
/* Don't expand any sizes in the return type of the function. */
immediate_size_expand = 0;
- decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE);
+ decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
/* If the declarator is not suitable for a function definition,
cause a syntax error. */
@@ -6218,6 +6231,10 @@ start_function (declspecs, declarator, attributes)
decl_attributes (&decl1, attributes, 0);
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_binding_level == global_binding_level)
+ maybe_apply_pragma_weak (decl1);
+
if (DECL_DECLARED_INLINE_P (decl1)
&& DECL_UNINLINABLE (decl1)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
@@ -6874,17 +6891,21 @@ store_parm_decls ()
This is called after parsing the body of the function definition.
- NESTED is nonzero if the function being finished is nested in another. */
+ NESTED is nonzero if the function being finished is nested in another.
+ CAN_DEFER_P is nonzero if the function may be deferred. */
void
-finish_function (nested)
+finish_function (nested, can_defer_p)
int nested;
+ int can_defer_p;
{
tree fndecl = current_function_decl;
-/* TREE_READONLY (fndecl) = 1;
- This caused &foo to be of type ptr-to-const-function
- which then got a warning when stored in a ptr-to-function variable. */
+#if 0
+ /* This caused &foo to be of type ptr-to-const-function which then
+ got a warning when stored in a ptr-to-function variable. */
+ TREE_READONLY (fndecl) = 1;
+#endif
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
@@ -6926,6 +6947,22 @@ finish_function (nested)
/* Tie off the statement tree for this function. */
finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
+
+ /* Complain if there's just no return statement. */
+ if (warn_return_type
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
+ && !current_function_returns_value && !current_function_returns_null
+ /* Don't complain if we abort. */
+ && !current_function_returns_abnormally
+ /* Don't warn for main(). */
+ && !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))
+ warning ("no return statement in function returning non-void");
+
/* Clear out memory we no longer need. */
free_after_parsing (cfun);
/* Since we never call rest_of_compilation, we never clear
@@ -6936,7 +6973,8 @@ finish_function (nested)
if (! nested)
{
/* Generate RTL for the body of this function. */
- c_expand_body (fndecl, nested, 1);
+ c_expand_body (fndecl, nested, can_defer_p);
+
/* Let the error reporting routines know that we're outside a
function. For a nested function, this value is used in
pop_c_function_context and then reset via pop_function_context. */
@@ -7215,6 +7253,7 @@ struct c_language_function
tree shadowed_labels;
int returns_value;
int returns_null;
+ int returns_abnormally;
int warn_about_return_type;
int extern_inline;
struct binding_level *binding_level;
@@ -7238,6 +7277,7 @@ push_c_function_context (f)
p->shadowed_labels = shadowed_labels;
p->returns_value = current_function_returns_value;
p->returns_null = current_function_returns_null;
+ p->returns_abnormally = current_function_returns_abnormally;
p->warn_about_return_type = warn_about_return_type;
p->extern_inline = current_extern_inline;
p->binding_level = current_binding_level;
@@ -7275,6 +7315,7 @@ pop_c_function_context (f)
shadowed_labels = p->shadowed_labels;
current_function_returns_value = p->returns_value;
current_function_returns_null = p->returns_null;
+ current_function_returns_abnormally = p->returns_abnormally;
warn_about_return_type = p->warn_about_return_type;
current_extern_inline = p->extern_inline;
current_binding_level = p->binding_level;
OpenPOWER on IntegriCloud