c-decl.c (finish_function): Warn about a non-void function with no return statement and no abnormal exit.

* c-decl.c (finish_function): Warn about a non-void function with
        no return statement and no abnormal exit.
        (current_function_returns_abnormally): New variable.
        (start_function): Clear it.
        (struct c_language_function): Add returns_abnormally.
        (push_c_function_context): Save it.
        (pop_c_function_context): Restore it.
        (builtin_function): Set TREE_THIS_VOLATILE on return fns.
        (grokdeclarator): Set C_FUNCTION_IMPLICIT_INT on functions without
        an explicit return type.
        * c-tree.h: Declare current_function_returns_abnormally.
        (C_FUNCTION_IMPLICIT_INT): New macro.
        * c-typeck.c (build_function_call): Set it.
        (c_expand_return): Set current_function_returns_value even if the
        value is erroneous.

From-SVN: r49551
This commit is contained in:
Jason Merrill 2002-02-06 15:40:18 -05:00 committed by Jason Merrill
parent caaf2272c0
commit 5ce89b2ef0
20 changed files with 86 additions and 17 deletions

View File

@ -1,3 +1,21 @@
2002-02-06 Jason Merrill <jason@redhat.com>
* c-decl.c (finish_function): Warn about a non-void function with
no return statement and no abnormal exit.
(current_function_returns_abnormally): New variable.
(start_function): Clear it.
(struct c_language_function): Add returns_abnormally.
(push_c_function_context): Save it.
(pop_c_function_context): Restore it.
(builtin_function): Set TREE_THIS_VOLATILE on return fns.
(grokdeclarator): Set C_FUNCTION_IMPLICIT_INT on functions without
an explicit return type.
* c-tree.h: Declare current_function_returns_abnormally.
(C_FUNCTION_IMPLICIT_INT): New macro.
* c-typeck.c (build_function_call): Set it.
(c_expand_return): Set current_function_returns_value even if the
value is erroneous.
2002-02-06 Jakub Jelinek <jakub@redhat.com>
PR c/5420:

View File

@ -134,6 +134,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. */
@ -3214,6 +3219,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] != '_')
@ -5086,6 +5095,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
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))
{
@ -6175,6 +6187,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;
@ -6904,6 +6917,21 @@ 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 (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)
/* If we have -Wreturn-type, let flow complain. Unless we're an
inline function, as we might never be compiled separately. */
&& (!warn_return_type || 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
@ -7193,6 +7221,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;
@ -7216,6 +7245,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;
@ -7253,6 +7283,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;

View File

@ -132,6 +132,10 @@ struct lang_type
/* Record whether a typedef for type `int' was actually `signed int'. */
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
/* For a FUNCTION_DECL, nonzero if it was defined without an explicit
return type. */
#define C_FUNCTION_IMPLICIT_INT(EXP) DECL_LANG_FLAG_1 (EXP)
/* Nonzero for a declaration of a built in function if there has been no
occasion that would declare the function in ordinary C.
Using the function draws a pedantic warning in this case. */
@ -277,6 +281,11 @@ extern int current_function_returns_value;
extern 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. */
extern int current_function_returns_abnormally;
/* Nonzero means the expression being parsed will never be evaluated.
This is a count, since unevaluated expressions can nest. */

View File

@ -1547,6 +1547,9 @@ build_function_call (function, params)
return error_mark_node;
}
if (fundecl && TREE_THIS_VOLATILE (fundecl))
current_function_returns_abnormally = 1;
/* fntype now gets the type of function pointed to. */
fntype = TREE_TYPE (fntype);
@ -7084,6 +7087,7 @@ c_expand_return (retval)
tree res = DECL_RESULT (current_function_decl);
tree inner;
current_function_returns_value = 1;
if (t == error_mark_node)
return NULL_TREE;
@ -7141,7 +7145,6 @@ c_expand_return (retval)
}
retval = build (MODIFY_EXPR, TREE_TYPE (res), res, t);
current_function_returns_value = 1;
}
return add_stmt (build_return_stmt (retval));

View File

@ -20,4 +20,5 @@ int foo (int s)
: "cc"); r; }))
continue;
}
return 0;
}

View File

@ -17,4 +17,5 @@ div_and_round_double (lden_orig, hden_orig)
quo[i] = work / (unsigned int ) lden;
carry = work % (unsigned int ) lden;
}
return 0;
}

View File

@ -18,4 +18,5 @@ foo ()
for (i = 0; i < 10; i++)
;
fabs (x - y);
return 0;
}

View File

