c-decl.c (finish_function): Only warn about missing return statement with -Wreturn-type.

* c-decl.c (finish_function): Only warn about missing return
        statement with -Wreturn-type.
        * cp/decl.c (finish_function): Only warn about missing return
        statement with -Wreturn-type.

From-SVN: r50134
This commit is contained in:
Jason Merrill 2002-02-28 08:57:39 -05:00 committed by Jason Merrill
parent beca58816c
commit 3b5f2209d2
5 changed files with 38 additions and 155 deletions

View File

@ -1,3 +1,8 @@
2002-02-28 Jason Merrill <jason@redhat.com>
* c-decl.c (finish_function): Only warn about missing return
statement with -Wreturn-type.
2002-02-27 Zack Weinberg <zack@codesourcery.com>
* mklibgcc.in: Don't use \n in a line subject to

View File

@ -299,10 +299,6 @@ int flag_cond_mismatch;
int flag_no_asm;
/* Nonzero means do some things the same way PCC does. */
int flag_traditional;
/* Nonzero means enable C89 Amendment 1 features. */
int flag_isoc94 = 0;
@ -320,10 +316,6 @@ int flag_hosted = 1;
int flag_noniso_default_format_attributes = 1;
/* Nonzero means to allow single precision math even if we're generally
being traditional. */
int flag_allow_single_precision = 0;
/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */
int flag_signed_bitfields = 1;
@ -470,15 +462,7 @@ c_decode_option (argc, argv)
strings_processed = cpp_handle_option (parse_in, argc, argv, 0);
if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
{
warning ("-traditional is deprecated and may be removed");
flag_traditional = 1;
flag_writable_strings = 1;
}
else if (!strcmp (p, "-fallow-single-precision"))
flag_allow_single_precision = 1;
else if (!strcmp (p, "-fhosted") || !strcmp (p, "-fno-freestanding"))
if (!strcmp (p, "-fhosted") || !strcmp (p, "-fno-freestanding"))
{
flag_hosted = 1;
flag_no_builtin = 0;
@ -491,11 +475,6 @@ c_decode_option (argc, argv)
if (warn_main == 2)
warn_main = 0;
}
else if (!strcmp (p, "-fnotraditional") || !strcmp (p, "-fno-traditional"))
{
flag_traditional = 0;
flag_writable_strings = 0;
}
else if (!strncmp (p, "-std=", 5))
{
/* Select the appropriate language standard. We currently
@ -516,7 +495,6 @@ c_decode_option (argc, argv)
iso_1990:
flag_isoc94 = 0;
iso_1994:
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 1;
flag_no_nonansi_builtin = 1;
@ -533,7 +511,6 @@ c_decode_option (argc, argv)
|| !strcmp (argstart, "c9x")
|| !strcmp (argstart, "c99"))
{
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 1;
flag_no_nonansi_builtin = 1;
@ -543,7 +520,6 @@ c_decode_option (argc, argv)
}
else if (!strcmp (argstart, "gnu89"))
{
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 0;
flag_no_nonansi_builtin = 0;
@ -553,7 +529,6 @@ c_decode_option (argc, argv)
}
else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
{
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 0;
flag_no_nonansi_builtin = 0;
@ -1482,14 +1457,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
match enough. Ultimately, copy most of the information from the new
decl to the old one, and keep using the old one. */
if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL
&& IDENTIFIER_IMPLICIT_DECL (DECL_NAME (newdecl)) == olddecl
&& DECL_INITIAL (olddecl) == 0)
/* If -traditional, avoid error for redeclaring fcn
after implicit decl. */
;
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_BUILT_IN (olddecl))
if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_BUILT_IN (olddecl))
{
/* A function declaration for a built-in function. */
if (!TREE_PUBLIC (newdecl))
@ -1738,12 +1706,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
}
/* Type for passing arg must be consistent
with that declared for the arg. */
if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type))
/* If -traditional, allow `unsigned int' instead of `int'
in the prototype. */
&& (! (flag_traditional
&& TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node
&& TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node)))
if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type)))
{
error_with_decl (newdecl,
"prototype for `%s' follows and argument %d doesn't match",
@ -2194,10 +2157,7 @@ pushdecl (x)
IDENTIFIER_POINTER (name));
t = lookup_name_current_level (name);
/* Don't type check externs here when -traditional. This is so that
code with conflicting declarations inside blocks will get warnings
not errors. X11 for instance depends on this. */
if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional)
if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x))
{
t = IDENTIFIER_GLOBAL_VALUE (name);
/* Type decls at global scope don't conflict with externs declared
@ -2216,9 +2176,8 @@ pushdecl (x)
}
/* If this decl is `static' and an implicit decl was seen previously,
warn. But don't complain if -traditional,
since traditional compilers don't complain. */
if (! flag_traditional && TREE_PUBLIC (name)
warn. */
if (TREE_PUBLIC (name)
/* Don't test for DECL_EXTERNAL, because grokdeclarator
sets this for all functions. */
&& ! TREE_PUBLIC (x)
@ -2312,9 +2271,6 @@ pushdecl (x)
}
/* Multiple external decls of the same identifier ought to match.
Check against both global declarations (when traditional) and out of
scope (limbo) block level declarations.
We get warnings about inline functions where they are defined.
Avoid duplicate warnings where they are used. */
if (TREE_PUBLIC (x)
@ -2322,11 +2278,7 @@ pushdecl (x)
{
tree decl;
if (flag_traditional && IDENTIFIER_GLOBAL_VALUE (name) != 0
&& (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name))
|| TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name))))
decl = IDENTIFIER_GLOBAL_VALUE (name);
else if (IDENTIFIER_LIMBO_VALUE (name) != 0)
if (IDENTIFIER_LIMBO_VALUE (name) != 0)
/* Decls in limbo are always extern, so no need to check that. */
decl = IDENTIFIER_LIMBO_VALUE (name);
else
@ -2356,39 +2308,6 @@ pushdecl (x)
"previous implicit declaration of `%s'");
}
/* In PCC-compatibility mode, extern decls of vars with no current decl
take effect at top level no matter where they are. */
if (flag_traditional && DECL_EXTERNAL (x)
&& lookup_name (name) == 0)
{
tree type = TREE_TYPE (x);
/* But don't do this if the type contains temporary nodes. */
while (type)
{
if (type == error_mark_node)
break;
if (TYPE_CONTEXT (type))
{
warning_with_decl (x, "type of external `%s' is not global");
/* By exiting the loop early, we leave TYPE nonzero,
and thus prevent globalization of the decl. */
break;
}
else if (TREE_CODE (type) == FUNCTION_TYPE
&& TYPE_ARG_TYPES (type) != 0)
/* The types might not be truly local,
but the list of arg types certainly is temporary.
Since prototypes are nontraditional,
ok not to do the traditional thing. */
break;
type = TREE_TYPE (type);
}
if (type == 0)
b = global_binding_level;
}
/* This name is new in its binding level.
Install the new declaration and return it. */
if (b == global_binding_level)
@ -2622,8 +2541,7 @@ implicitly_declare (functionid)
IDENTIFIER_IMPLICIT_DECL (functionid) = decl;
/* ANSI standard says implicit declarations are in the innermost block.
So we record the decl in the standard fashion.
If flag_traditional is set, pushdecl does it top-level. */
So we record the decl in the standard fashion. */
pushdecl (decl);
/* This is a no-op in c-lang.c or something real in objc-actions.c. */
@ -2671,17 +2589,8 @@ redeclaration_error_message (newdecl, olddecl)
{
if (TREE_CODE (newdecl) == TYPE_DECL)
{
if (flag_traditional && TREE_TYPE (newdecl) == TREE_TYPE (olddecl))
return 0;
/* pushdecl creates distinct types for TYPE_DECLs by calling
build_type_copy, so the above comparison generally fails. We do
another test against the TYPE_MAIN_VARIANT of the olddecl, which
is equivalent to what this code used to do before the build_type_copy
call. The variant type distinction should not matter for traditional
code, because it doesn't have type qualifiers. */
if (flag_traditional
&& TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)) == TREE_TYPE (newdecl))
return 0;
/* Do not complain about type redeclarations where at least one
declaration was in a system header. */
if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
return 0;
return 1;
@ -3226,11 +3135,6 @@ builtin_function (name, type, function_code, class, library_name)
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
/* If -traditional, permit redefining a builtin function any way you like.
(Though really, if the program redefines these functions,
it probably won't work right unless compiled with -fno-builtin.) */
if (flag_traditional && name[0] != '_')
DECL_BUILT_IN_NONANSI (decl) = 1;
if (library_name)
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
make_decl_rtl (decl, NULL);
@ -4319,9 +4223,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
/* Decide whether an integer type is signed or not.
Optionally treat bitfields as signed by default. */
if (specbits & 1 << (int) RID_UNSIGNED
/* Traditionally, all bitfields are unsigned. */
|| (bitfield && flag_traditional
&& (! explicit_flag_signed_bitfields || !flag_signed_bitfields))
|| (bitfield && ! flag_signed_bitfields
&& (explicit_int || defaulted_int || explicit_char
/* A typedef for plain `int' without `signed'
@ -4735,13 +4636,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
type = integer_type_node;
}
#ifndef TRADITIONAL_RETURN_FLOAT
/* Traditionally, declaring return type float means double. */
if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node)
type = double_type_node;
#endif /* TRADITIONAL_RETURN_FLOAT */
/* Construct the function type and go to the next
inner layer of declarator. */
@ -5634,7 +5528,7 @@ finish_struct (t, fieldlist, attributes)
if (pedantic)
pedwarn ("%s defined inside parms",
TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
else if (! flag_traditional)
else
warning ("%s defined inside parms",
TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
}
@ -6172,8 +6066,7 @@ build_enumerator (name, value)
type = TREE_TYPE (value);
type = type_for_size (MAX (TYPE_PRECISION (type),
TYPE_PRECISION (integer_type_node)),
((flag_traditional
|| TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node))
(TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node)
&& TREE_UNSIGNED (type)));
decl = build_decl (CONST_DECL, name, type);
@ -6402,12 +6295,10 @@ start_function (declspecs, declarator, attributes)
/* Promote the value to int before returning it. */
if (c_promoting_integer_type_p (restype))
{
/* It retains unsignedness if traditional
or if not really getting wider. */
/* It retains unsignedness if not really getting wider. */
if (TREE_UNSIGNED (restype)
&& (flag_traditional
|| (TYPE_PRECISION (restype)
== TYPE_PRECISION (integer_type_node))))
&& (TYPE_PRECISION (restype)
== TYPE_PRECISION (integer_type_node)))
restype = unsigned_type_node;
else
restype = integer_type_node;
@ -6626,15 +6517,6 @@ store_parm_decls ()
layout_decl (found, 0);
}
/* Traditionally, a parm declared float is actually a double. */
if (found && flag_traditional
&& TYPE_MAIN_VARIANT (TREE_TYPE (found)) == float_type_node)
{
TREE_TYPE (found) = double_type_node;
DECL_ARG_TYPE (found) = double_type_node;
layout_decl (found, 0);
}
/* If no declaration found, default to int. */
if (!found)
{
@ -6768,11 +6650,7 @@ store_parm_decls ()
"prototype declaration");
}
}
/* If -traditional, allow `int' argument to match
`unsigned' prototype. */
else if (! (flag_traditional
&& TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == integer_type_node
&& TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node))
else
{
error ("argument `%s' doesn't match prototype",
IDENTIFIER_POINTER (DECL_NAME (parm)));
@ -6903,13 +6781,6 @@ finish_function (nested)
DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
/* Obey `register' declarations if `setjmp' is called in this fn. */
if (flag_traditional && current_function_calls_setjmp)
{
setjmp_protect (DECL_INITIAL (fndecl));
setjmp_protect_args ();
}
if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted)
{
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
@ -6938,7 +6809,8 @@ finish_function (nested)
finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
/* Complain if there's just no return statement. */
if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
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
@ -6946,9 +6818,9 @@ finish_function (nested)
&& !MAIN_NAME_P (DECL_NAME (fndecl))
/* Or if they didn't actually specify a return type. */
&& !C_FUNCTION_IMPLICIT_INT (fndecl)
/* If we have -Wreturn-type, let flow complain. Unless we're an
/* Normally, with -Wreturn-type, flow will complain. Unless we're an
inline function, as we might never be compiled separately. */
&& (!warn_return_type || DECL_INLINE (fndecl)))
&& DECL_INLINE (fndecl))
warning ("no return statement in function returning non-void");
/* Clear out memory we no longer need. */
@ -7329,10 +7201,10 @@ mark_c_function_context (f)
mark_binding_level (&p->binding_level);
}
/* Copy the DECL_LANG_SPECIFIC data associated with NODE. */
/* Copy the DECL_LANG_SPECIFIC data associated with DECL. */
void
copy_lang_decl (decl)
c_dup_lang_specific_decl (decl)
tree decl;
{
struct lang_decl *ld;

View File

@ -1,3 +1,8 @@
2002-02-28 Jason Merrill <jason@redhat.com>
* decl.c (finish_function): Only warn about missing return
statement with -Wreturn-type.
2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
PR c++/4093

View File

@ -14224,15 +14224,16 @@ finish_function (flags)
DECL_UNINLINABLE (fndecl) = 1;
/* Complain if there's just no return statement. */
if (!processing_template_decl
if (warn_return_type
&& !processing_template_decl
&& TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
&& !current_function_returns_value && !current_function_returns_null
&& !DECL_NAME (DECL_RESULT (fndecl))
/* Don't complain if we abort or throw. */
&& !current_function_returns_abnormally
/* If we have -Wreturn-type, let flow complain. Unless we're an
&& !DECL_NAME (DECL_RESULT (fndecl))
/* Normally, with -Wreturn-type, flow will complain. Unless we're an
inline function, as we might never be compiled separately. */
&& (!warn_return_type || DECL_INLINE (fndecl)))
&& DECL_INLINE (fndecl))
warning ("no return statement in function returning non-void");
/* Clear out memory we no longer need. */

View File

@ -9,7 +9,7 @@ public:
X::x()
{ // ERROR -
} // WARNING - no return
}
X::~x()
{ // ERROR -