From 47b5e36e60da3c1765d8a90ca25102dfd259afff Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 16 Nov 2019 11:59:21 -0500 Subject: [PATCH] Add -Wpedantic for compliance testing. --- Changes | 4 +++- bin/verilator | 30 ++++++++++++++++--------- src/V3FileLine.cpp | 22 +++++++++++++----- src/V3Options.cpp | 2 ++ src/V3Options.h | 2 ++ src/verilog.l | 1 + src/verilog.y | 1 + test_regress/t/t_flag_wpedantic_bad.out | 4 ++++ test_regress/t/t_flag_wpedantic_bad.pl | 19 ++++++++++++++++ test_regress/t/t_flag_wpedantic_bad.v | 8 +++++++ test_regress/t/t_pp_line_bad.out | 15 +++++++++++++ test_regress/t/t_pp_line_bad.pl | 19 ++++++++++++++++ test_regress/t/t_pp_line_bad.v | 10 +++++++++ 13 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 test_regress/t/t_flag_wpedantic_bad.out create mode 100755 test_regress/t/t_flag_wpedantic_bad.pl create mode 100644 test_regress/t/t_flag_wpedantic_bad.v create mode 100644 test_regress/t/t_pp_line_bad.out create mode 100755 test_regress/t/t_pp_line_bad.pl create mode 100644 test_regress/t/t_pp_line_bad.v diff --git a/Changes b/Changes index d8b40a07d..b737e011f 100644 --- a/Changes +++ b/Changes @@ -4,10 +4,12 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 4.023 devel -**** Fix for loop missing initializer, bug1605. [Andrew Holme] +**** Add -Wpedantic for compliance testing. **** Add error on redefining preprocessor directives. [Piotr Binkowski] +**** Fix for loop missing initializer, bug1605. [Andrew Holme] + * Verilator 4.022 2019-11-10 diff --git a/bin/verilator b/bin/verilator index a14038e46..2cd9fc102 100755 --- a/bin/verilator +++ b/bin/verilator @@ -398,9 +398,10 @@ detailed descriptions in L for more information. -Werror- Convert warnings to errors -Wfuture- Disable unknown message warnings -Wno- Disable warning + -Wno-fatal Disable fatal exit on warnings -Wno-lint Disable all lint warnings -Wno-style Disable all style warnings - -Wno-fatal Disable fatal exit on warnings + -Wpedantic Warn on compliance-test issues --x-assign Assign non-initial Xs to this value --x-initial Assign initial Xs to this value --x-initial-edge Enable initial X->0 and X->1 edge triggers @@ -511,10 +512,10 @@ calls. =item --bbox-sys Black box any unknown $system task or function calls. System tasks will be -simply NOPed, and system functions will be replaced by unsized zero. -Arguments to such functions will be parsed, but not otherwise checked. -This prevents errors when linting in the presence of company specific PLI -calls. +simply become no-operations, and system functions will be replaced by +unsized zero. Arguments to such functions will be parsed, but not +otherwise checked. This prevents errors when linting in the presence of +company specific PLI calls. =item --bbox-unsup @@ -1525,6 +1526,14 @@ Disable the specified warning message, or in some cases where noted here disable an error. This will override any lint_on directives in the source, i.e. the warning will still not be printed. +=item -Wno-fatal + +When warnings are detected, print them, but do not exit the simulator. + +Having warning messages in builds is sloppy. It is strongly recommended +you cleanup your code, use inline lint_off, or use -Wno-... flags rather +than using this option. + =item -Wno-lint Disable all lint related warning messages, and all style warnings. This is @@ -1545,13 +1554,12 @@ already disabled). This is equivalent to "-Wno-DECLFILENAME -Wno-DEFPARAM -Wno-IMPORTSTAR -Wno-INCABSPATH -Wno-PINCONNECTEMPTY -Wno-PINNOCONNECT -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNUSED -Wno-VARHIDDEN". -=item -Wno-fatal +=item -Wpedantic -When warnings are detected, print them, but do not exit the simulator. - -Having warning messages in builds is sloppy. It is strongly recommended -you cleanup your code, use inline lint_off, or use -Wno-... flags rather -than using this option. +Warn on any construct demanded by IEEE, and disable all Verilator +extensions that may interfere with IEEE compliance to the standard defined +with --language (etc). Similar to GCC's -Wpedantic. Rarely used, and +intended only for strict compliance tests. =item -Wwarn-I diff --git a/src/V3FileLine.cpp b/src/V3FileLine.cpp index e00d051bb..88c931ba0 100644 --- a/src/V3FileLine.cpp +++ b/src/V3FileLine.cpp @@ -175,12 +175,15 @@ void FileLine::lineDirective(const char* textp, int& enterExitRef) { while (*textp && (isspace(*textp) || *textp=='"')) textp++; // Grab linenumber + bool fail = false; const char* ln = textp; while (*textp && !isspace(*textp)) textp++; if (isdigit(*ln)) { lineno(atoi(ln)); - } - while (*textp && (isspace(*textp) || *textp=='"')) textp++; + } else fail = true; + while (*textp && (isspace(*textp))) textp++; + if (*textp != '"') fail = true; + while (*textp && (isspace(*textp) || *textp == '"')) textp++; // Grab filename const char* fn = textp; @@ -189,12 +192,21 @@ void FileLine::lineDirective(const char* textp, int& enterExitRef) { string strfn = fn; strfn = strfn.substr(0, textp-fn); filename(strfn); - } + } else fail = true; // Grab level while (*textp && (isspace(*textp) || *textp=='"')) textp++; - if (isdigit(*textp)) enterExitRef = atoi(textp); - else enterExitRef = 0; + if (isdigit(*textp)) { + enterExitRef = atoi(textp); + if (enterExitRef >= 3) fail = true; + } else { + enterExitRef = 0; + fail = true; + } + + if (fail && v3Global.opt.pedantic()) { + v3error("`line was not properly formed with '`line number \"filename\" level'\n"); + } //printf ("PPLINE %d '%s'\n", s_lineno, s_filename.c_str()); } diff --git a/src/V3Options.cpp b/src/V3Options.cpp index e139a4bcb..160e10235 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -796,6 +796,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char else if ( onoff (sw, "-trace-underscore", flag/*ref*/)) { m_traceUnderscore = flag; } else if ( onoff (sw, "-underline-zero", flag/*ref*/)) { m_underlineZero = flag; } // Undocumented, old Verilator-2 else if ( onoff (sw, "-vpi", flag/*ref*/)) { m_vpi = flag; } + else if ( onoff (sw, "-Wpedantic", flag/*ref*/)) { m_pedantic = flag; } else if ( onoff (sw, "-x-initial-edge", flag/*ref*/)) { m_xInitialEdge = flag; } else if ( onoff (sw, "-xml-only", flag/*ref*/)) { m_xmlOnly = flag; } // Undocumented, still experimental // Optimization @@ -1456,6 +1457,7 @@ V3Options::V3Options() { m_makePhony = false; m_orderClockDly = true; m_outFormatOk = false; + m_pedantic = false; m_pinsBv = 65; m_pinsScUint = false; m_pinsScBigUint = false; diff --git a/src/V3Options.h b/src/V3Options.h index 013a183bd..b8e8be77c 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -163,6 +163,7 @@ class V3Options { bool m_gmake; // main switch: --make gmake bool m_orderClockDly;// main switch: --order-clock-delay bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified + bool m_pedantic; // main switch: --Wpedantic bool m_pinsScUint; // main switch: --pins-sc-uint bool m_pinsScBigUint;// main switch: --pins-sc-biguint bool m_pinsUint8; // main switch: --pins-uint8 @@ -348,6 +349,7 @@ class V3Options { bool orderClockDly() const { return m_orderClockDly; } bool outFormatOk() const { return m_outFormatOk; } bool keepTempFiles() const { return (V3Error::debugDefault()!=0); } + bool pedantic() const { return m_pedantic; } bool pinsScUint() const { return m_pinsScUint; } bool pinsScBigUint() const { return m_pinsScBigUint; } bool pinsUint8() const { return m_pinsUint8; } diff --git a/src/verilog.l b/src/verilog.l index 069553450..da62a98d4 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -1023,6 +1023,7 @@ void V3ParseImp::lexToken() { } else if (token == yGLOBAL__LEX) { if (nexttok == yCLOCKING) token = yGLOBAL__CLOCKING; + else if (v3Global.opt.pedantic()) token = yGLOBAL__ETC; // Avoid 2009 "global" conflicting with old code when we can else { token = yaID__LEX; yylval.strp = PARSEP->newString("global"); } } diff --git a/src/verilog.y b/src/verilog.y index 122db9c21..88b497cfc 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -383,6 +383,7 @@ class AstSenTree; %token yGENERATE "generate" %token yGENVAR "genvar" %token yGLOBAL__CLOCKING "global-then-clocking" +%token yGLOBAL__ETC "global" %token yGLOBAL__LEX "global-in-lex" %token yIF "if" %token yIFF "iff" diff --git a/test_regress/t/t_flag_wpedantic_bad.out b/test_regress/t/t_flag_wpedantic_bad.out new file mode 100644 index 000000000..e59968538 --- /dev/null +++ b/test_regress/t/t_flag_wpedantic_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_flag_wpedantic_bad.v:7: syntax error, unexpected global, expecting IDENTIFIER or do or final + reg global; + ^ +%Error: Exiting due to diff --git a/test_regress/t/t_flag_wpedantic_bad.pl b/test_regress/t/t_flag_wpedantic_bad.pl new file mode 100755 index 000000000..18439afa9 --- /dev/null +++ b/test_regress/t/t_flag_wpedantic_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. + +scenarios(vlt => 1); + +lint( + verilator_flags2 => ["-Wpedantic"], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_wpedantic_bad.v b/test_regress/t/t_flag_wpedantic_bad.v new file mode 100644 index 000000000..c21e4805b --- /dev/null +++ b/test_regress/t/t_flag_wpedantic_bad.v @@ -0,0 +1,8 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +module t (/*AUTOARG*/); + reg global; +endmodule diff --git a/test_regress/t/t_pp_line_bad.out b/test_regress/t/t_pp_line_bad.out new file mode 100644 index 000000000..609b3befb --- /dev/null +++ b/test_regress/t/t_pp_line_bad.out @@ -0,0 +1,15 @@ +%Error: t/t_pp_line_bad.v:100: `line was not properly formed with '`line number "filename" level' +`line 100 +^ +%Error: somefile:100: `line was not properly formed with '`line number "filename" level' +`line 100 +^ +%Error: somefile:100: `line was not properly formed with '`line number "filename" level' +%Error-internal-no-contents +^ +%Error: t/t_pp_line_bad.v:6: Define or directive not defined: '`line' +`line +^~~~~ +%Error: somefile:100: `line was not properly formed with '`line number "filename" level' + t/t_pp_line_bad.v:101: ... note: In file included from t_pp_line_bad.v +%Error: Exiting due to diff --git a/test_regress/t/t_pp_line_bad.pl b/test_regress/t/t_pp_line_bad.pl new file mode 100755 index 000000000..18439afa9 --- /dev/null +++ b/test_regress/t/t_pp_line_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. + +scenarios(vlt => 1); + +lint( + verilator_flags2 => ["-Wpedantic"], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_pp_line_bad.v b/test_regress/t/t_pp_line_bad.v new file mode 100644 index 000000000..ee4975ba0 --- /dev/null +++ b/test_regress/t/t_pp_line_bad.v @@ -0,0 +1,10 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +`line +`line 100 +`line 100 somefile 1 +`line 100 "somefile" +`line 100 "somefile" 3