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 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;') 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;') 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 varId varId for token, each variable has a unique non-zero id
variable Variable information for this token. See the Variable class. variable Variable information for this token. See the Variable class.
function If this token points at a function call, this attribute has the Function function If this token points at a function call, this attribute has the Function
@ -192,6 +193,7 @@ class Token:
isExpandedMacro = False isExpandedMacro = False
isSplittedVarDeclComma = False isSplittedVarDeclComma = False
isSplittedVarDeclEq = False isSplittedVarDeclEq = False
isImplicitInt = False
varId = None varId = None
variableId = None variableId = None
variable = None variable = None
@ -257,6 +259,8 @@ class Token:
self.isSplittedVarDeclComma = True self.isSplittedVarDeclComma = True
if element.get('isSplittedVarDeclEq'): if element.get('isSplittedVarDeclEq'):
self.isSplittedVarDeclEq = True self.isSplittedVarDeclEq = True
if element.get('isImplicitInt'):
self.isImplicitInt = True
self.linkId = element.get('link') self.linkId = element.get('link')
self.link = None self.link = None
if element.get('varId'): if element.get('varId'):
@ -288,9 +292,10 @@ class Token:
"isNumber", "isInt", "isFloat", "isString", "strlen", "isNumber", "isInt", "isFloat", "isString", "strlen",
"isChar", "isOp", "isArithmeticalOp", "isComparisonOp", "isChar", "isOp", "isArithmeticalOp", "isComparisonOp",
"isLogicalOp", "isExpandedMacro", "isSplittedVarDeclComma", "isLogicalOp", "isExpandedMacro", "isSplittedVarDeclComma",
"isSplittedVarDeclEq","linkId", "varId", "variableId", "isSplittedVarDeclEq", "isImplicitInt", "linkId", "varId",
"functionId", "valuesId", "valueType", "typeScopeId", "variableId", "functionId", "valuesId", "valueType",
"astParentId", "astOperand1Id", "file", "linenr", "column"] "typeScopeId", "astParentId", "astOperand1Id", "file",
"linenr", "column"]
return "{}({})".format( return "{}({})".format(
"Token", "Token",
", ".join(("{}={}".format(a, repr(getattr(self, a))) for a in attrs)) ", ".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: if usedParameter.isString and parameterDefinition.nameToken:
reportErrorIfVariableIsNotConst(parameterDefinition.nameToken, usedParameter) 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 misra_8_2(self, data, rawTokens):
def getFollowingRawTokens(rawTokens, token, count): def getFollowingRawTokens(rawTokens, token, count):
following =[] following =[]
@ -3271,6 +3276,7 @@ class MisraChecker:
if cfgNumber == 0: if cfgNumber == 0:
self.executeCheck(703, self.misra_7_3, data.rawTokens) self.executeCheck(703, self.misra_7_3, data.rawTokens)
self.executeCheck(704, self.misra_7_4, cfg) self.executeCheck(704, self.misra_7_4, cfg)
self.executeCheck(801, self.misra_8_1, cfg)
if cfgNumber == 0: if cfgNumber == 0:
self.executeCheck(802, self.misra_8_2, cfg, data.rawTokens) self.executeCheck(802, self.misra_8_2, cfg, data.rawTokens)
self.executeCheck(811, self.misra_8_11, cfg) 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 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, ...); static int misra_8_2_a (int n, ...);
extern int misra_8_2_b (int n); extern int misra_8_2_b (int n);
extern int misra_8_2_c (int); // 8.2 extern int misra_8_2_c (int); // 8.2

View File

@ -633,6 +633,13 @@ public:
setFlag(fIsSplitVarDeclEq, b); setFlag(fIsSplitVarDeclEq, b);
} }
bool isImplicitInt() const {
return getFlag(fIsImplicitInt);
}
void isImplicitInt(bool b) {
setFlag(fIsImplicitInt, b);
}
bool isBitfield() const { bool isBitfield() const {
return mImpl->mBits > 0; return mImpl->mBits > 0;
} }
@ -1196,7 +1203,7 @@ private:
Token *mPrevious; Token *mPrevious;
Token *mLink; Token *mLink;
enum { enum : uint32_t {
fIsUnsigned = (1 << 0), fIsUnsigned = (1 << 0),
fIsSigned = (1 << 1), fIsSigned = (1 << 1),
fIsPointerCompare = (1 << 2), fIsPointerCompare = (1 << 2),
@ -1227,7 +1234,8 @@ private:
fConstexpr = (1 << 27), fConstexpr = (1 << 27),
fExternC = (1 << 28), fExternC = (1 << 28),
fIsSplitVarDeclComma = (1 << 29), // set to true when variable declarations are split up ('int a,b;' => 'int a; int b;') 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; Token::Type mTokType;

View File

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

View File

@ -1860,6 +1860,16 @@ void TokenList::simplifyPlatformTypes()
void TokenList::simplifyStdType() void TokenList::simplifyStdType()
{ {
for (Token *tok = front(); tok; tok = tok->next()) { 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"))) { 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 isFloat= false;
bool isSigned = false; bool isSigned = false;
@ -1897,6 +1907,7 @@ void TokenList::simplifyStdType()
tok->str("int"); tok->str("int");
tok->isSigned(isSigned); tok->isSigned(isSigned);
tok->isUnsigned(isUnsigned); tok->isUnsigned(isUnsigned);
tok->isImplicitInt(true);
} }
} else { } else {
typeSpec->isLong(typeSpec->isLong() || (isFloat && countLong == 1) || countLong > 1); typeSpec->isLong(typeSpec->isLong() || (isFloat && countLong == 1) || countLong > 1);

View File

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