Commit e71c3fc4 authored by Sergio Costas's avatar Sergio Costas

Now bison adds always block start and block end in all IF statements, to...

Now bison adds always block start and block end in all IF statements, to ensure that the code can follow the execution flow in all cases

Added GE, LE, <, >, EQ_OP and NE_OP for generic cases
parent 50584266
......@@ -294,16 +294,16 @@ class crusty(object):
else:
return [ (self.STATUS_NOT_NULL, self._copy_container(var_container), valuetype, None, self.CONDITION_TRUE) ]
elif assignment.type == "FCONSTANT":
if assignment.type == "FCONSTANT":
if assignment.floatval == 0.0:
return [ (self.STATUS_NULL, self._copy_container(var_container), self.TYPE_NO_MATTER, None, self.CONDITION_FALSE) ]
else:
return [ (self.STATUS_NOT_NULL, self._copy_container(var_container), valuetype, None, self.CONDITION_TRUE) ]
elif assignment.type == "STRING_LITERAL":
if assignment.type == "STRING_LITERAL":
return [ (self.STATUS_NOT_NULL, self._copy_container(var_container), valuetype, None, self.CONDITION_TRUE) ]
elif assignment.type == "?":
if assignment.type == "?":
states = self._eval_assignment(assignment.condition[0],var_container,True)
retvals = []
for state in states:
......@@ -316,7 +316,7 @@ class crusty(object):
retvals += self._eval_assignment(assignment.child2[0],state[1],False)
return retvals
elif assignment.type == "FUNCTION_CALL":
if assignment.type == "FUNCTION_CALL":
function_data = self._find_function(assignment.name,assignment.line)
if function_data[0]["crust"] and (function_data[0]["pointer"] == 1):
retval_type = self.TYPE_CRUST
......@@ -378,7 +378,7 @@ class crusty(object):
return [ (self.STATUS_NOT_NULL_OR_NULL, newvar_container, retval_type, assignment.name, self.CONDITION_FALSE_TRUE) ]
return [ (retval, newvar_container, retval_type, assignment.name, self._status_to_condition(retval)) ]
elif assignment.type == "IDENTIFIER":
if assignment.type == "IDENTIFIER":
vardata = self._find_variable(var_container,assignment.name,assignment.line)
if valuetype == self.TYPE_NO_CRUST:
if vardata["crust"] and (vardata["pointer"] == 1):
......@@ -405,7 +405,7 @@ class crusty(object):
self._set_var_value(var_container,assignment.name,self.STATUS_FREED,assignment.line,True,True)
return [ (newstatus, self._copy_container(var_container), retval_type, assignment.name, self._status_to_condition(newstatus)) ]
elif assignment.type == "=":
if assignment.type == "=":
destination = assignment.child1[0]
var_defined = self._find_variable(var_container,destination.name,assignment.line)
options = self._eval_assignment(assignment.child2[0],var_container,False)
......@@ -467,15 +467,48 @@ class crusty(object):
self._set_var_value(var1,op1.name,crusty.STATUS_NULL,0,True)
self._set_var_value(var2,op1.name,crusty.STATUS_NOT_NULL,0,True)
return [(self.STATUS_NULL, self._copy_container(var1), self.TYPE_NO_CRUST,None, crusty.CONDITION_FALSE), (self.STATUS_NOT_NULL, self._copy_container(var2), self.TYPE_NO_CRUST,None, crusty.CONDITION_TRUE)]
else:
print("assignment type unknown '{:s}' at line {:d}".format(assignment.type,assignment.line))
return [ (self.STATUS_NOT_NULL_OR_NULL, self._copy_container(var_container), self.TYPE_NO_MATTER, assignment.name, self.CONDITION_FALSE_TRUE) ]
if assignment.type == "EQ_OP":
retvals = []
op1list = self._eval_assignment(assignment.child1[0],var_container,True)
for op1 in op1list:
op2list = self._eval_assignment(assignment.child2[0],op1[1],True)
for op2 in op2list:
if (op1[0] == self.STATUS_NULL) and (op2[0] == self.STATUS_NULL):
retvals += [(self.STATUS_NOT_NULL, op2[1], self.TYPE_NO_CRUST,None, crusty.CONDITION_TRUE)]
else:
retvals += [(self.STATUS_NOT_NULL, op2[1], self.TYPE_NO_CRUST,None, crusty.CONDITION_TRUE), (self.STATUS_NULL, op2[1], self.TYPE_NO_CRUST,None, crusty.CONDITION_FALSE)]
return retvals
if assignment.type == "NE_OP":
retvals = []
op1list = self._eval_assignment(assignment.child1[0],var_container,True)
for op1 in op1list:
op2list = self._eval_assignment(assignment.child2[0],op1[1],True)
for op2 in op2list:
if (op1[0] == self.STATUS_NULL) and (op2[0] == self.STATUS_NULL):
retvals += [(self.STATUS_NULL, op2[1], self.TYPE_NO_CRUST,None, crusty.CONDITION_FALSE) ]
else:
retvals += [ (self.STATUS_NOT_NULL, op2[1], self.TYPE_NO_CRUST,None, crusty.CONDITION_TRUE), (self.STATUS_NULL, op2[1], self.TYPE_NO_CRUST,None, crusty.CONDITION_FALSE) ]
return retvals
if (assignment.type == "GE_OP") or (assignment.type == "LE_OP") or (assignment.type == "<") or (assignment.type == ">"):
retvals = []
op1list = self._eval_assignment(assignment.child1[0],var_container,True)
for op1 in op1list:
op2list = self._eval_assignment(assignment.child2[0],op1[1],True)
for op2 in op2list:
retvals += [(self.STATUS_NOT_NULL_OR_NULL, op2[1], self.TYPE_NO_CRUST,None, crusty.CONDITION_FALSE_TRUE) ]
return retvals
print("assignment type unknown '{:s}' at line {:d}".format(assignment.type,assignment.line))
return [ (self.STATUS_NOT_NULL_OR_NULL, self._copy_container(var_container), self.TYPE_NO_MATTER, assignment.name, self.CONDITION_FALSE_TRUE) ]
def _get_next_block(self,current_block):
if current_block[0].type != "START_BLOCK":
# The block has only one statement, so it isn't a "block"
return ([current_block[0]],current_block[1:])
return [current_block[0]],current_block[1:]
depth = 0
pos = 0
while True:
......@@ -487,7 +520,7 @@ class crusty(object):
if depth == 0:
break
# return the block with both START_BLOCK and END_BLOCK statements
return (current_block[0:pos],current_block[pos:])
return current_block[0:pos],current_block[pos:]
def _get_variable_properties(self,node, pointers, is_parameter, is_retval = False):
......@@ -622,6 +655,11 @@ class crusty(object):
blocks += retval
def _print_tree(self,tree):
for node in tree:
print("{:s} at line {:d}".format(node.type,node.line))
print("\n\n")
def _process_block2(self, tree, var_container):
node = tree[0]
......@@ -683,6 +721,7 @@ class crusty(object):
for option in options:
retvals += self._check_return_block(tree[1:],option[1])
return retvals
if node.type == "IF":
tree = tree[1:]
block_true, block_other = self._get_next_block(tree)
......
......@@ -618,12 +618,32 @@ expression_statement
selection_statement
: IF '(' expression ')' statement { $$ = $1;
$$->condition = $3;
append_next($$,$5); }
if ($5->type == START_BLOCK) {
append_next($$,$5);
} else {
append_next_leaf($$,START_BLOCK);
append_next($$, $5);
append_next_leaf($$,END_BLOCK);
}
}
| IF '(' expression ')' statement ELSE statement { $$ = $1;
$$->condition = $3;
append_next($$,$5);
if ($5->type == START_BLOCK) {
append_next($$,$5);
} else {
append_next_leaf($$,START_BLOCK);
append_next($$, $5);
append_next_leaf($$,END_BLOCK);
}
append_next($$,$6);
append_next($$,$7); }
if ($7->type == START_BLOCK) {
append_next($$,$7);
} else {
append_next_leaf($$,START_BLOCK);
append_next($$, $7);
append_next_leaf($$,END_BLOCK);
}
}
| SWITCH '(' expression ')' statement { $$ = $1;
$$->condition = $3;
append_next($$,$5); }
......
......@@ -240,5 +240,14 @@ class Test(unittest.TestCase):
def testComparisonDoesntFreePointer(self):
self._generic_test("unitest/test56.c",[ (crusty.crusty.MSG_ERROR,"Assignment to '{:s}' at line {:d}, which was already assigned at line {:d}","param1",5,3) ])
def testComparisonWithoutBraces(self):
self._all_fine_test("unitest/test57.c")
def testNestedComparisonWithoutBraces(self):
self._all_fine_test("unitest/test58.c")
def testNestedComparisonWithBraces(self):
self._all_fine_test("unitest/test59.c")
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment