Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Add gcc warnings checker #144

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/mlx/warnings/regex_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
COVERITY_WARNING_REGEX = r"(?:((?:[/.]|[A-Za-z]).+?):(-?\d+):) (CID) \d+ \(#(?P<curr>\d+) of (?P<max>\d+)\): (?P<checker>.+\)): (?P<classification>\w+), *(.+)\n?"
coverity_pattern = re.compile(COVERITY_WARNING_REGEX)

GCC_WARNING_REGEX = r"(?:(?P<path1>(?:[/.]|[A-Za-z]).+?):(?P<line1>-?\d+):(?P<col1>-?\d+):\s*(?P<severity1>[Ww]arning|[Ee]rror)|<.+>:(?P<line2>-?\d+)(?::\s*(?P<severity2>[Ww]arning|[Ee]rror))?): (?P<description1>.+)\n?"
gcc_pattern = re.compile(GCC_WARNING_REGEX)


class RegexChecker(WarningsChecker):
name = 'regex'
Expand Down Expand Up @@ -137,3 +140,8 @@ def include_sphinx_deprecation(self):
class XMLRunnerChecker(RegexChecker):
name = 'xmlrunner'
pattern = xmlrunner_pattern


class GccChecker(RegexChecker):
name = 'gcc'
pattern = gcc_pattern
9 changes: 6 additions & 3 deletions src/mlx/warnings/warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from .exceptions import WarningsConfigError
from .junit_checker import JUnitChecker
from .regex_checker import CoverityChecker, DoxyChecker, SphinxChecker, XMLRunnerChecker
from .regex_checker import CoverityChecker, DoxyChecker, SphinxChecker, XMLRunnerChecker, GccChecker
from .robot_checker import RobotChecker
from .polyspace_checker import PolyspaceChecker

Expand All @@ -36,7 +36,7 @@ def __init__(self, verbose=False, config_file=None, cq_enabled=False):
self.verbose = verbose
self.cq_enabled = cq_enabled
self.public_checkers = [SphinxChecker(self.verbose), DoxyChecker(self.verbose), JUnitChecker(self.verbose),
XMLRunnerChecker(self.verbose), CoverityChecker(self.verbose),
XMLRunnerChecker(self.verbose), GccChecker(self.verbose), CoverityChecker(self.verbose),
RobotChecker(self.verbose), PolyspaceChecker(self.verbose)]

