diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/c-decl.c | 31 | ||||
-rw-r--r-- | gcc/c-tree.h | 9 | ||||
-rw-r--r-- | gcc/c-typeck.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20011029-2.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/980816-1.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/990117-1.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/990213-2.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/990214-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/990524-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/991214-1.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/asm-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/asm-3.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/attr-invalid.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/attr-noinline.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/deprecated.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/struct-ret-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.misc-tests/bprob-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.misc-tests/gcov-4.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.misc-tests/gcov-4b.c | 2 |
20 files changed, 86 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 96baa91..c1ba34f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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: diff --git a/gcc/c-decl.c b/gcc/c-decl.c index af6a2c0..746fa47 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -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; diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 03bd683..8f53b17 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -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. */ diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 8c34a17..dc844bf 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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)); diff --git a/gcc/testsuite/gcc.dg/20011029-2.c b/gcc/testsuite/gcc.dg/20011029-2.c index 77a5b07..b184af0 100644 --- a/gcc/testsuite/gcc.dg/20011029-2.c +++ b/gcc/testsuite/gcc.dg/20011029-2.c @@ -20,4 +20,5 @@ int foo (int s) : "cc"); r; })) continue; } + return 0; } diff --git a/gcc/testsuite/gcc.dg/980816-1.c b/gcc/testsuite/gcc.dg/980816-1.c index 2a96ef4..8581d99 100644 --- a/gcc/testsuite/gcc.dg/980816-1.c +++ b/gcc/testsuite/gcc.dg/980816-1.c @@ -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; } diff --git a/gcc/testsuite/gcc.dg/990117-1.c b/gcc/testsuite/gcc.dg/990117-1.c index 2e7ea5a..606ba44 100644 --- a/gcc/testsuite/gcc.dg/990117-1.c +++ b/gcc/testsuite/gcc.dg/990117-1.c @@ -18,4 +18,5 @@ foo () for (i = 0; i < 10; i++) ; fabs (x - y); + return 0; } diff --git a/gcc/testsuite/gcc.dg/990213-2.c b/gcc/testsuite/gcc.dg/990213-2.c index 6e6b924..a0a13b5 100644 --- a/gcc/testsuite/gcc.dg/990213-2.c +++ b/gcc/testsuite/gcc.dg/990213-2.c @@ -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; } diff --git a/gcc/testsuite/gcc.dg/990214-1.c b/gcc/testsuite/gcc.dg/990214-1.c index 492c6a7..7ad81b6 100644 --- a/gcc/testsuite/gcc.dg/990214-1.c +++ b/gcc/testsuite/gcc.dg/990214-1.c @@ -12,4 +12,6 @@ bar (int64_t which) case 5 : case 2 : ; } + + return 0; } diff --git a/gcc/testsuite/gcc.dg/990524-1.c b/gcc/testsuite/gcc.dg/990524-1.c index b87b588..8b10172 100644 --- a/gcc/testsuite/gcc.dg/990524-1.c +++ b/gcc/testsuite/gcc.dg/990524-1.c @@ -34,5 +34,5 @@ p_frames_to_multilayer(t_anim_info *ainfo_ptr, break; l_cur_frame_nr += l_step; } + return 0; } - diff --git a/gcc/testsuite/gcc.dg/991214-1.c b/gcc/testsuite/gcc.dg/991214-1.c index 5b9f56c..c8e3a04 100644 --- a/gcc/testsuite/gcc.dg/991214-1.c +++ b/gcc/testsuite/gcc.dg/991214-1.c @@ -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)); } diff --git a/gcc/testsuite/gcc.dg/asm-2.c b/gcc/testsuite/gcc.dg/asm-2.c index 5adee41..9c464ce 100644 --- a/gcc/testsuite/gcc.dg/asm-2.c +++ b/gcc/testsuite/gcc.dg/asm-2.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-options "" } */ -int f() +void f() { asm volatile ("foo%%bar" : : ); } diff --git a/gcc/testsuite/gcc.dg/asm-3.c b/gcc/testsuite/gcc.dg/asm-3.c index e7db804..917942d 100644 --- a/gcc/testsuite/gcc.dg/asm-3.c +++ b/gcc/testsuite/gcc.dg/asm-3.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-options "" } */ -int f() +void f() { asm ("foo%%bar"); } diff --git a/gcc/testsuite/gcc.dg/attr-invalid.c b/gcc/testsuite/gcc.dg/attr-invalid.c index 768921d..a999c26 100644 --- a/gcc/testsuite/gcc.dg/attr-invalid.c +++ b/gcc/testsuite/gcc.dg/attr-invalid.c @@ -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; } diff --git a/gcc/testsuite/gcc.dg/attr-noinline.c b/gcc/testsuite/gcc.dg/attr-noinline.c index 903959e..ee48eb9 100644 --- a/gcc/testsuite/gcc.dg/attr-noinline.c +++ b/gcc/testsuite/gcc.dg/attr-noinline.c @@ -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 (); diff --git a/gcc/testsuite/gcc.dg/deprecated.c b/gcc/testsuite/gcc.dg/deprecated.c index bc82c6d..8355747 100644 --- a/gcc/testsuite/gcc.dg/deprecated.c +++ b/gcc/testsuite/gcc.dg/deprecated.c @@ -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" "" } */ diff --git a/gcc/testsuite/gcc.dg/struct-ret-2.c b/gcc/testsuite/gcc.dg/struct-ret-2.c index b440bcf..0d9b86f 100644 --- a/gcc/testsuite/gcc.dg/struct-ret-2.c +++ b/gcc/testsuite/gcc.dg/struct-ret-2.c @@ -4,7 +4,7 @@ Copyright (C) 1999 Free Software Foundation */ /* { dg-do compile } */ -/* { dg-options "-O3" } */ +/* { dg-options "-O3 -w" } */ struct { unsigned i[4]; diff --git a/gcc/testsuite/gcc.misc-tests/bprob-1.c b/gcc/testsuite/gcc.misc-tests/bprob-1.c index 3d6055a..9420250 100644 --- a/gcc/testsuite/gcc.misc-tests/bprob-1.c +++ b/gcc/testsuite/gcc.misc-tests/bprob-1.c @@ -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); diff --git a/gcc/testsuite/gcc.misc-tests/gcov-4.c b/gcc/testsuite/gcc.misc-tests/gcov-4.c index d5986fe..27ef508 100644 --- a/gcc/testsuite/gcc.misc-tests/gcov-4.c +++ b/gcc/testsuite/gcc.misc-tests/gcov-4.c @@ -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); diff --git a/gcc/testsuite/gcc.misc-tests/gcov-4b.c b/gcc/testsuite/gcc.misc-tests/gcov-4b.c index 6bc20e0..72870b2 100644 --- a/gcc/testsuite/gcc.misc-tests/gcov-4b.c +++ b/gcc/testsuite/gcc.misc-tests/gcov-4b.c @@ -41,7 +41,7 @@ test_for2 (int m, int n, int o) return for_temp; } -int +void call_for () { for_val1 += test_for1 (0); |