From 0360859a0ff82d6509986100d1600defb88c27c5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 17 Feb 2004 00:39:21 +0000 Subject: [PATCH] all warnings (except for @self and self) are now fully controllable --- tools/qfcc/include/options.h | 6 ++ tools/qfcc/source/class.c | 19 ++++-- tools/qfcc/source/def.c | 4 +- tools/qfcc/source/emit.c | 23 +++++--- tools/qfcc/source/expr.c | 49 ++++++++++------ tools/qfcc/source/method.c | 2 +- tools/qfcc/source/options.c | 111 ++++++++++++++++++++++------------- 7 files changed, 138 insertions(+), 76 deletions(-) diff --git a/tools/qfcc/include/options.h b/tools/qfcc/include/options.h index 1f94dd74a..cfdfed6d7 100644 --- a/tools/qfcc/include/options.h +++ b/tools/qfcc/include/options.h @@ -49,6 +49,12 @@ typedef struct { qboolean vararg_integer; // Warn on passing an integer to vararg func qboolean integer_divide; // Warn on integer constant division qboolean interface_check; // Warn for methods not in interface + qboolean unused; // Warn on unused local variables + qboolean executable; // Warn on expressions with no effect + qboolean traditional; // Warn on bogus constructs allowed by qcc + qboolean precedence; // Warn on precedence issues + qboolean initializer; // Warn on excessive initializer elements + qboolean unimplemented; // Warn on unimplemented class methods } warn_options_t; typedef struct { diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index 946ba1d47..938eca462 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -467,8 +467,10 @@ class_message_response (class_t *class, int class_msg, expr_t *sel) m = find_method (selector->name); if (m) return m; - warning (sel, "could not find method for %c%s", class_msg ? '+' : '-', - selector->name); + //FIXME right option? + if (options.warnings.interface_check) + warning (sel, "could not find method for %c%s", + class_msg ? '+' : '-', selector->name); return 0; } else { while (c) { @@ -486,8 +488,10 @@ class_message_response (class_t *class, int class_msg, expr_t *sel) } c = c->super_class; } - warning (sel, "%s does not respond to %c%s", class->name, - class_msg ? '+' : '-', selector->name); + //FIXME right option? + if (options.warnings.interface_check) + warning (sel, "%s does not respond to %c%s", class->name, + class_msg ? '+' : '-', selector->name); } return 0; } @@ -534,8 +538,11 @@ class_add_ivars (class_t *class, struct_t *ivars) void class_check_ivars (class_t *class, struct_t *ivars) { - if (!struct_compare_fields (class->ivars, ivars)) - warning (0, "instance variable missmatch for %s", class->name); + if (!struct_compare_fields (class->ivars, ivars)) { + //FIXME right option? + if (options.warnings.interface_check) + warning (0, "instance variable missmatch for %s", class->name); + } class->ivars = ivars; } diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index 3ade85575..cc276dcfb 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -51,6 +51,7 @@ static __attribute__ ((unused)) const char rcsid[] = #include "def.h" #include "expr.h" #include "immediate.h" +#include "options.h" #include "reloc.h" #include "strpool.h" #include "struct.h" @@ -486,7 +487,8 @@ flush_scope (scope_t *scope, int force_used) e.line = def->line; e.file = def->file; - warning (&e, "unused variable `%s'", def->name); + if (options.warnings.unused) + warning (&e, "unused variable `%s'", def->name); } if (!def->removed) { Hash_Del (defs_by_name, def->name); diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c index 6d552246b..b5848f4d1 100644 --- a/tools/qfcc/source/emit.c +++ b/tools/qfcc/source/emit.c @@ -271,9 +271,11 @@ emit_assign_expr (int oper, expr_t *e) warning (e1, "assignment to constant %s (Moooooooo!)", def_a->name); } else { - if (options.traditional) - warning (e1, "assignment to constant %s", def_a->name); - else + if (options.traditional) { + //FIXME correct option? + if (options.warnings.cow) + warning (e1, "assignment to constant %s", def_a->name); + } else error (e1, "assignment to constant %s", def_a->name); } } @@ -838,8 +840,9 @@ emit_expr (expr_t *e) emit_statement (e, op_jumpb, def_a, def_b, 0); break; default: - warning (e, "Non-executable statement; " - "executing programmer instead."); + if (options.warnings.executable) + warning (e, "Non-executable statement; " + "executing programmer instead."); break; } break; @@ -855,8 +858,9 @@ emit_expr (expr_t *e) emit_branch (e, op_goto, 0, e->e.expr.e1); break; default: - warning (e, "Non-executable statement; " - "executing programmer instead."); + if (options.warnings.executable) + warning (e, "Non-executable statement; " + "executing programmer instead."); emit_expr (e->e.expr.e1); break; } @@ -876,8 +880,9 @@ emit_expr (expr_t *e) case ex_short: case ex_name: case ex_nil: - warning (e, "Non-executable statement; " - "executing programmer instead."); + if (options.warnings.executable) + warning (e, "Non-executable statement; " + "executing programmer instead."); break; } free_tempdefs (); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 1726a1636..8177a7e38 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -1011,7 +1011,8 @@ test_expr (expr_t *e, int test) abort (); case ev_void: if (options.traditional) { - warning (e, "void has no value"); + if (options.warnings.traditional) + warning (e, "void has no value"); return e; } return error (e, "void has no value"); @@ -1120,9 +1121,11 @@ convert_bool (expr_t *e, int block) expr_t *b; if (e->type == ex_expr && (e->e.expr.op == '=' || e->e.expr.op == PAS) - && !e->paren) - warning (e, - "suggest parentheses around assignment used as truth value"); + && !e->paren) { + if (options.warnings.precedence) + warning (e, "suggest parentheses around assignment " + "used as truth value"); + } if (e->type == ex_uexpr && e->e.expr.op == '!') { e = convert_bool (e->e.expr.e1, 0); @@ -1310,8 +1313,10 @@ check_precedence (int op, expr_t *e1, expr_t *e2) return unary_expr ('!', binary_expr (op, e1->e.expr.e1, e2)); } } else if (op == '&' || op == '|') { - warning (e1, "ambiguous logic. Suggest explicit parentheses with " - "expressions involving ! and %s", get_op_string (op)); + if (options.warnings.precedence) + warning (e1, "ambiguous logic. Suggest explicit parentheses " + "with expressions involving ! and %s", + get_op_string (op)); } } if (options.traditional) { @@ -1344,8 +1349,9 @@ check_precedence (int op, expr_t *e1, expr_t *e2) if (e2->type == ex_expr && !e2->paren) { if ((op == '&' || op == '|' || op == '^') && is_compare (e2->e.expr.op)) { - warning (e2, "suggest parentheses around comparison in " - "operand of %c", op); + if (options.warnings.precedence) + warning (e2, "suggest parentheses around comparison in " + "operand of %c", op); } } } @@ -1827,7 +1833,8 @@ build_function_call (expr_t *fexpr, type_t *ftype, expr_t *params) if (-arg_count > ftype->num_parms + 1) { if (!options.traditional) return error (fexpr, "too few arguments"); - warning (fexpr, "too few arguments"); + if (options.warnings.traditional) + warning (fexpr, "too few arguments"); } parm_count = -ftype->num_parms - 1; } else if (ftype->num_parms >= 0) { @@ -1836,7 +1843,8 @@ build_function_call (expr_t *fexpr, type_t *ftype, expr_t *params) } else if (arg_count < ftype->num_parms) { if (!options.traditional) return error (fexpr, "too few arguments"); - warning (fexpr, "too few arguments"); + if (options.warnings.traditional) + warning (fexpr, "too few arguments"); } parm_count = ftype->num_parms; } @@ -1960,7 +1968,9 @@ return_expr (function_t *f, expr_t *e) if (!e) { if (f->def->type->aux_type != &type_void) { if (options.traditional) { - warning (e, "return from non-void function without a value"); + if (options.warnings.traditional) + warning (e, + "return from non-void function without a value"); e = new_nil_expr (); } else { e = error (e, "return from non-void function without a value"); @@ -1977,7 +1987,8 @@ return_expr (function_t *f, expr_t *e) if (f->def->type->aux_type == &type_void) { if (!options.traditional) return error (e, "returning a value for a void function"); - warning (e, "returning a value for a void function"); + if (options.warnings.traditional) + warning (e, "returning a value for a void function"); } if (e->type == ex_bool) e = convert_from_bool (e, f->def->type->aux_type); @@ -1993,7 +2004,8 @@ return_expr (function_t *f, expr_t *e) } else { if (!options.traditional) return error (e, "void value not ignored as it ought to be"); - warning (e, "void value not ignored as it ought to be"); + if (options.warnings.traditional) + warning (e, "void value not ignored as it ought to be"); //FIXME does anything need to be done here? } } @@ -2001,8 +2013,9 @@ return_expr (function_t *f, expr_t *e) if (!options.traditional) return error (e, "type mismatch for return value of %s", f->def->name); - warning (e, "type mismatch for return value of %s", - f->def->name); + if (options.warnings.traditional) + warning (e, "type mismatch for return value of %s", + f->def->name); } else { if (f->def->type->aux_type != t) e = cast_expr (f->def->type->aux_type, e); @@ -2295,7 +2308,8 @@ assign_expr (expr_t *e1, expr_t *e2) if (!type_assignable (t1, t2)) { if (!options.traditional || t1->type != ev_func || t2->type != ev_func) return type_mismatch (e1, e2, op); - warning (e1, "assignment between disparate function types"); + if (options.warnings.traditional) + warning (e1, "assignment between disparate function types"); } type = t1; if (is_indirect (e1) && is_indirect (e2)) { @@ -2445,7 +2459,8 @@ init_elements (def_t *def, expr_t *eles) return; } if (count > num_params) { - warning (eles, "excessive elements in initializer"); + if (options.warnings.initializer) + warning (eles, "excessive elements in initializer"); count = num_params; } for (i = 0, e = eles->e.block.head; i < count; i++, e = e->next) { diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index 19a889d48..7a950b7a2 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -383,7 +383,7 @@ emit_methods (methodlist_t *_methods, const char *name, int instance) return 0; for (count = 0, method = _methods->head; method; method = method->next) if (!method->instance == !instance) { - if (!method->def) { + if (!method->def && options.warnings.unimplemented) { warning (0, "method %s not implemented", method->name); } count++; diff --git a/tools/qfcc/source/options.c b/tools/qfcc/source/options.c index 6b2c960e7..656900004 100644 --- a/tools/qfcc/source/options.c +++ b/tools/qfcc/source/options.c @@ -175,6 +175,12 @@ DecodeArgs (int argc, char **argv) options.code.progsversion = PROG_VERSION; options.code.short_circuit = -1; options.warnings.uninited_variable = true; + options.warnings.unused = true; + options.warnings.executable = true; + options.warnings.traditional = true; + options.warnings.precedence = true; + options.warnings.initializer = true; + options.warnings.unimplemented = true; options.save_temps = false; options.verbosity = 0; @@ -256,24 +262,25 @@ DecodeArgs (int argc, char **argv) char *temp = strtok (opts, ","); while (temp) { - if (!(strcasecmp (temp, "cow"))) { - options.code.cow = true; - } else if (!(strcasecmp (temp, "no-cow"))) { - options.code.cow = false; - } else if (!(strcasecmp (temp, "no-cpp"))) { - cpp_name = 0; + qboolean flag = true; + + if (!strncasecmp (temp, "no-", 3)) { + flag = false; + temp += 3; + } + if (!strcasecmp (temp, "cow")) { + options.code.cow = flag; + } else if (!(strcasecmp (temp, "cpp"))) { + cpp_name = flag ? CPP_NAME : 0; } else if (!(strcasecmp (temp, "debug"))) { - options.code.debug = true; - } else if (!(strcasecmp (temp, "no-debug"))) { - options.code.debug = false; + options.code.debug = flag; } else if (!(strcasecmp (temp, "short-circuit"))) { - options.code.short_circuit = true; - } else if (!(strcasecmp (temp, "no-short-circuit"))) { - options.code.short_circuit = false; + options.code.short_circuit = flag; } else if (!(strcasecmp (temp, "v6only"))) { - options.code.progsversion = PROG_ID_VERSION; - } else if (!(strcasecmp (temp, "no-v6only"))) { - options.code.progsversion = PROG_VERSION; + if (flag) + options.code.progsversion = PROG_ID_VERSION; + else + options.code.progsversion = PROG_VERSION; } temp = strtok (NULL, ","); } @@ -291,40 +298,60 @@ DecodeArgs (int argc, char **argv) options.warnings.uninited_variable = true; options.warnings.vararg_integer = true; options.warnings.integer_divide = true; + options.warnings.interface_check = true; + options.warnings.unused = true; + options.warnings.executable = true; + options.warnings.traditional = true; + options.warnings.precedence = true; + options.warnings.initializer = true; + options.warnings.unimplemented = true; } else if (!(strcasecmp (temp, "none"))) { options.warnings.cow = false; options.warnings.undefined_function = false; options.warnings.uninited_variable = false; options.warnings.vararg_integer = false; options.warnings.integer_divide = false; - } else if (!(strcasecmp (temp, "cow"))) { - options.warnings.cow = true; - } else if (!(strcasecmp (temp, "no-cow"))) { - options.warnings.cow = false; - } else if (!(strcasecmp (temp, "error"))) { - options.warnings.promote = true; - } else if (!(strcasecmp (temp, "no-error"))) { - options.warnings.promote = false; - } else if (!(strcasecmp (temp, "undef-function"))) { - options.warnings.undefined_function = true; - } else if (!(strcasecmp (temp, "no-undef-function"))) { - options.warnings.undefined_function = false; - } else if (!(strcasecmp (temp, "uninited-var"))) { - options.warnings.uninited_variable = true; - } else if (!(strcasecmp (temp, "no-uninited-var"))) { - options.warnings.uninited_variable = false; - } else if (!(strcasecmp (temp, "vararg-integer"))) { - options.warnings.vararg_integer = true; - } else if (!(strcasecmp (temp, "no-vararg-integer"))) { - options.warnings.vararg_integer = false; - } else if (!(strcasecmp (temp, "integer-divide"))) { - options.warnings.integer_divide = true; - } else if (!(strcasecmp (temp, "no-integer-divide"))) { - options.warnings.integer_divide = false; - } else if (!(strcasecmp (temp, "interface-check"))) { - options.warnings.interface_check = true; - } else if (!(strcasecmp (temp, "no-interface-check"))) { options.warnings.interface_check = false; + options.warnings.unused = false; + options.warnings.executable = false; + options.warnings.traditional = false; + options.warnings.precedence = false; + options.warnings.initializer = false; + options.warnings.unimplemented = false; + } else { + qboolean flag = true; + + if (!strncasecmp (temp, "no-", 3)) { + flag = false; + temp += 3; + } + if (!strcasecmp (temp, "error")) { + options.warnings.promote = flag; + } else if (!(strcasecmp (temp, "cow"))) { + options.warnings.cow = flag; + } else if (!strcasecmp (temp, "undef-function")) { + options.warnings.undefined_function = flag; + } else if (!strcasecmp (temp, "uninited-var")) { + options.warnings.uninited_variable = flag; + } else if (!strcasecmp (temp, "vararg-integer")) { + options.warnings.vararg_integer = flag; + } else if (!strcasecmp (temp, "integer-divide")) { + options.warnings.integer_divide = flag; + } else if (!strcasecmp (temp, "interface-check")) { + options.warnings.interface_check = flag; + } else if (!strcasecmp (temp, "unused")) { + options.warnings.unused = flag; + } else if (!strcasecmp (temp, "executable")) { + options.warnings.executable = flag; + } else if (!strcasecmp (temp, "traditional")) { + options.warnings.traditional = flag; + } else if (!strcasecmp (temp, "precedence")) { + options.warnings.precedence = flag; + } else if (!strcasecmp (temp, "initializer")) { + options.warnings.initializer = flag; + } else if (!strcasecmp (temp, "unimplemented")) { + options.warnings.unimplemented = flag; + } } temp = strtok (NULL, ","); }