From 498c920180d7f5de53ce1d2d2292db2fc5f8f677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 28 Aug 2015 18:07:12 +0200 Subject: [PATCH] addons/cert.py: better handling of structs. read pragmas in the file. --- addons/cert.py | 27 +++++++++++++++++++++------ addons/cppcheckdata.py | 7 +++++++ lib/tokenize.cpp | 2 ++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/addons/cert.py b/addons/cert.py index 257a8e53a..cf5788c4e 100644 --- a/addons/cert.py +++ b/addons/cert.py @@ -10,17 +10,32 @@ import cppcheckdata import sys - +import re def reportError(token, severity, msg): 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: 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): return token and (token.str in ['&', '|', '^']) @@ -44,9 +59,9 @@ def exp42(data): arg1 = token.astOperand2.astOperand1.astOperand1 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') - 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') # EXP46-C diff --git a/addons/cppcheckdata.py b/addons/cppcheckdata.py index 3017a35c4..50c43bdf5 100644 --- a/addons/cppcheckdata.py +++ b/addons/cppcheckdata.py @@ -107,6 +107,10 @@ class Token: # @endcode values = None + typeScopeId = None + ## type scope (token->type()->classScope) + typeScope = None + astParentId = None ## syntax tree parent astParent = None @@ -188,6 +192,8 @@ class Token: self.function = None self.valuesId = element.get('values') self.values = None + self.typeScopeId = element.get('type-scope') + self.typeScope = None self.astParentId = element.get('astParent') self.astParent = None self.astOperand1Id = element.get('astOperand1') @@ -203,6 +209,7 @@ class Token: self.variable = IdMap[self.variableId] self.function = IdMap[self.functionId] self.values = IdMap[self.valuesId] + self.typeScope = IdMap[self.typeScopeId] self.astParent = IdMap[self.astParentId] self.astOperand1 = IdMap[self.astOperand1Id] self.astOperand2 = IdMap[self.astOperand2Id] diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index cb511f573..b4b5beff2 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3834,6 +3834,8 @@ void Tokenizer::dump(std::ostream &out) const out << " function=\"" << tok->function() << '\"'; if (!tok->values.empty()) out << " values=\"" << &tok->values << '\"'; + if (tok->type()) + out << " type-scope=\"" << tok->type()->classScope << '\"'; if (tok->astParent()) out << " astParent=\"" << tok->astParent() << '\"'; if (tok->astOperand1())