addons/cert.py: better handling of structs. read pragmas in the file.
This commit is contained in:
parent
4fff185046
commit
498c920180
|
@ -10,17 +10,32 @@
|
||||||
|
|
||||||
import cppcheckdata
|
import cppcheckdata
|
||||||
import sys
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
def reportError(token, severity, msg):
|
def reportError(token, severity, msg):
|
||||||
sys.stderr.write('[' + token.file + ':' + str(token.linenr) + '] (' + severity + ') cert.py: ' + msg + '\n')
|
sys.stderr.write('[' + token.file + ':' + str(token.linenr) + '] (' + severity + ') cert.py: ' + msg + '\n')
|
||||||
|
|
||||||
|
def isUnpackedStruct(var):
|
||||||
|
decl = var.typeStartToken
|
||||||
|
while decl and decl.isName:
|
||||||
|
if decl.str == 'struct':
|
||||||
|
structScope = decl.next.typeScope
|
||||||
|
if structScope:
|
||||||
|
linenr = int(structScope.classStart.linenr)
|
||||||
|
for line in open(structScope.classStart.file):
|
||||||
|
linenr = linenr - 1
|
||||||
|
if linenr == 0:
|
||||||
|
return True
|
||||||
|
if re.match(r'#pragma\s+pack\s*\(',line):
|
||||||
|
return False
|
||||||
|
break
|
||||||
|
decl = decl.next
|
||||||
|
return False
|
||||||
|
|
||||||
def isLocalStruct(arg):
|
def isLocalUnpackedStruct(arg):
|
||||||
if arg and arg.str == '&' and not arg.astOperand2:
|
if arg and arg.str == '&' and not arg.astOperand2:
|
||||||
arg = arg.astOperand1
|
arg = arg.astOperand1
|
||||||
return arg and arg.variable and arg.variable.isClass and (arg.variable.isLocal or arg.variable.isArgument)
|
return arg and arg.variable and (arg.variable.isLocal or arg.variable.isArgument) and isUnpackedStruct(arg.variable)
|
||||||
|
|
||||||
|
|
||||||
def isBitwiseOp(token):
|
def isBitwiseOp(token):
|
||||||
return token and (token.str in ['&', '|', '^'])
|
return token and (token.str in ['&', '|', '^'])
|
||||||
|
@ -44,9 +59,9 @@ def exp42(data):
|
||||||
arg1 = token.astOperand2.astOperand1.astOperand1
|
arg1 = token.astOperand2.astOperand1.astOperand1
|
||||||
arg2 = token.astOperand2.astOperand1.astOperand2
|
arg2 = token.astOperand2.astOperand1.astOperand2
|
||||||
|
|
||||||
if token.astOperand1.str == 'memcmp' and (isLocalStruct(arg1) or isLocalStruct(arg2)):
|
if token.astOperand1.str == 'memcmp' and (isLocalUnpackedStruct(arg1) or isLocalUnpackedStruct(arg2)):
|
||||||
reportError(token, 'style', 'EXP42-C Comparison of struct padding data')
|
reportError(token, 'style', 'EXP42-C Comparison of struct padding data')
|
||||||
if (token.astOperand1.str in ['memcpy', 'memmove']) and isLocalStruct(arg2):
|
if (token.astOperand1.str in ['memcpy', 'memmove']) and isLocalUnpackedStruct(arg2):
|
||||||
reportError(token, 'style', 'EXP42-C Reading struct padding data')
|
reportError(token, 'style', 'EXP42-C Reading struct padding data')
|
||||||
|
|
||||||
# EXP46-C
|
# EXP46-C
|
||||||
|
|
|
@ -107,6 +107,10 @@ class Token:
|
||||||
# @endcode
|
# @endcode
|
||||||
values = None
|
values = None
|
||||||
|
|
||||||
|
typeScopeId = None
|
||||||
|
## type scope (token->type()->classScope)
|
||||||
|
typeScope = None
|
||||||
|
|
||||||
astParentId = None
|
astParentId = None
|
||||||
## syntax tree parent
|
## syntax tree parent
|
||||||
astParent = None
|
astParent = None
|
||||||
|
@ -188,6 +192,8 @@ class Token:
|
||||||
self.function = None
|
self.function = None
|
||||||
self.valuesId = element.get('values')
|
self.valuesId = element.get('values')
|
||||||
self.values = None
|
self.values = None
|
||||||
|
self.typeScopeId = element.get('type-scope')
|
||||||
|
self.typeScope = None
|
||||||
self.astParentId = element.get('astParent')
|
self.astParentId = element.get('astParent')
|
||||||
self.astParent = None
|
self.astParent = None
|
||||||
self.astOperand1Id = element.get('astOperand1')
|
self.astOperand1Id = element.get('astOperand1')
|
||||||
|
@ -203,6 +209,7 @@ class Token:
|
||||||
self.variable = IdMap[self.variableId]
|
self.variable = IdMap[self.variableId]
|
||||||
self.function = IdMap[self.functionId]
|
self.function = IdMap[self.functionId]
|
||||||
self.values = IdMap[self.valuesId]
|
self.values = IdMap[self.valuesId]
|
||||||
|
self.typeScope = IdMap[self.typeScopeId]
|
||||||
self.astParent = IdMap[self.astParentId]
|
self.astParent = IdMap[self.astParentId]
|
||||||
self.astOperand1 = IdMap[self.astOperand1Id]
|
self.astOperand1 = IdMap[self.astOperand1Id]
|
||||||
self.astOperand2 = IdMap[self.astOperand2Id]
|
self.astOperand2 = IdMap[self.astOperand2Id]
|
||||||
|
|
|
@ -3834,6 +3834,8 @@ void Tokenizer::dump(std::ostream &out) const
|
||||||
out << " function=\"" << tok->function() << '\"';
|
out << " function=\"" << tok->function() << '\"';
|
||||||
if (!tok->values.empty())
|
if (!tok->values.empty())
|
||||||
out << " values=\"" << &tok->values << '\"';
|
out << " values=\"" << &tok->values << '\"';
|
||||||
|
if (tok->type())
|
||||||
|
out << " type-scope=\"" << tok->type()->classScope << '\"';
|
||||||
if (tok->astParent())
|
if (tok->astParent())
|
||||||
out << " astParent=\"" << tok->astParent() << '\"';
|
out << " astParent=\"" << tok->astParent() << '\"';
|
||||||
if (tok->astOperand1())
|
if (tok->astOperand1())
|
||||||
|
|
Loading…
Reference in New Issue