mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-21 11:11:37 +00:00
all warnings (except for @self and self) are now fully controllable
This commit is contained in:
parent
825e1f88fd
commit
0360859a0f
7 changed files with 138 additions and 76 deletions
|
@ -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 {
|
||||
|
|
|
@ -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,6 +488,8 @@ class_message_response (class_t *class, int class_msg, expr_t *sel)
|
|||
}
|
||||
c = c->super_class;
|
||||
}
|
||||
//FIXME right option?
|
||||
if (options.warnings.interface_check)
|
||||
warning (sel, "%s does not respond to %c%s", class->name,
|
||||
class_msg ? '+' : '-', selector->name);
|
||||
}
|
||||
|
@ -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))
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,6 +487,7 @@ flush_scope (scope_t *scope, int force_used)
|
|||
|
||||
e.line = def->line;
|
||||
e.file = def->file;
|
||||
if (options.warnings.unused)
|
||||
warning (&e, "unused variable `%s'", def->name);
|
||||
}
|
||||
if (!def->removed) {
|
||||
|
|
|
@ -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)
|
||||
if (options.traditional) {
|
||||
//FIXME correct option?
|
||||
if (options.warnings.cow)
|
||||
warning (e1, "assignment to constant %s", def_a->name);
|
||||
else
|
||||
} else
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
if (options.warnings.executable)
|
||||
warning (e, "Non-executable statement; "
|
||||
"executing programmer instead.");
|
||||
break;
|
||||
|
@ -855,6 +858,7 @@ emit_expr (expr_t *e)
|
|||
emit_branch (e, op_goto, 0, e->e.expr.e1);
|
||||
break;
|
||||
default:
|
||||
if (options.warnings.executable)
|
||||
warning (e, "Non-executable statement; "
|
||||
"executing programmer instead.");
|
||||
emit_expr (e->e.expr.e1);
|
||||
|
@ -876,6 +880,7 @@ emit_expr (expr_t *e)
|
|||
case ex_short:
|
||||
case ex_name:
|
||||
case ex_nil:
|
||||
if (options.warnings.executable)
|
||||
warning (e, "Non-executable statement; "
|
||||
"executing programmer instead.");
|
||||
break;
|
||||
|
|
|
@ -1011,6 +1011,7 @@ test_expr (expr_t *e, int test)
|
|||
abort ();
|
||||
case ev_void:
|
||||
if (options.traditional) {
|
||||
if (options.warnings.traditional)
|
||||
warning (e, "void has no value");
|
||||
return e;
|
||||
}
|
||||
|
@ -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,6 +1349,7 @@ 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)) {
|
||||
if (options.warnings.precedence)
|
||||
warning (e2, "suggest parentheses around comparison in "
|
||||
"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 (!options.traditional)
|
||||
return error (fexpr, "too few arguments");
|
||||
if (options.warnings.traditional)
|
||||
warning (fexpr, "too few arguments");
|
||||
}
|
||||
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) {
|
||||
if (!options.traditional)
|
||||
return error (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,6 +1987,7 @@ 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");
|
||||
if (options.warnings.traditional)
|
||||
warning (e, "returning a value for a void function");
|
||||
}
|
||||
if (e->type == ex_bool)
|
||||
|
@ -1993,6 +2004,7 @@ return_expr (function_t *f, expr_t *e)
|
|||
} else {
|
||||
if (!options.traditional)
|
||||
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");
|
||||
//FIXME does anything need to be done here?
|
||||
}
|
||||
|
@ -2001,6 +2013,7 @@ return_expr (function_t *f, expr_t *e)
|
|||
if (!options.traditional)
|
||||
return error (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 {
|
||||
|
@ -2295,6 +2308,7 @@ 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);
|
||||
if (options.warnings.traditional)
|
||||
warning (e1, "assignment between disparate function types");
|
||||
}
|
||||
type = t1;
|
||||
|
@ -2445,6 +2459,7 @@ init_elements (def_t *def, expr_t *eles)
|
|||
return;
|
||||
}
|
||||
if (count > num_params) {
|
||||
if (options.warnings.initializer)
|
||||
warning (eles, "excessive elements in initializer");
|
||||
count = num_params;
|
||||
}
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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,23 +262,24 @@ 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"))) {
|
||||
if (flag)
|
||||
options.code.progsversion = PROG_ID_VERSION;
|
||||
} else if (!(strcasecmp (temp, "no-v6only"))) {
|
||||
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, ",");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue