Merge branch 'nekromant-master'

Adds warning about macro redefinition (GitHub pull request #168).
This commit is contained in:
Martin Whitaker 2017-11-06 21:07:47 +00:00
commit 1f85cd4154
5 changed files with 58 additions and 11 deletions

View File

@ -316,8 +316,8 @@ after a \fB\-Wall\fP argument to suppress isolated warning types.
.TP 8 .TP 8
.B all .B all
This enables the anachronisms, implicit, portbind, select\-range, This enables the anachronisms, implicit, macro-redefinition, portbind,
timescale, and sensitivity\-entire\-array warning categories. select\-range, timescale, and sensitivity\-entire\-array warning categories.
.TP 8 .TP 8
.B anachronisms .B anachronisms
@ -330,6 +330,10 @@ This enables warnings for creation of implicit declarations. For
example, if a scalar wire X is used but not declared in the Verilog example, if a scalar wire X is used but not declared in the Verilog
source, this will print a warning at its first use. source, this will print a warning at its first use.
.TP 8
.B macro-redefinition
This enables preprocessor warnings when a macro is being redefined.
.TP 8 .TP 8
.B portbind .B portbind
This enables warnings for ports of module instantiations that are not This enables warnings for ports of module instantiations that are not

View File

@ -138,7 +138,7 @@ int gen_std_include = 1;
of the include list. */ of the include list. */
int gen_relative_include = 0; int gen_relative_include = 0;
char warning_flags[16] = "n"; char warning_flags[17] = "n";
int separate_compilation_flag = 0; int separate_compilation_flag = 0;
@ -346,10 +346,14 @@ static int t_version_only(void)
static void build_preprocess_command(int e_flag) static void build_preprocess_command(int e_flag)
{ {
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F\"%s\" -f\"%s\" -p\"%s\"%s", snprintf(tmp, sizeof tmp, "%s%civlpp %s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s",
ivlpp_dir, sep, verbose_flag?" -v":"", ivlpp_dir, sep,
e_flag?"":" -L", defines_path, source_path, verbose_flag ? " -v" : "",
compiled_defines_path, e_flag?"":" | "); e_flag ? "" : " -L",
strchr(warning_flags, 'r') ? " -Wredef " : "",
defines_path, source_path,
compiled_defines_path,
e_flag ? "" : " | ");
} }
static int t_preprocess_only(void) static int t_preprocess_only(void)
@ -520,6 +524,10 @@ static void process_warning_switch(const char*name)
process_warning_switch("select-range"); process_warning_switch("select-range");
process_warning_switch("timescale"); process_warning_switch("timescale");
process_warning_switch("sensitivity-entire-array"); process_warning_switch("sensitivity-entire-array");
process_warning_switch("macro-redefinition");
} else if (strcmp(name,"macro-redefinition") == 0) {
if (! strchr(warning_flags, 'r'))
strcat(warning_flags, "r");
} else if (strcmp(name,"anachronisms") == 0) { } else if (strcmp(name,"anachronisms") == 0) {
if (! strchr(warning_flags, 'n')) if (! strchr(warning_flags, 'n'))
strcat(warning_flags, "n"); strcat(warning_flags, "n");
@ -558,6 +566,12 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1]; cp[0] = cp[1];
cp += 1; cp += 1;
} }
} else if (strcmp(name,"no-macro-redefinition") == 0) {
char*cp = strchr(warning_flags, 'r');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-floating-nets") == 0) { } else if (strcmp(name,"no-floating-nets") == 0) {
char*cp = strchr(warning_flags, 'f'); char*cp = strchr(warning_flags, 'f');
if (cp) while (*cp) { if (cp) while (*cp) {
@ -1306,8 +1320,11 @@ int main(int argc, char **argv)
/* Write the preprocessor command needed to preprocess a /* Write the preprocessor command needed to preprocess a
single file. This may be used to preprocess library single file. This may be used to preprocess library
files. */ files. */
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F\"%s\" -P\"%s\"\n", fprintf(iconfig_file, "ivlpp:%s%civlpp %s -L -F\"%s\" -P\"%s\"\n",
ivlpp_dir, sep, defines_path, compiled_defines_path); ivlpp_dir, sep,
strchr(warning_flags, 'r') ? "-Wredef" : "",
defines_path, compiled_defines_path
);
/* Done writing to the iconfig file. Close it now. */ /* Done writing to the iconfig file. Close it now. */
fclose(iconfig_file); fclose(iconfig_file);

View File

@ -53,6 +53,8 @@ extern char dep_mode;
extern int verbose_flag; extern int verbose_flag;
extern int warn_redef;
/* This is the entry to the lexer. */ /* This is the entry to the lexer. */
extern int yylex(void); extern int yylex(void);

View File

@ -858,6 +858,20 @@ void define_macro(const char* name, const char* value, int keyword, int argc)
{ {
int idx; int idx;
struct define_t* def; struct define_t* def;
struct define_t* prev;
/* Verilog has a very nasty system of macros jumping from
* file to file, resulting in a global macro scope. Here
* we optionally warn about any redefinitions.
*/
if (warn_redef) {
prev = def_lookup(name);
if (prev) {
emit_pathline(istack);
fprintf(stderr, "warning: redefinition of macro %s from value '%s' to '%s'\n",
name, prev->value, value);
}
}
def = malloc(sizeof(struct define_t)); def = malloc(sizeof(struct define_t));
def->name = strdup(name); def->name = strdup(name);

View File

@ -98,6 +98,9 @@ int line_direct_flag = 0;
unsigned error_count = 0; unsigned error_count = 0;
FILE *depend_file = NULL; FILE *depend_file = NULL;
/* Should we warn about macro redefinitions? */
int warn_redef = 0;
static int flist_read_flags(const char*path) static int flist_read_flags(const char*path)
{ {
char line_buf[2048]; char line_buf[2048];
@ -282,7 +285,7 @@ int main(int argc, char*argv[])
include_dir[0] = 0; /* 0 is reserved for the current files path. */ include_dir[0] = 0; /* 0 is reserved for the current files path. */
include_dir[1] = strdup("."); include_dir[1] = strdup(".");
while ((opt=getopt(argc, argv, "F:f:K:Lo:p:P:vV")) != EOF) switch (opt) { while ((opt=getopt(argc, argv, "F:f:K:Lo:p:P:vVW:")) != EOF) switch (opt) {
case 'F': case 'F':
flist_read_flags(optarg); flist_read_flags(optarg);
@ -336,6 +339,12 @@ int main(int argc, char*argv[])
break; break;
} }
case 'W': {
if (strcmp(optarg, "redef")==0)
warn_redef = 1;
break;
}
case 'v': case 'v':
fprintf(stderr, "Icarus Verilog Preprocessor version " fprintf(stderr, "Icarus Verilog Preprocessor version "
VERSION " (" VERSION_TAG ")\n\n"); VERSION " (" VERSION_TAG ")\n\n");
@ -366,7 +375,8 @@ int main(int argc, char*argv[])
" -p<fil> - Write precompiled defines to <fil>\n" " -p<fil> - Write precompiled defines to <fil>\n"
" -P<fil> - Read precompiled defines from <fil>\n" " -P<fil> - Read precompiled defines from <fil>\n"
" -v - Verbose\n" " -v - Verbose\n"
" -V - Print version information and quit\n", " -V - Print version information and quit\n"
" -W<cat> - Enable extra ivlpp warning category (e.g. redef)\n",
argv[0]); argv[0]);
return flag_errors; return flag_errors;
} }