if config_file:
Expand Down Expand Up @@ -246,6 +246,7 @@ def warnings_wrapper(args):
group1.add_argument('-r', '--robot', dest='robot', action='store_true')
group1.add_argument('-s', '--sphinx', dest='sphinx', action='store_true')
group1.add_argument('-x', '--xmlrunner', dest='xmlrunner', action='store_true')
group1.add_argument('-g', '--gcc', dest='gcc', action='store_true')
group1.add_argument('--name', default='',
help='Name of the Robot Framework test suite to check results of')
group1.add_argument('-m', '--maxwarnings', '--max-warnings', type=int, default=0,
Expand Down Expand Up @@ -277,7 +278,7 @@ def warnings_wrapper(args):
code_quality_enabled = bool(args.code_quality)
# Read config file
if args.configfile is not None:
checker_flags = args.sphinx or args.doxygen or args.junit or args.coverity or args.xmlrunner or args.robot
checker_flags = args.sphinx or args.doxygen or args.junit or args.coverity or args.xmlrunner or args.robot or args.gcc
warning_args = args.maxwarnings or args.minwarnings or args.exact_warnings
if checker_flags or warning_args:
print("Configfile cannot be provided with other arguments")
Expand All @@ -293,6 +294,8 @@ def warnings_wrapper(args):
warnings.activate_checker_name('junit')
if args.xmlrunner:
warnings.activate_checker_name('xmlrunner')
if args.gcc:
warnings.activate_checker_name('gcc')
if args.coverity:
warnings.activate_checker_name('coverity')
if args.robot:
Expand Down
54 changes: 54 additions & 0 deletions tests/test_gcc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from io import StringIO
from unittest import TestCase

from unittest.mock import patch

from mlx.warnings import WarningsPlugin


class TestGccWarnings(TestCase):
def setUp(self):
self.warnings = WarningsPlugin(verbose=True)
self.warnings.activate_checker_name('gcc')

def test_no_warning(self):
dut = 'This should not be treated as warning'
self.warnings.check(dut)
self.assertEqual(self.warnings.return_count(), 0)

def test_single_warning(self):
dut = "testfile.c:6:1: warning: missing initializer for field 'reserved' of 'ARM_SPI_CAPABILITIES' {aka 'const struct _ARM_SPI_CAPABILITIES'} [-Wmissing-field-initializers]"
with patch('sys.stdout', new=StringIO()) as fake_out:
self.warnings.check(dut)
self.assertEqual(self.warnings.return_count(), 1)
self.assertRegex(fake_out.getvalue()[:25], dut[:25])

def test_single_warning_mixed(self):
dut1 = 'This1 should not be treated as warning'
dut2 = "testfile.c:6:1: warning: missing initializer for field 'reserved' of 'ARM_SPI_CAPABILITIES' {aka 'const struct _ARM_SPI_CAPABILITIES'} [-Wmissing-field-initializers]"
dut3 = 'This should not be treated as warning2'
with patch('sys.stdout', new=StringIO()) as fake_out:
self.warnings.check(dut1)
self.warnings.check(dut2)
self.warnings.check(dut3)
self.assertEqual(self.warnings.return_count(), 1)
self.assertRegex(fake_out.getvalue()[:25], dut2[:25])

def test_multiline(self):
duterr1 = "../Driver/bla/Source/example_spi.c: In function 'SPI_InterruptReceive':\n../Driver/bla/Source/example_spi.c:957:43: warning: unused parameter 'data' [-Wunused-parameter]\n 957 | static int32_t SPI_InterruptReceive(void *data, uint32_t num, DEV_SPI_INFO *spi_info_ptr)\n | ~~~~~~^~~~"
duterr2 = "../Driver/bla/Source/example_spi.c: In function 'SPI_MasterCommonControl':\n../Driver/bla/Source/example_spi.c:200:18: warning: statement will never be executed [-Wswitch-unreachable]\n 200 | uint32_t val32 = SPI_CPOL_0_CPHA_0;\n | ^~~~~"
dut = "This1 should not be treated as warning\n"
dut += duterr1
dut += "This should not be treated as warning2\n"
dut += duterr2
with patch('sys.stdout', new=StringIO()) as fake_out:
self.warnings.check(dut)
self.assertEqual(self.warnings.return_count(), 2)
self.assertRegex(fake_out.getvalue()[:25], duterr1[:25])
self.assertRegex(fake_out.getvalue()[:25], duterr2[:25])

def test_gcc_warnings_txt(self):
dut_file = 'tests/test_in/gcc_warnings.txt'
with open(dut_file, 'r') as open_file:
self.warnings.check(open_file.read())
self.assertEqual(self.warnings.return_count(), 15)
3 changes: 3 additions & 0 deletions tests/test_in/config_example.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,8 @@
},
"polyspace": {
"enabled": false
},
"gcc": {
"enabled": false
}
}
3 changes: 3 additions & 0 deletions tests/test_in/config_example_exclude.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,8 @@
},
"polyspace": {
"enabled": false
},
"gcc": {
"enabled": false
}
}
2 changes: 2 additions & 0 deletions tests/test_in/config_example_exclude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ polyspace:
- information: "impact: low"
min: 0
max: 30
gcc:
enabled: false
2 changes: 2 additions & 0 deletions tests/test_in/config_example_polyspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ polyspace:
- information: "impact: low"
min: 0
max: 30
gcc:
enabled: false
4 changes: 3 additions & 1 deletion tests/test_in/config_example_polyspace_exclude.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
"max": 30
}
]

},
"gcc": {
"enabled": false
}
}
2 changes: 2 additions & 0 deletions tests/test_in/config_example_polyspace_exclude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ polyspace:
- information: 'impact: low'
min: 0
max: 30
gcc:
enabled: false
2 changes: 2 additions & 0 deletions tests/test_in/config_example_polyspace_green.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ polyspace:
- information: "impact: low"
min: 0
max: 30
gcc:
enabled: false
3 changes: 3 additions & 0 deletions tests/test_in/config_example_robot.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,8 @@
},
"polyspace": {
"enabled": false
},
"gcc": {
"enabled": false
}
}
3 changes: 3 additions & 0 deletions tests/test_in/config_example_robot_invalid_suite.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@
},
"polyspace": {
"enabled": false
},
"gcc": {
"enabled": false
}
}
64 changes: 64 additions & 0 deletions tests/test_in/gcc_warnings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
[13/27] Compiling C object bla-cpu0.elf.p/App_Source_bla2_bla2.c.o
../App/Source/bla2/bla2.c: In function 'bla2_MasterSignalEvent_t':
../App/Source/bla2/bla2.c:66:44: warning: unused parameter 'event' [-Wunused-parameter]
66 | void bla2_MasterSignalEvent_t(uint32_t event)
| ~~~~~~~~~^~~~~
../App/Source/bla2/bla2.c: In function 'bla2_CRC':
../App/Source/bla2/bla2.c:233:35: warning: comparison of integer expressions of different signedness: 'int16_t' {aka 'short int'} and 'unsigned int' [-Wsign-compare]
233 | for (int16_t index = 0; index < bla2_TRANSFER_SIZE - 1; index++)
| ^
[14/27] Compiling C object subprojects/CMock-2.5.3/src/libcmock.a.p/cmock.c.o
[15/27] Linking static target subprojects/CMock-2.5.3/src/libcmock.a
[16/27] Compiling C object bla-cpu0-tests.elf.p/App_Test_test_math.c.o
[17/27] Compiling C object libdrivers.a.p/Driver_bla_Source_example_spi.c.o
../Driver/bla/Source/example_spi.c:88:1: warning: missing initializer for field 'reserved' of 'ARM_SPI_CAPABILITIES' {aka 'const struct _ARM_SPI_CAPABILITIES'} [-Wmissing-field-initializers]
88 | };
| ^
In file included from ../Driver/bla/Include/example_spi.h:25,
from ../Driver/bla/Source/example_spi.c:25:
../Driver/Include/Driver_SPI.h:201:12: note: 'reserved' declared here
201 | uint32_t reserved : 28; ///< Reserved (must be zero)
| ^~~~~~~~
../Driver/bla/Source/example_spi.c: In function 'SPI_InterruptSend':
../Driver/bla/Source/example_spi.c:912:46: warning: unused parameter 'data' [-Wunused-parameter]
912 | static int32_t SPI_InterruptSend(const void *data, uint32_t num, DEV_SPI_INFO *spi_info_ptr)
| ~~~~~~~~~~~~^~~~
../Driver/bla/Source/example_spi.c:912:61: warning: unused parameter 'num' [-Wunused-parameter]
912 | static int32_t SPI_InterruptSend(const void *data, uint32_t num, DEV_SPI_INFO *spi_info_ptr)
| ~~~~~~~~~^~~
../Driver/bla/Source/example_spi.c:912:80: warning: unused parameter 'spi_info_ptr' [-Wunused-parameter]
912 | static int32_t SPI_InterruptSend(const void *data, uint32_t num, DEV_SPI_INFO *spi_info_ptr)
| ~~~~~~~~~~~~~~^~~~~~~~~~~~
../Driver/bla/Source/example_spi.c: In function 'SPI_InterruptReceive':
../Driver/bla/Source/example_spi.c:957:43: warning: unused parameter 'data' [-Wunused-parameter]
957 | static int32_t SPI_InterruptReceive(void *data, uint32_t num, DEV_SPI_INFO *spi_info_ptr)
| ~~~~~~^~~~
../Driver/bla/Source/example_spi.c:957:58: warning: unused parameter 'num' [-Wunused-parameter]
957 | static int32_t SPI_InterruptReceive(void *data, uint32_t num, DEV_SPI_INFO *spi_info_ptr)
| ~~~~~~~~~^~~
../Driver/bla/Source/example_spi.c:957:77: warning: unused parameter 'spi_info_ptr' [-Wunused-parameter]
957 | static int32_t SPI_InterruptReceive(void *data, uint32_t num, DEV_SPI_INFO *spi_info_ptr)
| ~~~~~~~~~~~~~~^~~~~~~~~~~~
../Driver/bla/Source/example_spi.c: In function 'SPI_InterruptTransfer':
../Driver/bla/Source/example_spi.c:1010:13: warning: unused variable 'buffer_in' [-Wunused-variable]
1010 | int8_t *buffer_in = (int8_t *)data_in;
| ^~~~~~~~~
../Driver/bla/Source/example_spi.c:1009:13: warning: unused variable 'buffer_out' [-Wunused-variable]
1009 | int8_t *buffer_out = (int8_t *)data_out;
| ^~~~~~~~~~
../Driver/bla/Source/example_spi.c: In function 'SPI_InterruptGetStatus':
../Driver/bla/Source/example_spi.c:1189:60: warning: unused parameter 'spi' [-Wunused-parameter]
1189 | static ARM_SPI_STATUS SPI_InterruptGetStatus(DEV_SPI_INFO *spi)
| ~~~~~~~~~~~~~~^~~
../Driver/bla/Source/example_spi.c: At top level:
../Driver/bla/Source/example_spi.c:99:13: warning: 'dw_spi_0_isr' declared 'static' but never defined [-Wunused-function]
99 | static void dw_spi_0_isr(void *ptr);
| ^~~~~~~~~~~~
../Driver/bla/Source/example_spi.c: In function 'SPI_MasterCommonControl':
../Driver/bla/Source/example_spi.c:200:18: warning: statement will never be executed [-Wswitch-unreachable]
200 | uint32_t val32 = SPI_CPOL_0_CPHA_0;
| ^~~~~
../Driver/bla/Source/example_spi.c: In function 'SPI_SlaveCommonControl':
../Driver/bla/Source/example_spi.c:278:18: warning: statement will never be executed [-Wswitch-unreachable]
278 | uint32_t val32 = SPI_CPOL_0_CPHA_0;
| ^~~~~
Loading