Implement -Wmissing-noreturn.
authorChristoph Mallon <christoph.mallon@gmx.de>
Mon, 25 Aug 2008 08:09:56 +0000 (08:09 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Mon, 25 Aug 2008 08:09:56 +0000 (08:09 +0000)
[r21431]

parser.c
warning.c
warning.h

index 4007c8f..6c390b5 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -4674,6 +4674,8 @@ static int determine_truth(expression_t const* const cond)
                -1;
 }
 
+static bool noreturn_candidate;
+
 static void check_reachable(statement_t *const stmt)
 {
        if (stmt->base.reachable)
@@ -4696,6 +4698,7 @@ static void check_reachable(statement_t *const stmt)
                        break;
 
                case STATEMENT_RETURN:
+                       noreturn_candidate = false;
                        return;
 
                case STATEMENT_IF: {
@@ -4877,6 +4880,8 @@ found_break_parent:
        while (next == NULL) {
                next = last->base.parent;
                if (next == NULL) {
+                       noreturn_candidate = false;
+
                        type_t *const type = current_function->type;
                        assert(is_type_function(type));
                        type_t *const ret  = skip_typeref(type->function.return_type);
@@ -5201,10 +5206,20 @@ static void parse_external_declaration(void)
                first_err = true;
                check_labels();
                check_declarations();
-               if (warning.return_type || warning.unreachable_code) {
+               if (warning.return_type      ||
+                   warning.unreachable_code ||
+                   (warning.missing_noreturn && !(declaration->modifiers & DM_NORETURN))) {
+                       noreturn_candidate = true;
                        check_reachable(body);
                        if (warning.unreachable_code)
                                check_unreachable(body);
+                       if (warning.missing_noreturn &&
+                           noreturn_candidate       &&
+                           !(declaration->modifiers & DM_NORETURN)) {
+                               warningf(&body->base.source_position,
+                                        "function '%#T' is candidate for attribute 'noreturn'",
+                                        type, declaration->symbol);
+                       }
                }
 
                assert(current_parent   == NULL);
index a25cb0b..ad9f1aa 100644 (file)
--- a/warning.c
+++ b/warning.c
@@ -35,6 +35,7 @@ warning_t warning = {
        .long_long                     = false,
        .main                          = true,
        .missing_declarations          = false,
+       .missing_noreturn              = false,
        .missing_prototypes            = false,
        .multichar                     = true,
        .nested_externs                = false,
@@ -124,6 +125,7 @@ void set_warning_opt(const char *const opt)
        OPT("long-long",                     long_long);
        OPT("main",                          main);
        OPT("missing-declarations",          missing_declarations);
+       OPT("missing-noreturn",              missing_noreturn);
        OPT("missing-prototypes",            missing_prototypes);
        OPT("multichar",                     multichar);
        OPT("nested-externs",                nested_externs);
index da1815a..380161e 100644 (file)
--- a/warning.h
+++ b/warning.h
@@ -62,8 +62,8 @@ typedef struct warning_t {
        bool missing_declarations:1;          /**< Warn if a global function is defined without a previous declaration */
 #if 0 // TODO
        bool missing_format_attribute:1;      /**< If '-Wformat' is enabled, also warn about functions which might be candidates for 'format' attributes */
-       bool missing_noreturn:1;              /**< Warn about functions which might be candidates for attribute 'noreturn' */
 #endif
+       bool missing_noreturn:1;              /**< Warn about functions which might be candidates for attribute 'noreturn' */
        bool missing_prototypes:1;            /**< Warn if a global function is defined without a previous prototype declaration */
        bool multichar:1;                     /**< Warn if a multicharacter constant ('FOOF') is used. */
        bool nested_externs:1;                /**< Warn if an 'extern' declaration is encountered within a function */