Commit 25c460f9 authored by Sergio Costas's avatar Sergio Costas

Added CONTINUE support

parent b94c3edb
......@@ -1130,10 +1130,10 @@ class crust(object):
tmpvars["variables"][0][element.name] = params
parameters = self._find_function(thread_status, node.name, -1)
tmpvars["return_is_crust"] = self._check_statement_is_crust(node,parameters[0])
self._process_block(node.child1, tmpvars)
self._process_block(node.name, node.child1, tmpvars)
def _process_block(self, tree, thread_status):
def _process_block(self, function_name, tree, thread_status):
thread_status["debug_level"] = 0
thread_status["loop_level"] = 0
......@@ -1141,12 +1141,15 @@ class crust(object):
if tree[0].type == "START_BLOCK":
tree = tree[1:] # the variable block has been already added
blocks = [ (tree, thread_status) ]
print()
while len(blocks) > 0:
print("\rProcessing {:s}. Pending threads: {:d} ".format(function_name, len(blocks)),end="")
current_block = blocks[0]
blocks = blocks[1:]
if current_block[0] is not None:
retval = self._process_block2(current_block[0], current_block[1])
blocks = retval + blocks
print()
def _check_return_block(self, tree, thread_status):
......@@ -1303,10 +1306,21 @@ class crust(object):
tree = tree[1:]
return self._check_return_block(tree, thread_status)
if node.type == "CONTINUE":
if thread_status["loop_level"] == 0:
self._add_error(thread_status, self.MSG_CRITICAL, "Continue not in a loop at line {:d}", node.line)
return [(None, thread_status)]
while(tree[0].type != "TMP_END_LOOP"):
tree = tree[1:]
return self._check_return_block(tree, thread_status)
if node.type == "END_LOOP":
thread_status["loop_level"] -= 1
return self._check_return_block(tree[1:], thread_status)
if node.type == "TMP_END_LOOP":
return self._check_return_block(tree[1:], thread_status)
if node.type == "WHILE":
thread_status["loop_level"] += 1
condition = node.condition[0]
......@@ -1316,9 +1330,9 @@ class crust(object):
# loop executed zero times
retvals += self._check_return_block([self._new_eval_false(condition)] + other_block[:], self._copy_status(thread_status) )
# loop executed one time
retvals += self._check_return_block([self._new_start_block(), self._new_eval_true(condition)] + wblock[1:-1] + [self._new_eval_false(condition), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
retvals += self._check_return_block([self._new_start_block(), self._new_eval_true(condition)] + wblock[1:-1] + [self._new_eval_false(condition), self._new_tmp_end_loop(), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
# loop executed two times
retvals += self._check_return_block([self._new_start_block(), self._new_eval_true(condition)] + wblock[1:-1] + [self._new_eval_true(condition)] + wblock[1:-1] + [self._new_eval_false(condition), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
retvals += self._check_return_block([self._new_start_block(), self._new_eval_true(condition)] + wblock[1:-1] + [self._new_eval_true(condition), self._new_tmp_end_loop()] + wblock[1:-1] + [self._new_eval_false(condition), self._new_tmp_end_loop(), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
return retvals
if node.type == "DO":
......@@ -1327,9 +1341,9 @@ class crust(object):
wblock, other_block = self._get_next_block(tree[1:])
retvals = []
# loop executed one time
retvals += self._check_return_block([self._new_start_block()] + wblock[1:-1] + [self._new_eval_false(condition), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
retvals += self._check_return_block([self._new_start_block()] + wblock[1:-1] + [self._new_eval_false(condition), self._new_tmp_end_loop(), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
# loop executed two times
retvals += self._check_return_block([self._new_start_block()] + wblock[1:-1] + [self._new_eval_true(condition)] + wblock[1:-1] + [self._new_eval_false(condition), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
retvals += self._check_return_block([self._new_start_block()] + wblock[1:-1] + [self._new_eval_true(condition), self._new_tmp_end_loop()] + wblock[1:-1] + [self._new_eval_false(condition), self._new_tmp_end_loop(), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
return retvals
if node.type == "FOR":
......@@ -1352,14 +1366,17 @@ class crust(object):
# loop executed zero times
retvals += self._check_return_block([self._new_start_block()] + init_loop + [self._new_eval_false(condition), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status) )
# loop executed one time
retvals += self._check_return_block([self._new_start_block()] + init_loop + [self._new_eval_true(condition)] + wblock[1:-1] + end_loop + [self._new_eval_false(condition), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
retvals += self._check_return_block([self._new_start_block()] + init_loop + [self._new_eval_true(condition)] + wblock[1:-1] + end_loop + [self._new_eval_false(condition), self._new_tmp_end_loop(), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
# loop executed two times
retvals += self._check_return_block([self._new_start_block()] + init_loop + [self._new_eval_true(condition)] + wblock[1:-1] + end_loop + [self._new_eval_true(condition)] + wblock[1:-1] + end_loop + [self._new_eval_false(condition), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
retvals += self._check_return_block([self._new_start_block()] + init_loop + [self._new_eval_true(condition)] + wblock[1:-1] + end_loop + [self._new_eval_true(condition), self._new_tmp_end_loop()] + wblock[1:-1] + end_loop + [self._new_eval_false(condition), self._new_tmp_end_loop(), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
return retvals
if node.type == "CASE":
return self._check_return_block(tree[1:], self._copy_status(thread_status))
if node.type == "DEFAULT":
return self._check_return_block(tree[1:], self._copy_status(thread_status))
if node.type == "SWITCH":
thread_status["loop_level"] += 1
first_part = node.condition[0]
......@@ -1456,6 +1473,14 @@ class crust(object):
node.name = ""
return node
def _new_tmp_end_loop(self):
node = self.AST_node()
node.type = "TMP_END_LOOP"
node.line = -1
node.name = ""
return node
def _new_eval_false(self, condition):
node = self.AST_node()
node.type = "EVAL_FALSE"
......
......@@ -716,6 +716,30 @@ class Test(unittest.TestCase):
def test148CheckStructAccessWithoutPointer(self):
self._all_fine_test("unitest/test148.c")
def test149TestWhileContinue(self):
self._generic_test("unitest/test149.c", [ (crust.crust.MSG_ERROR, "Memory block '{:s}', initialized at line {:d}, is still in use at exit point at line {:d}", "param", 12, 16), (crust.crust.MSG_ERROR, "Assignment to '{:s}' at line {:d}, which was already assigned at line {:d}", "param", 12, 12) ])
def test150TestDoWhileContinue(self):
self._generic_test("unitest/test150.c", [ (crust.crust.MSG_ERROR, "Memory block '{:s}', initialized at line {:d}, is still in use at exit point at line {:d}", "param", 12, 16), (crust.crust.MSG_ERROR, "Assignment to '{:s}' at line {:d}, which was already assigned at line {:d}", "param", 12, 12) ])
def test151TestForContinue(self):
self._generic_test("unitest/test151.c", [ (crust.crust.MSG_ERROR, "Memory block '{:s}', initialized at line {:d}, is still in use at exit point at line {:d}", "param", 12, 16), (crust.crust.MSG_ERROR, "Assignment to '{:s}' at line {:d}, which was already assigned at line {:d}", "param", 12, 12) ])
def test152TestWhileContinue2(self):
self._generic_test("unitest/test152.c", [ (crust.crust.MSG_ERROR, "Parameter {:d} when calling function '{:s}' at line {:d} isn't initialized", 1, "function", 16), (crust.crust.MSG_ERROR, "Assignment to '{:s}' at line {:d}, which was already assigned at line {:d}", "param", 12, 12) ])
def test153TestDoWhileContinue2(self):
self._generic_test("unitest/test153.c", [ (crust.crust.MSG_ERROR, "Assignment to '{:s}' at line {:d}, which was already assigned at line {:d}", "param", 12, 12) ])
def test154TestForContinue2(self):
self._generic_test("unitest/test154.c", [ (crust.crust.MSG_ERROR, "Parameter {:d} when calling function '{:s}' at line {:d} isn't initialized", 1, "function", 16), (crust.crust.MSG_ERROR, "Assignment to '{:s}' at line {:d}, which was already assigned at line {:d}", "param", 12, 12) ])
def test155TestWhileContinue3(self):
self._generic_test("unitest/test155.c", [ (crust.crust.MSG_ERROR, "Assignment to '{:s}' at line {:d}, which was already assigned at line {:d}", "param", 12, 12) ])
def test156TestForContinue3(self):
self._generic_test("unitest/test156.c", [ (crust.crust.MSG_ERROR, "Assignment to '{:s}' at line {:d}, which was already assigned at line {:d}", "param", 12, 12) ])
if __name__ == '__main__':
try:
os.remove("error_list.txt")
......
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void function(crust_t param);
void main(int b) {
crust_t param;
while(b) {
param = (crust_t) 1; // ERROR: the second time the loop is run, this will overwrite the old value
continue;
function(param); // this will never be called
}
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void function(crust_t param);
void main(int b) {
crust_t param;
do {
param = (crust_t) 1; // ERROR: the second time the loop is run, this will overwrite the old value
continue;
function(param); // this will never be called
} while(b);
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void function(crust_t param);
void main(int b) {
crust_t param;
for(b=0; b<5; b++) {
param = (crust_t) 1; // ERROR: the second time the loop is run, this will overwrite the old value
continue;
function(param); // this will never be called
}
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void function(crust_t param);
void main(int b) {
crust_t param;
while(b) {
param = (crust_t) 1; // ERROR: the second time the loop is run, this will overwrite the old value
continue;
function(param); // this will never be called
}
function(param); // ERROR: if the FOR loop is not run (0 loops) this will fail
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void function(crust_t param);
void main(int b) {
crust_t param;
do {
param = (crust_t) 1; // ERROR: the second time the loop is run, this will overwrite the old value
continue;
function(param); // this will never be called
} while(b);
function(param); // This will always work because DO...WHILE loops always run at least once
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void function(crust_t param);
void main(int b) {
crust_t param;
for(b=0; b<5; b++) {
param = (crust_t) 1; // ERROR: the second time the loop is run, this will overwrite the old value
continue;
function(param); // this will never be called
}
function(param); // ERROR: if the FOR loop is not run (0 loops) this will fail
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void function(crust_t param);
void main(int b) {
crust_t param;
while __crust_no_0__ (b) {
param = (crust_t) 1; // ERROR: the second time the loop is run, this will overwrite the old value
continue;
function(param); // this will never be called
}
function(param); // This will always work because we disabled the option of never execute the statements inside the loop
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void function(crust_t param);
void main(int b) {
crust_t param;
for __crust_no_0__(b=0; b<5; b++) {
param = (crust_t) 1; // ERROR: the second time the loop is run, this will overwrite the old value
continue;
function(param); // this will never be called
}
function(param); // This will always work because we disabled the option of never execute the statements inside the loop
}
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