Change -w so that warnings can be activated again later on.
authorChristoph Mallon <christoph.mallon@gmx.de>
Sun, 26 Oct 2008 12:11:03 +0000 (12:11 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Sun, 26 Oct 2008 12:11:03 +0000 (12:11 +0000)
[r23205]

diagnostic.c
diagnostic.h
main.c
parser.c
warning.c
warning.h

index 0a582af..585d61b 100644 (file)
@@ -34,8 +34,6 @@ unsigned diagnostic_count = 0;
 unsigned error_count      = 0;
 /** Number of occurred warnings. */
 unsigned warning_count    = 0;
-/** true if warnings should be inhibited */
-bool inhibit_all_warnings = false;
 
 static const source_position_t *curr_pos = NULL;
 
@@ -217,9 +215,6 @@ static void warningvf(const source_position_t *pos,
 
 void warningf(const source_position_t *pos, const char *const fmt, ...)
 {
-       if (inhibit_all_warnings)
-               return;
-
        va_list ap;
        va_start(ap, fmt);
        curr_pos = pos;
index 663e6dc..cb114ef 100644 (file)
@@ -62,7 +62,4 @@ extern unsigned diagnostic_count;
 extern unsigned error_count;
 extern unsigned warning_count;
 
-/* true if warnings should be inhibited */
-extern bool inhibit_all_warnings;
-
 #endif
diff --git a/main.c b/main.c
index 629190a..6595f80 100644 (file)
--- a/main.c
+++ b/main.c
@@ -634,7 +634,7 @@ int main(int argc, char **argv)
                        } else if(SINGLE_OPTION('v')) {
                                verbose = 1;
                        } else if(SINGLE_OPTION('w')) {
-                               inhibit_all_warnings = true;
+                               memset(&warning, 0, sizeof(warning));
                        } else if(option[0] == 'x') {
                                const char *opt;
                                GET_ARG_AFTER(opt, "-x");
index b2d5463..a859dc4 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -1002,36 +1002,42 @@ static void report_assign_error(assign_error_t error, type_t *orig_type_left,
                return;
 
        case ASSIGN_ERROR_POINTER_QUALIFIER_MISSING: {
-               type_t *points_to_left
-                       = skip_typeref(type_left->pointer.points_to);
-               type_t *points_to_right
-                       = skip_typeref(type_right->pointer.points_to);
-
-               /* the left type has all qualifiers from the right type */
-               unsigned missing_qualifiers
-                       = points_to_right->base.qualifiers & ~points_to_left->base.qualifiers;
-               warningf(source_position,
-                        "destination type '%T' in %s from type '%T' lacks qualifiers '%Q' in pointer target type",
-                        orig_type_left, context, orig_type_right, missing_qualifiers);
+               if (warning.other) {
+                       type_t *points_to_left  = skip_typeref(type_left->pointer.points_to);
+                       type_t *points_to_right = skip_typeref(type_right->pointer.points_to);
+
+                       /* the left type has all qualifiers from the right type */
+                       unsigned missing_qualifiers
+                               = points_to_right->base.qualifiers & ~points_to_left->base.qualifiers;
+                       warningf(source_position,
+                                       "destination type '%T' in %s from type '%T' lacks qualifiers '%Q' in pointer target type",
+                                       orig_type_left, context, orig_type_right, missing_qualifiers);
+               }
                return;
        }
 
        case ASSIGN_WARNING_POINTER_INCOMPATIBLE:
-               warningf(source_position,
-                        "destination type '%T' in %s is incompatible with '%E' of type '%T'",
-                                orig_type_left, context, right, orig_type_right);
+               if (warning.other) {
+                       warningf(source_position,
+                                       "destination type '%T' in %s is incompatible with '%E' of type '%T'",
+                                       orig_type_left, context, right, orig_type_right);
+               }
                return;
 
        case ASSIGN_WARNING_POINTER_FROM_INT:
-               warningf(source_position,
-                        "%s makes pointer '%T' from integer '%T' without a cast",
-                                context, orig_type_left, orig_type_right);
+               if (warning.other) {
+                       warningf(source_position,
+                                       "%s makes pointer '%T' from integer '%T' without a cast",
+                                       context, orig_type_left, orig_type_right);
+               }
                return;
 
        case ASSIGN_WARNING_INT_FROM_POINTER:
-               warningf(source_position,
-                               "%s makes integer '%T' from pointer '%T' without a cast",
-                               context, orig_type_left, orig_type_right);
+               if (warning.other) {
+                       warningf(source_position,
+                                       "%s makes integer '%T' from pointer '%T' without a cast",
+                                       context, orig_type_left, orig_type_right);
+               }
                return;
 
        default:
@@ -1418,7 +1424,8 @@ static void parse_gnu_attribute_mode_arg(gnu_attribute_t *attribute)
        } else if (strcmp_underscore("DI", symbol_str) == 0) {
                attribute->u.akind = ATOMIC_TYPE_LONGLONG;
        } else {
-               warningf(HERE, "ignoring unknown mode '%s'", symbol_str);
+               if (warning.other)
+                       warningf(HERE, "ignoring unknown mode '%s'", symbol_str);
                attribute->invalid = true;
        }
        next_token();
@@ -1856,7 +1863,8 @@ static decl_modifiers_t parse_attributes(gnu_attribute_t **attributes)
 
                case T___thiscall:
                        /* TODO record modifier */
-                       warningf(HERE, "Ignoring declaration modifier %K", &token);
+                       if (warning.other)
+                               warningf(HERE, "Ignoring declaration modifier %K", &token);
                        break;
 
 end_error:
@@ -2225,7 +2233,8 @@ static initializer_t *parse_scalar_initializer(type_t *type,
        /* there might be extra {} hierarchies */
        int braces = 0;
        if (token.type == '{') {
-               warningf(HERE, "extra curly braces around scalar initializer");
+               if (warning.other)
+                       warningf(HERE, "extra curly braces around scalar initializer");
                do {
                        ++braces;
                        next_token();
@@ -2256,7 +2265,7 @@ static initializer_t *parse_scalar_initializer(type_t *type,
                        next_token();
                }
                if (token.type != '}') {
-                       if (!additional_warning_displayed) {
+                       if (!additional_warning_displayed && warning.other) {
                                warningf(HERE, "additional elements in scalar initializer");
                                additional_warning_displayed = true;
                        }
@@ -2688,7 +2697,7 @@ finish_designator:
                                        if (token.type == ',') {
                                                next_token();
                                        }
-                                       if (token.type != '}') {
+                                       if (token.type != '}' && warning.other) {
                                                warningf(HERE, "excessive elements in initializer for type '%T'",
                                                                 orig_type);
                                        }
@@ -2735,11 +2744,14 @@ finish_designator:
                        ARR_APP1(initializer_t*, initializers, sub);
                } else {
 error_excess:
-                       if (env->declaration != NULL)
-                               warningf(HERE, "excess elements in struct initializer for '%Y'",
-                                env->declaration->symbol);
-                       else
-                               warningf(HERE, "excess elements in struct initializer");
+                       if (warning.other) {
+                               if (env->declaration != NULL) {
+                                       warningf(HERE, "excess elements in struct initializer for '%Y'",
+                                          env->declaration->symbol);
+                               } else {
+                                       warningf(HERE, "excess elements in struct initializer");
+                               }
+                       }
                }
 
 error_parse_next:
@@ -3171,7 +3183,7 @@ static bool check_alignment_value(long long intvalue)
 }
 
 #define DET_MOD(name, tag) do { \
-       if (*modifiers & tag) warningf(HERE, #name " used more than once"); \
+       if (*modifiers & tag && warning.other) warningf(HERE, #name " used more than once"); \
        *modifiers |= tag; \
 } while (0)
 
@@ -3193,7 +3205,7 @@ static void parse_microsoft_extended_decl_modifier(declaration_specifiers_t *spe
                        if (token.type != T_INTEGER)
                                goto end_error;
                        if (check_alignment_value(token.v.intvalue)) {
-                               if (specifiers->alignment != 0)
+                               if (specifiers->alignment != 0 && warning.other)
                                        warningf(HERE, "align used more than once");
                                specifiers->alignment = (unsigned char)token.v.intvalue;
                        }
@@ -3281,7 +3293,7 @@ static void parse_microsoft_extended_decl_modifier(declaration_specifiers_t *spe
                        expect(')');
                } else if (symbol == sym_deprecated) {
                        next_token();
-                       if (specifiers->deprecated != 0)
+                       if (specifiers->deprecated != 0 && warning.other)
                                warningf(HERE, "deprecated used more than once");
                        specifiers->deprecated = 1;
                        if (token.type == '(') {
@@ -3298,7 +3310,8 @@ static void parse_microsoft_extended_decl_modifier(declaration_specifiers_t *spe
                        next_token();
                        DET_MOD(noalias, DM_NOALIAS);
                } else {
-                       warningf(HERE, "Unknown modifier %Y ignored", token.v.symbol);
+                       if (warning.other)
+                               warningf(HERE, "Unknown modifier %Y ignored", token.v.symbol);
                        next_token();
                        if (token.type == '(')
                                skip_until(')');
@@ -4378,7 +4391,7 @@ static type_t *construct_declarator_type(construct_type_t *construct_list,
                        } else if (is_type_array(skipped_return_type)) {
                                errorf(HERE, "function returning array is not allowed");
                        } else {
-                               if (skipped_return_type->base.qualifiers != 0) {
+                               if (skipped_return_type->base.qualifiers != 0 && warning.other) {
                                        warningf(HERE,
                                                "type qualifiers in return type of function type are meaningless");
                                }
@@ -4827,28 +4840,30 @@ static void parse_anonymous_declaration_rest(
 {
        eat(';');
 
-       if (specifiers->declared_storage_class != STORAGE_CLASS_NONE) {
-               warningf(&specifiers->source_position,
-                        "useless storage class in empty declaration");
-       }
+       if (warning.other) {
+               if (specifiers->declared_storage_class != STORAGE_CLASS_NONE) {
+                       warningf(&specifiers->source_position,
+                                "useless storage class in empty declaration");
+               }
 
-       type_t *type = specifiers->type;
-       switch (type->kind) {
-               case TYPE_COMPOUND_STRUCT:
-               case TYPE_COMPOUND_UNION: {
-                       if (type->compound.declaration->symbol == NULL) {
-                               warningf(&specifiers->source_position,
-                                        "unnamed struct/union that defines no instances");
+               type_t *type = specifiers->type;
+               switch (type->kind) {
+                       case TYPE_COMPOUND_STRUCT:
+                       case TYPE_COMPOUND_UNION: {
+                               if (type->compound.declaration->symbol == NULL) {
+                                       warningf(&specifiers->source_position,
+                                                "unnamed struct/union that defines no instances");
+                               }
+                               break;
                        }
-                       break;
-               }
 
-               case TYPE_ENUM:
-                       break;
+                       case TYPE_ENUM:
+                               break;
 
-               default:
-                       warningf(&specifiers->source_position, "empty declaration");
-                       break;
+                       default:
+                               warningf(&specifiers->source_position, "empty declaration");
+                               break;
+               }
        }
 
 #ifdef RECORD_EMPTY_DECLARATIONS
@@ -4876,8 +4891,9 @@ static void parse_declaration_rest(declaration_t *ndeclaration,
                type_t *orig_type = declaration->type;
                type_t *type      = skip_typeref(orig_type);
 
-               if (type->kind != TYPE_FUNCTION &&
-                   declaration->is_inline &&
+               if (warning.other               &&
+                               type->kind != TYPE_FUNCTION &&
+                   declaration->is_inline      &&
                    is_type_valid(type)) {
                        warningf(&declaration->source_position,
                                 "variable '%Y' declared 'inline'\n", declaration->symbol);
@@ -6485,7 +6501,7 @@ static expression_t *parse_statement_expression(void)
                if (stmt->kind == STATEMENT_EXPRESSION) {
                        type = stmt->expression.expression->base.type;
                }
-       } else {
+       } else if (warning.other) {
                warningf(&expression->base.source_position, "empty statement expression ({})");
        }
        expression->base.type = type;
@@ -7491,10 +7507,12 @@ static expression_t *parse_conditional_expression(expression_t *expression)
 
        /* 6.5.15.3 */
        type_t *result_type;
-       if (is_type_atomic(true_type, ATOMIC_TYPE_VOID) ||
-               is_type_atomic(false_type, ATOMIC_TYPE_VOID)) {
-               if (!is_type_atomic(true_type, ATOMIC_TYPE_VOID)
-                   || !is_type_atomic(false_type, ATOMIC_TYPE_VOID)) {
+       if (is_type_atomic(true_type,  ATOMIC_TYPE_VOID) ||
+                       is_type_atomic(false_type, ATOMIC_TYPE_VOID)) {
+               if (warning.other && (
+                                       !is_type_atomic(true_type,  ATOMIC_TYPE_VOID) ||
+                                       !is_type_atomic(false_type, ATOMIC_TYPE_VOID)
+                               )) {
                        warningf(&conditional->base.source_position,
                                        "ISO C forbids conditional expression with only one void side");
                }
@@ -7541,9 +7559,11 @@ static expression_t *parse_conditional_expression(expression_t *expression)
                                                    get_unqualified_type(to2))) {
                                to = to1;
                        } else {
-                               warningf(&conditional->base.source_position,
-                                       "pointer types '%T' and '%T' in conditional expression are incompatible",
-                                       true_type, false_type);
+                               if (warning.other) {
+                                       warningf(&conditional->base.source_position,
+                                                       "pointer types '%T' and '%T' in conditional expression are incompatible",
+                                                       true_type, false_type);
+                               }
                                to = type_void;
                        }
 
@@ -7551,8 +7571,10 @@ static expression_t *parse_conditional_expression(expression_t *expression)
                                get_qualified_type(to, to1->base.qualifiers | to2->base.qualifiers);
                        result_type = make_pointer_type(type, TYPE_QUALIFIER_NONE);
                } else if (is_type_integer(other_type)) {
-                       warningf(&conditional->base.source_position,
-                                       "pointer/integer type mismatch in conditional expression ('%T' and '%T')", true_type, false_type);
+                       if (warning.other) {
+                               warningf(&conditional->base.source_position,
+                                               "pointer/integer type mismatch in conditional expression ('%T' and '%T')", true_type, false_type);
+                       }
                        result_type = pointer_type;
                } else {
                        if (is_type_valid(other_type)) {
@@ -8093,11 +8115,11 @@ static void semantic_sub(binary_expression_t *expression)
                               "subtracting pointers to incompatible types '%T' and '%T'",
                               orig_type_left, orig_type_right);
                } else if (!is_type_object(unqual_left)) {
-                       if (is_type_atomic(unqual_left, ATOMIC_TYPE_VOID)) {
-                               warningf(pos, "subtracting pointers to void");
-                       } else {
+                       if (!is_type_atomic(unqual_left, ATOMIC_TYPE_VOID)) {
                                errorf(pos, "subtracting pointers to non-object types '%T'",
                                       orig_type_left);
+                       } else if (warning.other) {
+                               warningf(pos, "subtracting pointers to void");
                        }
                }
                expression->base.type = type_ptrdiff_t;
@@ -8958,7 +8980,7 @@ static statement_t *parse_case_statement(void)
                                long const val = fold_constant(end_range);
                                statement->case_label.last_case = val;
 
-                               if (val < statement->case_label.first_case) {
+                               if (warning.other && val < statement->case_label.first_case) {
                                        statement->case_label.is_empty_range = true;
                                        warningf(pos, "empty range specified");
                                }
@@ -9086,7 +9108,7 @@ static statement_t *parse_label_statement(void)
 
        if (token.type == '}') {
                /* TODO only warn? */
-               if (false) {
+               if (warning.other && false) {
                        warningf(HERE, "label at end of compound statement");
                        statement->label.statement = create_empty_statement();
                } else {
@@ -9415,7 +9437,7 @@ static statement_t *parse_goto(void)
                        if (!is_type_pointer(type) && !is_type_integer(type)) {
                                errorf(&expression->base.source_position,
                                        "cannot convert to a pointer type");
-                       } else if (type != type_void_ptr) {
+                       } else if (warning.other && type != type_void_ptr) {
                                warningf(&expression->base.source_position,
                                        "type of computed goto expression should be 'void*' not '%T'", type);
                        }
@@ -9588,10 +9610,12 @@ static statement_t *parse_return(void)
        if (return_value != NULL) {
                type_t *return_value_type = skip_typeref(return_value->base.type);
 
-               if (is_type_atomic(return_type, ATOMIC_TYPE_VOID)
-                               && !is_type_atomic(return_value_type, ATOMIC_TYPE_VOID)) {
-                       warningf(&statement->base.source_position,
-                                "'return' with a value, in function returning void");
+               if (is_type_atomic(return_type,        ATOMIC_TYPE_VOID) &&
+                               !is_type_atomic(return_value_type, ATOMIC_TYPE_VOID)) {
+                       if (warning.other) {
+                               warningf(&statement->base.source_position,
+                                               "'return' with a value, in function returning void");
+                       }
                        return_value = NULL;
                } else {
                        assign_error_t error = semantic_assign(return_type, return_value);
@@ -9600,7 +9624,8 @@ static statement_t *parse_return(void)
                        return_value = create_implicit_cast(return_value, return_type);
                }
                /* check for returning address of a local var */
-               if (return_value != NULL &&
+               if (warning.other        &&
+                               return_value != NULL &&
                                return_value->base.kind == EXPR_UNARY_TAKE_ADDRESS) {
                        const expression_t *expression = return_value->unary.value;
                        if (is_local_variable(expression)) {
@@ -9608,11 +9633,9 @@ static statement_t *parse_return(void)
                                         "function returns address of local variable");
                        }
                }
-       } else {
-               if (!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
-                       warningf(&statement->base.source_position,
-                                "'return' without value, in function returning non-void");
-               }
+       } else if (warning.other && !is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
+               warningf(&statement->base.source_position,
+                               "'return' without value, in function returning non-void");
        }
        statement->returns.value = return_value;
 
@@ -10130,7 +10153,8 @@ static void parse_translation_unit(void)
 
                        case ';':
                                if (!strict_mode) {
-                                       warningf(HERE, "stray ';' outside of function");
+                                       if (warning.other)
+                                               warningf(HERE, "stray ';' outside of function");
                                        next_token();
                                        break;
                                }
index 894b782..df0b7f5 100644 (file)
--- a/warning.c
+++ b/warning.c
@@ -22,6 +22,8 @@
 #include "warning.h"
 
 warning_t warning = {
+       .other                         = true,
+
        .address                       = true,
        .aggregate_return              = false,
        .attribute                     = true,
@@ -88,6 +90,8 @@ void set_warning_opt(const char *const opt)
 #define OPT(x, y) OPTX(x) SET(y)
        OPTX("all") {
                /* Note: this switched on a lot of more warnings than gcc's -Wall */
+               SET(other);
+
                SET(address);
                SET(attribute);
                SET(char_subscripts);
index 31d9005..90f3ca6 100644 (file)
--- a/warning.h
+++ b/warning.h
@@ -25,6 +25,8 @@
 void set_warning_opt(const char *opt);
 
 typedef struct warning_t {
+       bool other:1;                         /**< Warnings not covered by any option below */
+
        bool address:1;                       /**< Warn about suspicious uses of memory addresses */
        bool aggregate_return:1;              /**< Warn if any functions that return structures or unions are defined or called */
        bool attribute:1;                     /**< Warn if an unexpected `__attribute__' is used or function attributes applied to variables, etc. */