@ -12,4 +12,5 @@ XmlInitUnknownEncoding(void *mem)
struct unknown_encoding *e = mem;
for (i = 0; i < sizeof(struct normal_encoding); i++)
((char *)mem)[i] = ((char *)&latin1_encoding)[i];
return 0;
}

View File

@ -12,4 +12,6 @@ bar (int64_t which)
case 5 :
case 2 : ;
}
return 0;
}

View File

@ -34,5 +34,5 @@ p_frames_to_multilayer(t_anim_info *ainfo_ptr,
break;
l_cur_frame_nr += l_step;
}
return 0;
}

View File

@ -3,8 +3,8 @@
/* Test against a problem with the combiner substituting explicit hard reg
references when it shouldn't. */
int foo (int, int) __attribute__ ((regparm (3)));
int foo (int x, int y)
void foo (int, int) __attribute__ ((regparm (3)));
void foo (int x, int y)
{
__asm__ __volatile__("" : : "d" (x), "r" (y));
}

View File

@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "" } */
int f()
void f()
{
asm volatile ("foo%%bar" : : );
}

View File

@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "" } */
int f()
void f()
{
asm ("foo%%bar");
}

View File

@ -21,13 +21,14 @@ int ATSYM(var) ATTR; /* { dg-warning "attribute ignored" "" } */
int ATSYM(fn_knrarg) (arg)
int arg ATTR; /* { dg-warning "attribute ignored" "" } */
{}
{ return 0; }
int ATSYM(fn_isoarg) (int arg ATTR) {} /* { dg-warning "attribute ignored" "" } */
int ATSYM(fn_isoarg) (int arg ATTR) { return 0; } /* { dg-warning "attribute ignored" "" } */
int ATSYM(fn_vars) (void) {
static int svar ATTR; /* { dg-warning "attribute ignored" "" } */
auto int lvar ATTR; /* { dg-warning "attribute ignored" "" } */
return 0;
}
@ -46,11 +47,12 @@ int ATSYM(var) ATTR; /* { dg-warning "attribute ignored" "" } */
int ATSYM(fn_knrarg) (arg)
int arg ATTR; /* { dg-warning "attribute ignored" "" } */
{}
{ return 0; }
int ATSYM(fn_isoarg) (int arg ATTR) {} /* { dg-warning "attribute ignored" "" } */
int ATSYM(fn_isoarg) (int arg ATTR) { return 0; } /* { dg-warning "attribute ignored" "" } */
int ATSYM(fn_vars) (void) {
static int svar ATTR; /* { dg-warning "attribute ignored" "" } */
auto int lvar ATTR; /* { dg-warning "attribute ignored" "" } */
return 0;
}

View File

@ -43,7 +43,7 @@ static inline void function_declaration_noinline_inline_before(void); /* { dg-wa
static void function_declaration_noinline_inline_before(void) {}
int f () {
void f () {
function_definition ();
function_declaration_both_before ();
function_declaration_both_after ();

View File

@ -13,10 +13,10 @@ INT1 should_be_unavailable; /* { dg-warning "`INT1' is deprecated" "" } */
INT1a should_not_be_deprecated;
INT1 f1(void) __attribute__ ((deprecated));
INT1 f2(void) {} /* { dg-warning "`INT1' is deprecated" "" } */
INT1 f2(void) { return 0; } /* { dg-warning "`INT1' is deprecated" "" } */
INT2 f3(void) __attribute__ ((__deprecated__));
INT2 f4(void) {} /* { dg-warning "`INT2' is deprecated" "" } */
INT2 f4(void) { return 0; } /* { dg-warning "`INT2' is deprecated" "" } */
int f5(INT2 x); /* { dg-warning "`INT2' is deprecated" "" } */
int f6(INT2 x) __attribute__ ((__deprecated__)); /* { dg-warning "`INT2' is deprecated" "" } */

View File

@ -4,7 +4,7 @@
Copyright (C) 1999 Free Software Foundation */
/* { dg-do compile } */
/* { dg-options "-O3" } */
/* { dg-options "-O3 -w" } */
struct {
unsigned i[4];

View File

@ -68,7 +68,7 @@ test_for2 (int m, int n, int o)
return for_temp; /* count(6) */
}
int
void
call_for ()
{
for_val1 += test_for1 (0);

View File

@ -68,7 +68,7 @@ test_for2 (int m, int n, int o)
return for_temp; /* count(6) */
}
int
void
call_for ()
{
for_val1 += test_for1 (0);

View File

@ -41,7 +41,7 @@ test_for2 (int m, int n, int o)
return for_temp;
}
int
void
call_for ()
{
for_val1 += test_for1 (0);