misra: implement 8.1
This commit is contained in:
parent
2e5828aef0
commit
00a9671f46
|
@ -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))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
12
lib/token.h
12
lib/token.h
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 > ( ) ;";
|
||||||
|
|
Loading…
Reference in New Issue