Commit 4163c4ea authored by Sergio Costas's avatar Sergio Costas

Fixed the BREAK statement

Now the __crust_no_0__ can be put before or after FOR and WHILE
parent 6e0a0992
......@@ -1277,9 +1277,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_block(), self._new_end_loop()] + 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_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_block(), self._new_end_loop()] + 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)] + wblock[1:-1] + [self._new_eval_false(condition), self._new_end_loop(), self._new_end_block()] + other_block[:], self._copy_status(thread_status))
return retvals
if node.type == "DO":
......@@ -1288,9 +1288,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_block(), self._new_end_loop()] + 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_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_block(), self._new_end_loop()] + other_block[:], self._copy_status(thread_status))
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))
return retvals
if node.type == "FOR":
......@@ -1311,13 +1311,19 @@ class crust(object):
retvals = []
if not node.t_crust_no_zero:
# loop executed zero times
retvals += self._check_return_block([self._new_start_block()] + init_loop + [self._new_eval_false(condition), self._new_end_block(), self._new_end_loop()] + other_block[:], self._copy_status(thread_status) )
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_block(), self._new_end_loop()] + 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_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_block(), self._new_end_loop()] + 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)] + 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))
return retvals
# if node.type == "FOR":
# thread_status["loop_level"] += 1
if (node.type == "jlejlfe"):
pass
if (node.type == "EVAL_TRUE") or (node.type == "EVAL_FALSE"):
threads = self._eval_statement(node.condition, thread_status)
retvals = []
......
......@@ -797,6 +797,9 @@ for_statement
| CRUST_NO_ZERO FOR { $$ = $2;
$$->t_crust_no_zero = true;
free_tree($1); }
| FOR CRUST_NO_ZERO { $$ = $1;
$$->t_crust_no_zero = true;
free_tree($2); }
;
while_statement
......@@ -804,6 +807,9 @@ while_statement
| CRUST_NO_ZERO WHILE { $$ = $2;
$$->t_crust_no_zero = true;
free_tree($1); }
| WHILE CRUST_NO_ZERO { $$ = $1;
$$->t_crust_no_zero = true;
free_tree($2); }
;
iteration_statement
......
......@@ -680,6 +680,12 @@ class Test(unittest.TestCase):
def test137ReturnNoCrustExpectCrust(self):
self._generic_test("unitest/test137.c", [ (crust.crust.MSG_ERROR, "Return statement at line {:d} is returning a non-crust value, but is must return a crust one", 7) ])
def test138OddBreakInFor(self):
self._generic_test("unitest/test138.c", [ (crust.crust.MSG_ERROR, "Memory block '{:s}', initialized at line {:d}, is still in use at exit point at line {:d}", "param1", 7, 15) ])
def test139BreakInNestedFor(self):
self._generic_test("unitest/test139.c", [ (crust.crust.MSG_ERROR, "Memory block '{:s}', initialized at line {:d}, is still in use at exit point at line {:d}", "param2", 7, 22), (crust.crust.MSG_ERROR, "Memory block '{:s}', initialized at line {:d}, is still in use at exit point at line {:d}", "param1", 7, 22) ])
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(crust_t param1, crust_t param2) {
for __crust_no_0__ (int b=0; b < 4; b++) {
function(param2); // this must be called
break;
function(param1); // this must not be called
}
// here, param2 must be freed, but not param1
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void function(crust_t param);
void main(crust_t param1, crust_t param2, crust_t param3) {
for __crust_no_0__ (int b=0; b < 4; b++) {
for __crust_no_0__ (int c = 0; c < 4; b++) {
break;
for __crust_no_0__ (int d = 0; d < 4; d++) {
function(param1); // this never should be called
}
function(param2); // this also never should be called
}
function(param3); // this must be called
break;
}
// here, param3 must be freed, but neither param1 or param2
}
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