misra; implement rule 8.10
This commit is contained in:
parent
f6efd8c6be
commit
d1fe34e167
|
@ -471,7 +471,8 @@ class Function:
|
|||
tokenDef Token in function definition
|
||||
isVirtual Is this function is virtual
|
||||
isImplicitlyVirtual Is this function is virtual this in the base classes
|
||||
isStatic Is this function is static
|
||||
isInlineKeyword Is inline keyword used
|
||||
isStatic Is this function static?
|
||||
"""
|
||||
|
||||
Id = None
|
||||
|
@ -485,6 +486,7 @@ class Function:
|
|||
type = None
|
||||
isVirtual = None
|
||||
isImplicitlyVirtual = None
|
||||
isInlineKeyword = None
|
||||
isStatic = None
|
||||
nestedIn = None
|
||||
|
||||
|
@ -494,12 +496,10 @@ class Function:
|
|||
self.tokenDefId = element.get('tokenDef')
|
||||
self.name = element.get('name')
|
||||
self.type = element.get('type')
|
||||
isVirtual = element.get('isVirtual')
|
||||
self.isVirtual = (isVirtual and isVirtual == 'true')
|
||||
isImplicitlyVirtual = element.get('isImplicitlyVirtual')
|
||||
self.isImplicitlyVirtual = (isImplicitlyVirtual and isImplicitlyVirtual == 'true')
|
||||
isStatic = element.get('isStatic')
|
||||
self.isStatic = (isStatic and isStatic == 'true')
|
||||
self.isImplicitlyVirtual = element.get('isImplicitlyVirtual', 'false') == 'true'
|
||||
self.isVirtual = element.get('isVirtual', 'false') == 'true'
|
||||
self.isInlineKeyword = element.get('isInlineKeyword', 'false') == 'true'
|
||||
self.isStatic = element.get('isStatic', 'false') == 'true'
|
||||
self.nestedIn = nestedIn
|
||||
|
||||
self.argument = {}
|
||||
|
@ -507,7 +507,7 @@ class Function:
|
|||
|
||||
def __repr__(self):
|
||||
attrs = ["Id", "tokenId", "tokenDefId", "name", "type", "isVirtual",
|
||||
"isImplicitlyVirtual", "isStatic", "argumentId"]
|
||||
"isImplicitlyVirtual", "isInlineKeyword", "isStatic", "argumentId"]
|
||||
return "{}({})".format(
|
||||
"Function",
|
||||
", ".join(("{}={}".format(a, repr(getattr(self, a))) for a in attrs))
|
||||
|
|
|
@ -1880,6 +1880,11 @@ class MisraChecker:
|
|||
self.reportError(var.nameToken, 8, 9)
|
||||
|
||||
|
||||
def misra_8_10(self, cfg):
|
||||
for func in cfg.functions:
|
||||
if func.isInlineKeyword and not func.isStatic:
|
||||
self.reportError(func.tokenDef, 8, 10)
|
||||
|
||||
def misra_8_11(self, data):
|
||||
for var in data.variables:
|
||||
if var.isExtern and simpleMatch(var.nameToken.next, '[ ]') and var.nameToken.scope.type == 'Global':
|
||||
|
@ -3602,6 +3607,7 @@ class MisraChecker:
|
|||
self.executeCheck(807, self.misra_8_7, dumpfile, cfg)
|
||||
self.executeCheck(808, self.misra_8_8, cfg)
|
||||
self.executeCheck(809, self.misra_8_9, cfg)
|
||||
self.executeCheck(810, self.misra_8_10, cfg)
|
||||
self.executeCheck(811, self.misra_8_11, cfg)
|
||||
self.executeCheck(812, self.misra_8_12, cfg)
|
||||
if cfgNumber == 0:
|
||||
|
|
|
@ -379,6 +379,8 @@ extern int32_t misra_8_8; // 8.8 8.4
|
|||
static int32_t misra_8_9_i; // 8.9
|
||||
static int32_t misra_8_9_foo(void) { return misra_8_9_i++; }
|
||||
|
||||
inline int32_t misra_8_10_value(void) { return 123; } // 8.10 8.4
|
||||
|
||||
extern int a811[]; // 8.11 8.4
|
||||
|
||||
enum misra_8_12_a { misra_a1 = 1, misra_a2 = 2, misra_a3, misra_a4 = 3 }; //8.12
|
||||
|
|
|
@ -2268,10 +2268,16 @@ Function::Function(const Token *tokenDef, const std::string &clangType)
|
|||
|
||||
const Token *Function::setFlags(const Token *tok1, const Scope *scope)
|
||||
{
|
||||
if (tok1->isInline())
|
||||
isInlineKeyword(true);
|
||||
|
||||
// look for end of previous statement
|
||||
while (tok1->previous() && !Token::Match(tok1->previous(), ";|}|{|public:|protected:|private:")) {
|
||||
tok1 = tok1->previous();
|
||||
|
||||
if (tok1->isInline())
|
||||
isInlineKeyword(true);
|
||||
|
||||
// extern function
|
||||
if (tok1->str() == "extern") {
|
||||
isExtern(true);
|
||||
|
@ -3721,6 +3727,8 @@ void SymbolDatabase::printXml(std::ostream &out) const
|
|||
else if (function->isImplicitlyVirtual())
|
||||
out << " isImplicitlyVirtual=\"true\"";
|
||||
}
|
||||
if (function->isInlineKeyword())
|
||||
out << " isInlineKeyword=\"true\"";
|
||||
if (function->isStatic())
|
||||
out << " isStatic=\"true\"";
|
||||
if (function->argCount() == 0U)
|
||||
|
|
|
@ -722,6 +722,7 @@ class CPPCHECKLIB Function {
|
|||
fIsVolatile = (1 << 20), ///< @brief is volatile
|
||||
fHasTrailingReturnType = (1 << 21), ///< @brief has trailing return type
|
||||
fIsEscapeFunction = (1 << 22), ///< @brief Function throws or exits
|
||||
fIsInlineKeyword = (1 << 23), ///< @brief Function has "inline" keyword
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -878,6 +879,9 @@ public:
|
|||
void hasBody(bool state) {
|
||||
setFlag(fHasBody, state);
|
||||
}
|
||||
bool isInlineKeyword() const {
|
||||
return getFlag(fIsInlineKeyword);
|
||||
}
|
||||
|
||||
bool isEscapeFunction() const {
|
||||
return getFlag(fIsEscapeFunction);
|
||||
|
@ -991,6 +995,9 @@ private:
|
|||
void hasTrailingReturnType(bool state) {
|
||||
return setFlag(fHasTrailingReturnType, state);
|
||||
}
|
||||
void isInlineKeyword(bool state) {
|
||||
setFlag(fIsInlineKeyword, state);
|
||||
}
|
||||
const Token *setFlags(const Token *tok1, const Scope *scope);
|
||||
};
|
||||
|
||||
|
|
18
lib/token.h
18
lib/token.h
|
@ -634,6 +634,13 @@ public:
|
|||
setFlag(fIsImplicitInt, b);
|
||||
}
|
||||
|
||||
bool isInline() const {
|
||||
return getFlag(fIsInline);
|
||||
}
|
||||
void isInline(bool b) {
|
||||
setFlag(fIsInline, b);
|
||||
}
|
||||
|
||||
bool isBitfield() const {
|
||||
return mImpl->mBits > 0;
|
||||
}
|
||||
|
@ -1197,7 +1204,7 @@ private:
|
|||
Token *mPrevious;
|
||||
Token *mLink;
|
||||
|
||||
enum : uint32_t {
|
||||
enum : uint64_t {
|
||||
fIsUnsigned = (1 << 0),
|
||||
fIsSigned = (1 << 1),
|
||||
fIsPointerCompare = (1 << 2),
|
||||
|
@ -1229,12 +1236,13 @@ private:
|
|||
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;')
|
||||
fIsImplicitInt = (1U << 31) // Is "int" token implicitly added?
|
||||
fIsImplicitInt = (1U << 31), // Is "int" token implicitly added?
|
||||
fIsInline = (1ULL << 32) // Is this a inline type
|
||||
};
|
||||
|
||||
Token::Type mTokType;
|
||||
|
||||
unsigned int mFlags;
|
||||
uint64_t mFlags;
|
||||
|
||||
TokenImpl *mImpl;
|
||||
|
||||
|
@ -1243,7 +1251,7 @@ private:
|
|||
* @param flag_ flag to get state of
|
||||
* @return true if flag set or false in flag not set
|
||||
*/
|
||||
bool getFlag(unsigned int flag_) const {
|
||||
bool getFlag(uint64_t flag_) const {
|
||||
return ((mFlags & flag_) != 0);
|
||||
}
|
||||
|
||||
|
@ -1252,7 +1260,7 @@ private:
|
|||
* @param flag_ flag to set state
|
||||
* @param state_ new state of flag
|
||||
*/
|
||||
void setFlag(unsigned int flag_, bool state_) {
|
||||
void setFlag(uint64_t flag_, bool state_) {
|
||||
mFlags = state_ ? mFlags | flag_ : mFlags & ~flag_;
|
||||
}
|
||||
|
||||
|
|
|
@ -11174,8 +11174,11 @@ void Tokenizer::simplifyKeyword()
|
|||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
if (keywords.find(tok->str()) != keywords.end()) {
|
||||
// Don't remove struct members
|
||||
if (!Token::simpleMatch(tok->previous(), "."))
|
||||
if (!Token::simpleMatch(tok->previous(), ".")) {
|
||||
if (tok->str().find("inline") != std::string::npos && Token::Match(tok->next(), "%name%"))
|
||||
tok->next()->isInline(true);
|
||||
tok->deleteThis(); // Simplify..
|
||||
}
|
||||
}
|
||||
|
||||
if (isC() || mSettings->standards.cpp == Standards::CPP03) {
|
||||
|
|
|
@ -247,6 +247,8 @@ private:
|
|||
|
||||
TEST_CASE(functionImplicitlyVirtual);
|
||||
|
||||
TEST_CASE(functionIsInlineKeyword);
|
||||
|
||||
TEST_CASE(functionStatic);
|
||||
|
||||
TEST_CASE(functionReturnsReference); // Function::returnsReference
|
||||
|
@ -2464,6 +2466,14 @@ private:
|
|||
ASSERT_EQUALS(true, function && function->isImplicitlyVirtual(false));
|
||||
}
|
||||
|
||||
void functionIsInlineKeyword() {
|
||||
GET_SYMBOL_DB("inline void fs() {}");
|
||||
(void)db;
|
||||
const Function *func = db->scopeList.back().function;
|
||||
ASSERT(func);
|
||||
ASSERT(func->isInlineKeyword());
|
||||
}
|
||||
|
||||
void functionStatic() {
|
||||
GET_SYMBOL_DB("static void fs() { }");
|
||||
(void)db;
|
||||
|
|
Loading…
Reference in New Issue