misra: implement 8.1

This commit is contained in:
Daniel Marjamäki 2021-07-07 13:34:55 +02:00
parent 2e5828aef0
commit 00a9671f46
7 changed files with 61 additions and 13 deletions

View File

@ -141,6 +141,7 @@ class Token:
isExpandedMacro Is this token a expanded macro token
isSplittedVarDeclComma Is this a comma changed to semicolon in a splitted variable declaration ('int a,b;' => 'int a; int b;')
isSplittedVarDeclEq Is this a '=' changed to semicolon in a splitted variable declaration ('int a=5;' => 'int a; a=5;')
isImplicitInt Is this token an implicit "int"?
varId varId for token, each variable has a unique non-zero id
variable Variable information for this token. See the Variable class.
function If this token points at a function call, this attribute has the Function
@ -192,6 +193,7 @@ class Token:
isExpandedMacro = False
isSplittedVarDeclComma = False
isSplittedVarDeclEq = False
isImplicitInt = False
varId = None
variableId = None
variable = None
@ -257,6 +259,8 @@ class Token:
self.isSplittedVarDeclComma = True
if element.get('isSplittedVarDeclEq'):
self.isSplittedVarDeclEq = True
if element.get('isImplicitInt'):
self.isImplicitInt = True
self.linkId = element.get('link')
self.link = None
if element.get('varId'):
@ -288,9 +292,10 @@ class Token:
"isNumber", "isInt", "isFloat", "isString", "strlen",
"isChar", "isOp", "isArithmeticalOp", "isComparisonOp",
"isLogicalOp", "isExpandedMacro", "isSplittedVarDeclComma",
"isSplittedVarDeclEq","linkId", "varId", "variableId",
"functionId", "valuesId", "valueType", "typeScopeId",
"astParentId", "astOperand1Id", "file", "linenr", "column"]
"isSplittedVarDeclEq", "isImplicitInt", "linkId", "varId",
"variableId", "functionId", "valuesId", "valueType",
"typeScopeId", "astParentId", "astOperand1Id", "file",
"linenr", "column"]
return "{}({})".format(
"Token",
", ".join(("{}={}".format(a, repr(getattr(self, a))) for a in attrs))

View File

@ -1486,6 +1486,11 @@ class MisraChecker:
if usedParameter.isString and parameterDefinition.nameToken:
reportErrorIfVariableIsNotConst(parameterDefinition.nameToken, usedParameter)
def misra_8_1(self, cfg):
for token in cfg.tokenlist:
if token.isImplicitInt:
self.reportError(token, 8, 1)
def misra_8_2(self, data, rawTokens):
def getFollowingRawTokens(rawTokens, token, count):
following =[]
@ -3271,6 +3276,7 @@ class MisraChecker:
if cfgNumber == 0:
self.executeCheck(703, self.misra_7_3, data.rawTokens)
self.executeCheck(704, self.misra_7_4, cfg)
self.executeCheck(801, self.misra_8_1, cfg)
if cfgNumber == 0:
self.executeCheck(802, self.misra_8_2, cfg, data.rawTokens)
self.executeCheck(811, self.misra_8_11, cfg)

View File

@ -326,6 +326,8 @@ void misra_7_4(void)
misra_7_4_call(1, "text_call"); // 7.4 11.8
}
const misra_8_1_a; // 8.1
static int misra_8_2_a (int n, ...);
extern int misra_8_2_b (int n);
extern int misra_8_2_c (int); // 8.2

View File

