From cb6d92a9005a21d3c7bdb668d1f2dd8ea47e0295 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Thu, 12 Jan 2012 02:00:39 -0300 Subject: [PATCH] compiler: -Wundefined to warn about undefined variables (WIP) Limitations: - complains about iterative calculations like avg = A*avg+(1-A)*VALUE - no way to explicitly initialize variables to zero (making the warning go away) --- src/compiler/idgen | 1 + src/compiler/parser.y | 5 ++++ src/compiler/parser_helper.h | 1 + src/compiler/ptest/ptest.c | 4 +++- src/compiler/symtab.h | 4 +++- src/compiler/test/wundef | 46 ++++++++++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100755 src/compiler/test/wundef diff --git a/src/compiler/idgen b/src/compiler/idgen index 82fdad7..cad5485 100755 --- a/src/compiler/idgen +++ b/src/compiler/idgen @@ -50,6 +50,7 @@ sed 's/#.*//;/^ *$/d' $1 | sort | { .fpvm_sym = { .name = "$1" }, .pfv_idx = $2, .pvv_idx = $3, + .flags = SF_SYSTEM, }, EOF i=`expr $i + 1` diff --git a/src/compiler/parser.y b/src/compiler/parser.y index 3296ec7..d4289ca 100644 --- a/src/compiler/parser.y +++ b/src/compiler/parser.y @@ -33,6 +33,7 @@ int warn_section = 0; + int warn_undefined = 0; struct yyParser; static void yy_parse_failed(struct yyParser *yypParser); @@ -255,6 +256,7 @@ assignments ::= assignments assignment. assignments ::= . assignment ::= ident(I) TOK_ASSIGN expr(N) opt_semi. { + I->sym->flags |= SF_ASSIGNED; state->error = state->comm->assign_default(state->comm, I->sym, N); free(I); if(state->error) { @@ -477,6 +479,9 @@ primary_expr(N) ::= TOK_CONSTANT(C). { } primary_expr(N) ::= ident(I). { + if(warn_undefined && !(I->sym->flags & (SF_SYSTEM | SF_ASSIGNED))) + printf("accessing undefined variable %s\n", + I->sym->fpvm_sym.name); N = node(I->token, I->sym, NULL, NULL, NULL); free(I); } diff --git a/src/compiler/parser_helper.h b/src/compiler/parser_helper.h index 40eb556..8880caf 100644 --- a/src/compiler/parser_helper.h +++ b/src/compiler/parser_helper.h @@ -46,6 +46,7 @@ struct parser_comm { }; extern int warn_section; +extern int warn_undefined; const char *parse(const char *expr, int start_token, struct parser_comm *comm); void parse_free_one(struct ast_node *node); diff --git a/src/compiler/ptest/ptest.c b/src/compiler/ptest/ptest.c index 69ee21d..232a78f 100644 --- a/src/compiler/ptest/ptest.c +++ b/src/compiler/ptest/ptest.c @@ -333,7 +333,7 @@ static void usage(const char *name) " -n runs run compilation repeatedly (default: run only once)\n" " -q quiet operation\n" " -s dump symbol table after parsing (only if -c is not set)\n" -" -Wwarning enable compiler warning (one of: section)\n" +" -Wwarning enable compiler warning (one of: section, undefined)\n" , name); exit(1); } @@ -368,6 +368,8 @@ int main(int argc, char **argv) case 'W': if (!strcmp(optarg, "section")) warn_section = 1; + else if (!strcmp(optarg, "undefined")) + warn_undefined = 1; else usage(*argv); break; diff --git a/src/compiler/symtab.h b/src/compiler/symtab.h index 7781eb3..d623a1c 100644 --- a/src/compiler/symtab.h +++ b/src/compiler/symtab.h @@ -14,7 +14,9 @@ #include -#define SF_FIXED 0 +#define SF_SYSTEM (1 << 0) +#define SF_ASSIGNED (1 << 1) +#define SF_FIXED SF_SYSTEM struct sym { struct fpvm_sym fpvm_sym; diff --git a/src/compiler/test/wundef b/src/compiler/test/wundef new file mode 100755 index 0000000..2f038f3 --- /dev/null +++ b/src/compiler/test/wundef @@ -0,0 +1,46 @@ +#!/bin/sh +. ./Common + +############################################################################### + +ptest "-Wundefined: variable defined per-frame" -q -Wundefined <