misra; implemented rule 20.8
This commit is contained in:
parent
00eb71fd49
commit
74ab8f1a48
|
@ -43,7 +43,7 @@ jobs:
|
|||
- name: Extra test for misra
|
||||
run: |
|
||||
C:\tools\cygwin\bin\bash.exe -l -c cd %GITHUB_WORKSPACE%\addons\test
|
||||
..\..\cppcheck --dump --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 --platform=unix64 && python3 ..\misra.py -verify misra\misra-test.c.dump
|
||||
..\..\cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 --platform=unix64 && python3 ..\misra.py -verify misra\misra-test.c.dump
|
||||
C:\tools\cygwin\bin\bash.exe -l -c cd %GITHUB_WORKSPACE%
|
||||
.\cppcheck --addon=misra --inline-suppr --enable=information --error-exitcode=1 addons\test\misra\misra-ctu-*-test.c
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ jobs:
|
|||
./cppcheck --addon=threadsafety --std=c++03 addons/test/threadsafety
|
||||
./cppcheck --addon=misra --inline-suppr --enable=information --error-exitcode=1 addons/test/misra/misra-ctu-*-test.c
|
||||
cd addons/test
|
||||
../../cppcheck --dump --suppress=uninitvar --inline-suppr misra/misra-test.c --std=c89 --platform=unix64 && python3 ../misra.py -verify misra/misra-test.c.dump
|
||||
../../cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra/misra-test.c --std=c89 --platform=unix64 && python3 ../misra.py -verify misra/misra-test.c.dump
|
||||
|
||||
- name: Build GUI on ubuntu
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
|
|
|
@ -137,5 +137,5 @@ jobs:
|
|||
run: |
|
||||
.\cppcheck.exe --addon=misra --inline-suppr --enable=information --error-exitcode=1 addons\test\misra\misra-ctu-*-test.c
|
||||
cd addons\test
|
||||
..\..\cppcheck.exe --dump --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 --platform=unix64 && python3 ..\misra.py -verify misra\misra-test.c.dump
|
||||
..\..\cppcheck.exe --dump -DDUMMY --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 --platform=unix64 && python3 ..\misra.py -verify misra\misra-test.c.dump
|
||||
|
||||
|
|
|
@ -73,8 +73,8 @@ matrix:
|
|||
- cd addons/test
|
||||
# We'll force C89 standard to enable an additional verification for
|
||||
# rules 5.4 and 5.5 which have standard-dependent options.
|
||||
- ${CPPCHECK} --dump --suppress=uninitvar --suppress=uninitStructMember --std=c89 misra/misra-test.c
|
||||
- ${CPPCHECK} --dump --suppress=uninitvar --suppress=uninitStructMember --std=c89 misra/misra-test.h
|
||||
- ${CPPCHECK} --dump -DDUMMY --suppress=uninitvar --suppress=uninitStructMember --std=c89 misra/misra-test.c
|
||||
- ${CPPCHECK} --dump -DDUMMY --suppress=uninitvar --suppress=uninitStructMember --std=c89 misra/misra-test.h
|
||||
- python3 ../misra.py -verify misra/misra-test.c.dump
|
||||
- ${CPPCHECK} --dump misra/misra-test.cpp
|
||||
- python3 ../misra.py -verify misra/misra-test.cpp.dump
|
||||
|
|
|
@ -94,6 +94,29 @@ class MacroUsage:
|
|||
)
|
||||
|
||||
|
||||
class PreprocessorIfCondition:
|
||||
"""
|
||||
Information about #if/#elif conditions
|
||||
"""
|
||||
|
||||
file = None
|
||||
linenr = None
|
||||
column = None
|
||||
E = None
|
||||
result = None
|
||||
|
||||
def __init__(self, element):
|
||||
_load_location(self, element)
|
||||
self.E = element.get('E')
|
||||
self.result = int(element.get('result'))
|
||||
|
||||
def __repr__(self):
|
||||
attrs = ["file", "linenr", "column", "E", "result"]
|
||||
return "{}({})".format(
|
||||
"PreprocessorIfCondition",
|
||||
", ".join(("{}={}".format(a, repr(getattr(self, a))) for a in attrs))
|
||||
)
|
||||
|
||||
|
||||
class ValueType:
|
||||
"""
|
||||
|
@ -759,6 +782,7 @@ class Configuration:
|
|||
name Name of the configuration, "" for default
|
||||
directives List of Directive items
|
||||
macro_usage List of used macros
|
||||
preprocessor_if_conditions List of preprocessor if conditions that was evaluated during preprocessing
|
||||
tokenlist List of Token items
|
||||
scopes List of Scope items
|
||||
functions List of Function items
|
||||
|
@ -770,6 +794,7 @@ class Configuration:
|
|||
name = ''
|
||||
directives = []
|
||||
macro_usage = []
|
||||
preprocessor_if_conditions = []
|
||||
tokenlist = []
|
||||
scopes = []
|
||||
functions = []
|
||||
|
@ -782,6 +807,7 @@ class Configuration:
|
|||
self.name = name
|
||||
self.directives = []
|
||||
self.macro_usage = []
|
||||
self.preprocessor_if_conditions = []
|
||||
self.tokenlist = []
|
||||
self.scopes = []
|
||||
self.functions = []
|
||||
|
@ -1045,6 +1071,10 @@ class CppcheckData:
|
|||
elif node.tag == 'macro' and event == 'start':
|
||||
cfg.macro_usage.append(MacroUsage(node))
|
||||
|
||||
# Preprocessor #if/#elif condition
|
||||
elif node.tag == "if-cond" and event == 'start':
|
||||
cfg.preprocessor_if_conditions.append(PreprocessorIfCondition(node))
|
||||
|
||||
# Parse tokens
|
||||
elif node.tag == 'tokenlist' and event == 'start':
|
||||
continue
|
||||
|
|
|
@ -3209,6 +3209,12 @@ class MisraChecker:
|
|||
self.reportError(directive, 20, 7)
|
||||
break
|
||||
|
||||
def misra_20_8(self, cfg):
|
||||
for cond in cfg.preprocessor_if_conditions:
|
||||
#print(cond)
|
||||
if cond.result and cond.result not in (0,1):
|
||||
self.reportError(cond, 20, 8)
|
||||
|
||||
def misra_20_10(self, data):
|
||||
for directive in data.directives:
|
||||
d = Define(directive)
|
||||
|
@ -3884,7 +3890,8 @@ class MisraChecker:
|
|||
self.executeCheck(2003, self.misra_20_3, cfg)
|
||||
self.executeCheck(2004, self.misra_20_4, cfg)
|
||||
self.executeCheck(2005, self.misra_20_5, cfg)
|
||||
self.executeCheck(2006, self.misra_20_7, cfg)
|
||||
self.executeCheck(2007, self.misra_20_7, cfg)
|
||||
self.executeCheck(2008, self.misra_20_8, cfg)
|
||||
self.executeCheck(2010, self.misra_20_10, cfg)
|
||||
self.executeCheck(2013, self.misra_20_13, cfg)
|
||||
self.executeCheck(2014, self.misra_20_14, cfg)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// To test:
|
||||
// ~/cppcheck/cppcheck --dump misra/misra-test.h --std=c89
|
||||
// ~/cppcheck/cppcheck --dump --suppress=uninitvar --inline-suppr misra/misra-test.c --std=c89 --platform=unix64 && python3 ../misra.py -verify misra/misra-test.c.dump
|
||||
// ~/cppcheck/cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra/misra-test.c --std=c89 --platform=unix64 && python3 ../misra.py -verify misra/misra-test.c.dump
|
||||
|
||||
#include "path\file.h" // 20.2
|
||||
#include "file//.h" // 20.2
|
||||
|
@ -1558,6 +1558,9 @@ struct { int a; } struct_20_7_s;
|
|||
|
||||
#define MUL(a ,b ) ( a * b ) // 20.7
|
||||
|
||||
#if __LINE__ // 20.8
|
||||
#endif
|
||||
|
||||
#define M_20_10(a) (#a) // 20.10
|
||||
|
||||
#else1 // 20.13
|
||||
|
|
|
@ -20,7 +20,7 @@ def find_cppcheck_binary():
|
|||
|
||||
def dump_create(fpath, *argv):
|
||||
cppcheck_binary = find_cppcheck_binary()
|
||||
cmd = [cppcheck_binary, "--dump", "--quiet", fpath] + list(argv)
|
||||
cmd = [cppcheck_binary, "--dump", "-DDUMMY", "--quiet", fpath] + list(argv)
|
||||
p = subprocess.Popen(cmd)
|
||||
p.communicate()
|
||||
if p.returncode != 0:
|
||||
|
|
|
@ -738,9 +738,11 @@ simplecpp::TokenList Preprocessor::preprocess(const simplecpp::TokenList &tokens
|
|||
|
||||
simplecpp::OutputList outputList;
|
||||
std::list<simplecpp::MacroUsage> macroUsage;
|
||||
std::list<simplecpp::IfCond> ifCond;
|
||||
simplecpp::TokenList tokens2(files);
|
||||
simplecpp::preprocess(tokens2, tokens1, files, mTokenLists, dui, &outputList, ¯oUsage);
|
||||
simplecpp::preprocess(tokens2, tokens1, files, mTokenLists, dui, &outputList, ¯oUsage, &ifCond);
|
||||
mMacroUsage = macroUsage;
|
||||
mIfCond = ifCond;
|
||||
|
||||
handleErrors(outputList, throwError);
|
||||
|
||||
|
@ -800,6 +802,9 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string
|
|||
std::string ret;
|
||||
try {
|
||||
ret = getcode(tokens1, cfg, files, filedata.find("#file") != std::string::npos);
|
||||
// Since "files" is a local variable the tracking info must be cleared..
|
||||
mMacroUsage.clear();
|
||||
mIfCond.clear();
|
||||
} catch (const simplecpp::Output &) {
|
||||
ret.clear();
|
||||
}
|
||||
|
@ -961,7 +966,7 @@ void Preprocessor::dump(std::ostream &out) const
|
|||
if (!mMacroUsage.empty()) {
|
||||
out << " <macro-usage>" << std::endl;
|
||||
for (const simplecpp::MacroUsage ¯oUsage: mMacroUsage) {
|
||||
out << " <macro "
|
||||
out << " <macro"
|
||||
<< " name=\"" << macroUsage.macroName << "\""
|
||||
<< " file=\"" << macroUsage.macroLocation.file() << "\""
|
||||
<< " line=\"" << macroUsage.macroLocation.line << "\""
|
||||
|
@ -969,10 +974,25 @@ void Preprocessor::dump(std::ostream &out) const
|
|||
<< " usefile=\"" << macroUsage.useLocation.file() << "\""
|
||||
<< " useline=\"" << macroUsage.useLocation.line << "\""
|
||||
<< " usecolumn=\"" << macroUsage.useLocation.col << "\""
|
||||
<< " known-value=\"" << (macroUsage.macroValueKnown ? 1 : 0) << "\"/>" << std::endl;
|
||||
<< " is-known-value=\"" << (macroUsage.macroValueKnown ? "true" : "false") << "\""
|
||||
<< "/>" << std::endl;
|
||||
}
|
||||
out << " </macro-usage>" << std::endl;
|
||||
}
|
||||
|
||||
if (!mIfCond.empty()) {
|
||||
out << " <simplecpp-if-cond>" << std::endl;
|
||||
for (const simplecpp::IfCond &ifCond: mIfCond) {
|
||||
out << " <if-cond"
|
||||
<< " file=\"" << ErrorLogger::toxml(ifCond.location.file()) << "\""
|
||||
<< " line=\"" << ifCond.location.line << "\""
|
||||
<< " column=\"" << ifCond.location.col << "\""
|
||||
<< " E=\"" << ErrorLogger::toxml(ifCond.E) << "\""
|
||||
<< " result=\"" << ifCond.result << "\""
|
||||
<< "/>" << std::endl;
|
||||
}
|
||||
out << " </simplecpp-if-cond>" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static const std::uint32_t crc32Table[] = {
|
||||
|
|
|
@ -223,7 +223,9 @@ private:
|
|||
/** filename for cpp/c file - useful when reporting errors */
|
||||
std::string mFile0;
|
||||
|
||||
/** simplecpp tracking info */
|
||||
std::list<simplecpp::MacroUsage> mMacroUsage;
|
||||
std::list<simplecpp::IfCond> mIfCond;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
Loading…
Reference in New Issue