@ -633,6 +633,13 @@ public:
setFlag(fIsSplitVarDeclEq, b);
}
bool isImplicitInt() const {
return getFlag(fIsImplicitInt);
}
void isImplicitInt(bool b) {
setFlag(fIsImplicitInt, b);
}
bool isBitfield() const {
return mImpl->mBits > 0;
}
@ -1196,7 +1203,7 @@ private:
Token *mPrevious;
Token *mLink;
enum {
enum : uint32_t {
fIsUnsigned = (1 << 0),
fIsSigned = (1 << 1),
fIsPointerCompare = (1 << 2),
@ -1227,7 +1234,8 @@ private:
fConstexpr = (1 << 27),
fExternC = (1 << 28),
fIsSplitVarDeclComma = (1 << 29), // set to true when variable declarations are split up ('int a,b;' => 'int a; int b;')
fIsSplitVarDeclEq = (1 << 30) // set to true when variable declaration with initialization is split up ('int a=5;' => 'int a; a=5;')
fIsSplitVarDeclEq = (1 << 30), // set to true when variable declaration with initialization is split up ('int a=5;' => 'int a; a=5;')
fIsImplicitInt = (1U << 31) // Is "int" token implicitly added?
};
Token::Type mTokType;

View File

@ -5457,6 +5457,8 @@ void Tokenizer::dump(std::ostream &out) const
out << " isSplittedVarDeclComma=\"true\"";
if (tok->isSplittedVarDeclEq())
out << " isSplittedVarDeclEq=\"true\"";
if (tok->isImplicitInt())
out << " isImplicitInt=\"true\"";
if (tok->link())
out << " link=\"" << tok->link() << '\"';
if (tok->varId() > 0)

View File

@ -1860,6 +1860,16 @@ void TokenList::simplifyPlatformTypes()
void TokenList::simplifyStdType()
{
for (Token *tok = front(); tok; tok = tok->next()) {
if (Token::Match(tok, "const|extern *|&|%name%") && (!tok->previous() || Token::Match(tok->previous(), "[;{}]"))) {
if (Token::Match(tok->next(), "%name% !!;"))
continue;
tok->insertToken("int");
tok->next()->isImplicitInt(true);
continue;
}
if (Token::Match(tok, "char|short|int|long|unsigned|signed|double|float") || (mSettings->standards.c >= Standards::C99 && Token::Match(tok, "complex|_Complex"))) {
bool isFloat= false;
bool isSigned = false;
@ -1897,6 +1907,7 @@ void TokenList::simplifyStdType()
tok->str("int");
tok->isSigned(isSigned);
tok->isUnsigned(isUnsigned);
tok->isImplicitInt(true);
}
} else {
typeSpec->isLong(typeSpec->isLong() || (isFloat && countLong == 1) || countLong > 1);

View File

@ -228,15 +228,17 @@ private:
TEST_CASE(volatile_variables);
// unsigned i; => unsigned int i;
TEST_CASE(unsigned1);
TEST_CASE(unsigned2);
TEST_CASE(unsigned3); // template arguments
TEST_CASE(implicitIntConst);
TEST_CASE(implicitIntExtern);
TEST_CASE(implicitIntSigned1);
TEST_CASE(implicitIntUnsigned1);
TEST_CASE(implicitIntUnsigned2);
TEST_CASE(implicitIntUnsigned3); // template arguments
TEST_CASE(simplifyStdType); // #4947, #4950, #4951
TEST_CASE(createLinks);
TEST_CASE(createLinks2);
TEST_CASE(signed1);
TEST_CASE(simplifyString);
TEST_CASE(simplifyConst);
@ -2535,10 +2537,22 @@ private:
}
}
void implicitIntConst() {
ASSERT_EQUALS("const int x ;", tokenizeAndStringify("const x;"));
ASSERT_EQUALS("const int * x ;", tokenizeAndStringify("const *x;"));
ASSERT_EQUALS("const int * f ( ) ;", tokenizeAndStringify("const *f();"));
}
void implicitIntExtern() {
ASSERT_EQUALS("extern int x ;", tokenizeAndStringify("extern x;"));
ASSERT_EQUALS("extern int * x ;", tokenizeAndStringify("extern *x;"));
ASSERT_EQUALS("const int * f ( ) ;", tokenizeAndStringify("const *f();"));
}
/**
* tokenize "signed i" => "signed int i"
*/
void signed1() {
void implicitIntSigned1() {
{
const char code1[] = "void foo ( signed int , float ) ;";
ASSERT_EQUALS(code1, tokenizeAndStringify(code1));
@ -2572,7 +2586,7 @@ private:
* tokenize "unsigned i" => "unsigned int i"
* tokenize "unsigned" => "unsigned int"
*/
void unsigned1() {
void implicitIntUnsigned1() {
// No changes..
{
const char code[] = "void foo ( unsigned int , float ) ;";
@ -2607,14 +2621,14 @@ private:
}
}
void unsigned2() {
void implicitIntUnsigned2() {
const char code[] = "i = (unsigned)j;";
const char expected[] = "i = ( unsigned int ) j ;";
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
}
// simplify "unsigned" when using templates..
void unsigned3() {
void implicitIntUnsigned3() {
{
const char code[] = "; foo<unsigned>();";
const char expected[] = "; foo < unsigned int > ( ) ;";