all warnings (except for @self and self) are now fully controllable

This commit is contained in:
Bill Currie 2004-02-17 00:39:21 +00:00
parent 825e1f88fd
commit 0360859a0f
7 changed files with 138 additions and 76 deletions

View file

@ -49,6 +49,12 @@ typedef struct {
qboolean vararg_integer; // Warn on passing an integer to vararg func qboolean vararg_integer; // Warn on passing an integer to vararg func
qboolean integer_divide; // Warn on integer constant division qboolean integer_divide; // Warn on integer constant division
qboolean interface_check; // Warn for methods not in interface 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; } warn_options_t;
typedef struct { typedef struct {

View file

@ -467,8 +467,10 @@ class_message_response (class_t *class, int class_msg, expr_t *sel)
m = find_method (selector->name); m = find_method (selector->name);
if (m) if (m)
return m; return m;
warning (sel, "could not find method for %c%s", class_msg ? '+' : '-', //FIXME right option?
selector->name); if (options.warnings.interface_check)
warning (sel, "could not find method for %c%s",
class_msg ? '+' : '-', selector->name);
return 0; return 0;
} else { } else {
while (c) { while (c) {
@ -486,6 +488,8 @@ class_message_response (class_t *class, int class_msg, expr_t *sel)
} }
c = c->super_class; c = c->super_class;
} }
//FIXME right option?
if (options.warnings.interface_check)
warning (sel, "%s does not respond to %c%s", class->name, warning (sel, "%s does not respond to %c%s", class->name,
class_msg ? '+' : '-', selector->name); class_msg ? '+' : '-', selector->name);
} }
@ -534,8 +538,11 @@ class_add_ivars (class_t *class, struct_t *ivars)
void void
class_check_ivars (class_t *class, struct_t *ivars) class_check_ivars (class_t *class, struct_t *ivars)
{ {
if (!struct_compare_fields (class->ivars, ivars)) if (!struct_compare_fields (class->ivars, ivars)) {
//FIXME right option?
if (options.warnings.interface_check)
warning (0, "instance variable missmatch for %s", class->name); warning (0, "instance variable missmatch for %s", class->name);
}
class->ivars = ivars; class->ivars = ivars;
} }

View file

@ -51,6 +51,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "def.h" #include "def.h"
#include "expr.h" #include "expr.h"
#include "immediate.h" #include "immediate.h"
#include "options.h"
#include "reloc.h" #include "reloc.h"
#include "strpool.h" #include "strpool.h"
#include "struct.h" #include "struct.h"
@ -486,6 +487,7 @@ flush_scope (scope_t *scope, int force_used)
e.line = def->line; e.line = def->line;
e.file = def->file; e.file = def->file;
if (options.warnings.unused)
warning (&e, "unused variable `%s'", def->name); warning (&e, "unused variable `%s'", def->name);
} }
if (!def->removed) { if (!def->removed) {

View file

@ -271,9 +271,11 @@ emit_assign_expr (int oper, expr_t *e)
warning (e1, "assignment to constant %s (Moooooooo!)", warning (e1, "assignment to constant %s (Moooooooo!)",
def_a->name); def_a->name);
} else { } else {
if (options.traditional) if (options.traditional) {
//FIXME correct option?
if (options.warnings.cow)
warning (e1, "assignment to constant %s", def_a->name); warning (e1, "assignment to constant %s", def_a->name);
else } else
error (e1, "assignment to constant %s", def_a->name); error (e1, "assignment to constant %s", def_a->name);
} }
} }
@ -838,6 +840,7 @@ emit_expr (expr_t *e)
emit_statement (e, op_jumpb, def_a, def_b, 0); emit_statement (e, op_jumpb, def_a, def_b, 0);
break; break;
default: default:
if (options.warnings.executable)
warning (e, "Non-executable statement; " warning (e, "Non-executable statement; "
"executing programmer instead."); "executing programmer instead.");
break; break;
@ -855,6 +858,7 @@ emit_expr (expr_t *e)
emit_branch (e, op_goto, 0, e->e.expr.e1); emit_branch (e, op_goto, 0, e->e.expr.e1);
break; break;
default: default:
if (options.warnings.executable)
warning (e, "Non-executable statement; " warning (e, "Non-executable statement; "
"executing programmer instead."); "executing programmer instead.");
emit_expr (e->e.expr.e1); emit_expr (e->e.expr.e1);
@ -876,6 +880,7 @@ emit_expr (expr_t *e)
case ex_short: case ex_short:
case ex_name: case ex_name:
case ex_nil: case ex_nil:
if (options.warnings.executable)
warning (e, "Non-executable statement; " warning (e, "Non-executable statement; "
"executing programmer instead."); "executing programmer instead.");
break; break;

