Fix issue where misra 9_x evaluation crashes on some undefined structs with nested initialisers (#3290)
This commit is contained in:
parent
486e440c4a
commit
e3b7ceec7e
|
@ -87,7 +87,7 @@ class ElementDef:
|
||||||
if self.isFlexible:
|
if self.isFlexible:
|
||||||
while len(self.children) <= index:
|
while len(self.children) <= index:
|
||||||
createChild(self, self.flexibleToken, len(self.children))
|
createChild(self, self.flexibleToken, len(self.children))
|
||||||
return self.children[index] if index >= 0 and len(self.children) > index else None
|
return self.children[index] if 0 <= index < len(self.children) else None
|
||||||
|
|
||||||
def getChildByName(self, name):
|
def getChildByName(self, name):
|
||||||
for c in self.children:
|
for c in self.children:
|
||||||
|
@ -130,7 +130,7 @@ class ElementDef:
|
||||||
|
|
||||||
def getChildByValueElement(self, ed):
|
def getChildByValueElement(self, ed):
|
||||||
potentialChild = ed
|
potentialChild = ed
|
||||||
while potentialChild and not potentialChild in self.children:
|
while potentialChild and potentialChild not in self.children:
|
||||||
potentialChild = potentialChild.parent
|
potentialChild = potentialChild.parent
|
||||||
|
|
||||||
return self.children[self.children.index(potentialChild)] if potentialChild else None
|
return self.children[self.children.index(potentialChild)] if potentialChild else None
|
||||||
|
@ -182,7 +182,7 @@ class ElementDef:
|
||||||
|
|
||||||
def isAllChildrenSet(self):
|
def isAllChildrenSet(self):
|
||||||
myself = len(self.children) == 0 and (self.isDesignated or self.isPositional)
|
myself = len(self.children) == 0 and (self.isDesignated or self.isPositional)
|
||||||
mychildren = len(self.children) > 0 and all([child.isAllChildrenSet() for child in self.children])
|
mychildren = len(self.children) > 0 and all([child.isAllChildrenSet() for child in self.children])
|
||||||
return myself or mychildren
|
return myself or mychildren
|
||||||
|
|
||||||
def isAllSet(self):
|
def isAllSet(self):
|
||||||
|
@ -197,9 +197,9 @@ class ElementDef:
|
||||||
def isMisra93Compliant(self):
|
def isMisra93Compliant(self):
|
||||||
if self.elementType == 'array':
|
if self.elementType == 'array':
|
||||||
result = self.isAllChildrenSet() or \
|
result = self.isAllChildrenSet() or \
|
||||||
((self.isAllSet() or \
|
((self.isAllSet() or
|
||||||
self.isOnlyDesignated()) and \
|
self.isOnlyDesignated()) and
|
||||||
all([not (child.isDesignated or child.isPositional) or child.isMisra93Compliant() for child in self.children]))
|
all([not (child.isDesignated or child.isPositional) or child.isMisra93Compliant() for child in self.children]))
|
||||||
return result
|
return result
|
||||||
elif self.elementType == 'record':
|
elif self.elementType == 'record':
|
||||||
result = all([child.isMisra93Compliant() for child in self.children])
|
result = all([child.isMisra93Compliant() for child in self.children])
|
||||||
|
@ -213,7 +213,7 @@ class ElementDef:
|
||||||
def isMisra95Compliant(self):
|
def isMisra95Compliant(self):
|
||||||
return not self.isFlexible or all([not child.isDesignated for child in self.children])
|
return not self.isFlexible or all([not child.isDesignated for child in self.children])
|
||||||
|
|
||||||
# Parses the initializers and uodate the ElementDefs status accordingly
|
# Parses the initializers and update the ElementDefs status accordingly
|
||||||
class InitializerParser:
|
class InitializerParser:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.token = None
|
self.token = None
|
||||||
|
@ -254,7 +254,7 @@ class InitializerParser:
|
||||||
isDesignated = True
|
isDesignated = True
|
||||||
|
|
||||||
elif self.token.str == '{':
|
elif self.token.str == '{':
|
||||||
nextChild = self.root.getNextChild()
|
nextChild = self.root.getNextChild() if self.root is not None else None
|
||||||
|
|
||||||
if nextChild:
|
if nextChild:
|
||||||
if nextChild.isArray or nextChild.isRecord:
|
if nextChild.isArray or nextChild.isRecord:
|
||||||
|
@ -286,11 +286,12 @@ class InitializerParser:
|
||||||
self.token = self.token.astOperand1
|
self.token = self.token.astOperand1
|
||||||
isFirstElement = True
|
isFirstElement = True
|
||||||
else:
|
else:
|
||||||
# {}
|
if self.root:
|
||||||
if self.root.name == '<-':
|
# {}
|
||||||
self.root.parent.markStuctureViolation(self.token)
|
if self.root.name == '<-':
|
||||||
else:
|
self.root.parent.markStuctureViolation(self.token)
|
||||||
self.root.markStuctureViolation(self.token)
|
else:
|
||||||
|
self.root.markStuctureViolation(self.token)
|
||||||
self.ed = None
|
self.ed = None
|
||||||
self.unwindAndContinue()
|
self.unwindAndContinue()
|
||||||
|
|
||||||
|
@ -403,6 +404,12 @@ def misra_9_x(self, data, rule, rawTokens = None):
|
||||||
|
|
||||||
if variable.isArray or variable.isClass:
|
if variable.isArray or variable.isClass:
|
||||||
ed = getElementDef(nameToken, rawTokens)
|
ed = getElementDef(nameToken, rawTokens)
|
||||||
|
# No need to check non-arrays if valueType is missing,
|
||||||
|
# since we can't say anything useful about the structure
|
||||||
|
# without it.
|
||||||
|
if ed.valueType is None and not variable.isArray:
|
||||||
|
continue
|
||||||
|
|
||||||
parser.parseInitializer(ed, eq.astOperand2)
|
parser.parseInitializer(ed, eq.astOperand2)
|
||||||
# print(rule, nameToken.str + '=', ed.getInitDump())
|
# print(rule, nameToken.str + '=', ed.getInitDump())
|
||||||
if rule == 902 and not ed.isMisra92Compliant():
|
if rule == 902 and not ed.isMisra92Compliant():
|
||||||
|
|
|
@ -479,7 +479,9 @@ void misra_9_struct_initializers(void) {
|
||||||
dummy_struct dsc[2][2] = { {1,2}, {3,4} };
|
dummy_struct dsc[2][2] = { {1,2}, {3,4} };
|
||||||
dummy_struct dsd[2][2] = { 1, 2, 3, 4 }; // 9.2
|
dummy_struct dsd[2][2] = { 1, 2, 3, 4 }; // 9.2
|
||||||
dummy_struct dse[3] = { {1,2}, {3,4}, [1] = {5,6} }; // 9.3 9.4
|
dummy_struct dse[3] = { {1,2}, {3,4}, [1] = {5,6} }; // 9.3 9.4
|
||||||
dummy_struct dsd[] = { [0] = 1 }; // 9.5
|
dummy_struct dsf[] = { [0] = 1 }; // 9.5
|
||||||
|
dummy_struct dsg = { .a = {0}, .b = {0} };
|
||||||
|
dummy_struct dsh[2][2] = { { {.a = 0, .b = {0}}, { 0 } }, { { 0 }, {.a = 0, .b = {0}}} };
|
||||||
|
|
||||||
// Obsolete initialization syntax for GCC
|
// Obsolete initialization syntax for GCC
|
||||||
struct1 os1 = { i1: 1, i2: 2 }; // 10.4 13.4
|
struct1 os1 = { i1: 1, i2: 2 }; // 10.4 13.4
|
||||||
|
|
Loading…
Reference in New Issue