View file

@ -1011,6 +1011,7 @@ test_expr (expr_t *e, int test)
abort (); abort ();
case ev_void: case ev_void:
if (options.traditional) { if (options.traditional) {
if (options.warnings.traditional)
warning (e, "void has no value"); warning (e, "void has no value");
return e; return e;
} }
@ -1120,9 +1121,11 @@ convert_bool (expr_t *e, int block)
expr_t *b; expr_t *b;
if (e->type == ex_expr && (e->e.expr.op == '=' || e->e.expr.op == PAS) if (e->type == ex_expr && (e->e.expr.op == '=' || e->e.expr.op == PAS)
&& !e->paren) && !e->paren) {
warning (e, if (options.warnings.precedence)
"suggest parentheses around assignment used as truth value"); warning (e, "suggest parentheses around assignment "
"used as truth value");
}
if (e->type == ex_uexpr && e->e.expr.op == '!') { if (e->type == ex_uexpr && e->e.expr.op == '!') {
e = convert_bool (e->e.expr.e1, 0); 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)); return unary_expr ('!', binary_expr (op, e1->e.expr.e1, e2));
} }
} else if (op == '&' || op == '|') { } else if (op == '&' || op == '|') {
warning (e1, "ambiguous logic. Suggest explicit parentheses with " if (options.warnings.precedence)
"expressions involving ! and %s", get_op_string (op)); warning (e1, "ambiguous logic. Suggest explicit parentheses "
"with expressions involving ! and %s",
get_op_string (op));
} }
} }
if (options.traditional) { if (options.traditional) {
@ -1344,6 +1349,7 @@ check_precedence (int op, expr_t *e1, expr_t *e2)
if (e2->type == ex_expr && !e2->paren) { if (e2->type == ex_expr && !e2->paren) {
if ((op == '&' || op == '|' || op == '^') if ((op == '&' || op == '|' || op == '^')
&& is_compare (e2->e.expr.op)) { && is_compare (e2->e.expr.op)) {
if (options.warnings.precedence)
warning (e2, "suggest parentheses around comparison in " warning (e2, "suggest parentheses around comparison in "
"operand of %c", op); "operand of %c", op);
} }
@ -1827,6 +1833,7 @@ build_function_call (expr_t *fexpr, type_t *ftype, expr_t *params)
if (-arg_count > ftype->num_parms + 1) { if (-arg_count > ftype->num_parms + 1) {
if (!options.traditional) if (!options.traditional)
return error (fexpr, "too few arguments"); return error (fexpr, "too few arguments");
if (options.warnings.traditional)
warning (fexpr, "too few arguments"); warning (fexpr, "too few arguments");
} }
parm_count = -ftype->num_parms - 1; parm_count = -ftype->num_parms - 1;
@ -1836,6 +1843,7 @@ build_function_call (expr_t *fexpr, type_t *ftype, expr_t *params)
} else if (arg_count < ftype->num_parms) { } else if (arg_count < ftype->num_parms) {
if (!options.traditional) if (!options.traditional)
return error (fexpr, "too few arguments"); return error (fexpr, "too few arguments");
if (options.warnings.traditional)
warning (fexpr, "too few arguments"); warning (fexpr, "too few arguments");
} }
parm_count = ftype->num_parms; parm_count = ftype->num_parms;
@ -1960,7 +1968,9 @@ return_expr (function_t *f, expr_t *e)
if (!e) { if (!e) {
if (f->def->type->aux_type != &type_void) { if (f->def->type->aux_type != &type_void) {
if (options.traditional) { 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 (); e = new_nil_expr ();
} else { } else {
e = error (e, "return from non-void function without a value"); e = error (e, "return from non-void function without a value");
@ -1977,6 +1987,7 @@ return_expr (function_t *f, expr_t *e)
if (f->def->type->aux_type == &type_void) { if (f->def->type->aux_type == &type_void) {
if (!options.traditional) if (!options.traditional)
return error (e, "returning a value for a void function"); return error (e, "returning a value for a void function");
if (options.warnings.traditional)
warning (e, "returning a value for a void function"); warning (e, "returning a value for a void function");
} }
if (e->type == ex_bool) if (e->type == ex_bool)
@ -1993,6 +2004,7 @@ return_expr (function_t *f, expr_t *e)
} else { } else {
if (!options.traditional) if (!options.traditional)
return error (e, "void value not ignored as it ought to be"); return error (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"); warning (e, "void value not ignored as it ought to be");
//FIXME does anything need to be done here? //FIXME does anything need to be done here?
} }
@ -2001,6 +2013,7 @@ return_expr (function_t *f, expr_t *e)
if (!options.traditional) if (!options.traditional)
return error (e, "type mismatch for return value of %s", return error (e, "type mismatch for return value of %s",
f->def->name); f->def->name);
if (options.warnings.traditional)
warning (e, "type mismatch for return value of %s", warning (e, "type mismatch for return value of %s",
f->def->name); f->def->name);
} else { } else {
@ -2295,6 +2308,7 @@ assign_expr (expr_t *e1, expr_t *e2)
if (!type_assignable (t1, t2)) { if (!type_assignable (t1, t2)) {
if (!options.traditional || t1->type != ev_func || t2->type != ev_func) if (!options.traditional || t1->type != ev_func || t2->type != ev_func)
return type_mismatch (e1, e2, op); return type_mismatch (e1, e2, op);
if (options.warnings.traditional)
warning (e1, "assignment between disparate function types"); warning (e1, "assignment between disparate function types");
} }
type = t1; type = t1;
@ -2445,6 +2459,7 @@ init_elements (def_t *def, expr_t *eles)
return; return;
} }
if (count > num_params) { if (count > num_params) {
if (options.warnings.initializer)
warning (eles, "excessive elements in initializer"); warning (eles, "excessive elements in initializer");
count = num_params; count = num_params;
} }

View file

@ -383,7 +383,7 @@ emit_methods (methodlist_t *_methods, const char *name, int instance)
return 0; return 0;
for (count = 0, method = _methods->head; method; method = method->next) for (count = 0, method = _methods->head; method; method = method->next)
if (!method->instance == !instance) { if (!method->instance == !instance) {
if (!method->def) { if (!method->def && options.warnings.unimplemented) {
warning (0, "method %s not implemented", method->name); warning (0, "method %s not implemented", method->name);
} }
count++; count++;

View file

@ -175,6 +175,12 @@ DecodeArgs (int argc, char **argv)
options.code.progsversion = PROG_VERSION; options.code.progsversion = PROG_VERSION;
options.code.short_circuit = -1; options.code.short_circuit = -1;
options.warnings.uninited_variable = true; 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.save_temps = false;
options.verbosity = 0; options.verbosity = 0;
@ -256,23 +262,24 @@ DecodeArgs (int argc, char **argv)
char *temp = strtok (opts, ","); char *temp = strtok (opts, ",");
while (temp) { while (temp) {
if (!(strcasecmp (temp, "cow"))) { qboolean flag = true;
options.code.cow = true;
} else if (!(strcasecmp (temp, "no-cow"))) { if (!strncasecmp (temp, "no-", 3)) {
options.code.cow = false; flag = false;
} else if (!(strcasecmp (temp, "no-cpp"))) { temp += 3;
cpp_name = 0; }
if (!strcasecmp (temp, "cow")) {
options.code.cow = flag;
} else if (!(strcasecmp (temp, "cpp"))) {
cpp_name = flag ? CPP_NAME : 0;
} else if (!(strcasecmp (temp, "debug"))) { } else if (!(strcasecmp (temp, "debug"))) {
options.code.debug = true; options.code.debug = flag;
} else if (!(strcasecmp (temp, "no-debug"))) {
options.code.debug = false;
} else if (!(strcasecmp (temp, "short-circuit"))) { } else if (!(strcasecmp (temp, "short-circuit"))) {
options.code.short_circuit = true; options.code.short_circuit = flag;
} else if (!(strcasecmp (temp, "no-short-circuit"))) {
options.code.short_circuit = false;
} else if (!(strcasecmp (temp, "v6only"))) { } else if (!(strcasecmp (temp, "v6only"))) {
if (flag)
options.code.progsversion = PROG_ID_VERSION; options.code.progsversion = PROG_ID_VERSION;
} else if (!(strcasecmp (temp, "no-v6only"))) { else
options.code.progsversion = PROG_VERSION; options.code.progsversion = PROG_VERSION;
} }
temp = strtok (NULL, ","); temp = strtok (NULL, ",");
@ -291,40 +298,60 @@ DecodeArgs (int argc, char **argv)
options.warnings.uninited_variable = true; options.warnings.uninited_variable = true;
options.warnings.vararg_integer = true; options.warnings.vararg_integer = true;
options.warnings.integer_divide = 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"))) { } else if (!(strcasecmp (temp, "none"))) {
options.warnings.cow = false; options.warnings.cow = false;
options.warnings.undefined_function = false; options.warnings.undefined_function = false;
options.warnings.uninited_variable = false; options.warnings.uninited_variable = false;
options.warnings.vararg_integer = false; options.warnings.vararg_integer = false;
options.warnings.integer_divide = 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.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, ","); temp = strtok (NULL, ",");
} }