Commit a47d9331 authored by Sergio Costas's avatar Sergio Costas

Added support for FOR loops

parent e69a65c4
......@@ -157,6 +157,7 @@ class crust(object):
print(" Block:")
for variable in block:
print(" Variable: {:s}".format(variable))
print(" uid: {:s}".format(str(block[variable]["uid"])))
print(" status: {:s}".format(str(block[variable]["status"])))
print(" alias: {:s}".format(str(block[variable]["alias"])))
print(" aliases: {:s}".format(str(block[variable]["aliases"])))
......@@ -354,7 +355,10 @@ class crust(object):
for a in base_alias["aliases"]:
if a != var_alias["uid"]:
new_aliases.append(a)
base_alias["aliases"] = new_aliases
if len(new_aliases) == 0:
base_alias["aliases"] = None
else:
base_alias["aliases"] = new_aliases
var_alias["aliases"] = None
......@@ -363,7 +367,7 @@ class crust(object):
self._remove_alias(var_container, var_alias)
if var_crust is not None:
if (var_crust is not None) and (var_crust["uid"] != var_alias["uid"]):
if var_crust["aliases"] is None:
var_crust["aliases"] = []
var_crust["aliases"].append(var_alias["uid"])
......@@ -549,7 +553,7 @@ class crust(object):
self._add_error(v["varlist"], self.MSG_CRITICAL, "Assigning the crust variable '{:s}' to the non-crust variable '{:s}' at line {:d}", v["node"].name, dest_data["name"], statement.line)
if (orig_type == self.TYPE_NO_CRUST) and (dest_type == self.TYPE_CRUST):
self._add_error(v["varlist"], self.MSG_CRITICAL, "Assigning the non-crust variable '{:s}' to the crust variable '{:s}' at line {:d}", v["node"].name, dest_data["name"], statement.line)
if dest_data["alias"]:
if dest_data["alias"] and (dest_var.right is None):
self._assign_alias(v["varlist"], dest_data, orig_var, v["status"])
else:
if (orig_type == self.TYPE_CRUST) and self._check_statement_is_crust(v["node"], orig_var):
......@@ -776,6 +780,22 @@ class crust(object):
(statement.child2 is None)):
return self._eval_statement(statement.child1[0], var_container, first)
if ((statement.type == "INC_OP") or
(statement.type == "DEC_OP")):
tmp1 = statement.copy()
tmp1.type = "="
tmp2 = statement.copy()
if statement.type == "INC_OP":
tmp2.type = "+"
elif statement.type == "DEC_OP":
tmp2.type = "-"
tmp3 = statement.copy()
tmp3.type = "CONSTANT"
tmp3.t_null = False
tmp3.intval = 1
tmp1.child2 = [ tmp2 ] # child1 is the statement to be incremented
tmp2.child2 = [ tmp3 ] # child1 is the statement to be incremented
return self._eval_statement(tmp1, var_container, first)
if ((statement.type == "MUL_ASSIGN") or
(statement.type == "DIV_ASSIGN") or
......@@ -1256,6 +1276,31 @@ class crust(object):
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_container(var_container))
return retvals
if node.type == "FOR":
var_container["loop_level"] += 1
if node.for_ch1 is None:
init_loop = []
else:
init_loop = node.for_ch1
if node.for_ch2 is None:
init_loop = None
else:
condition = node.for_ch2[0]
if node.for_ch3 is None:
end_loop = []
else:
end_loop = node.for_ch3
wblock, other_block = self._get_next_block(tree[1:])
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_container(var_container) )
# 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_container(var_container))
# 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_container(var_container))
return retvals
if (node.type == "EVAL_TRUE") or (node.type == "EVAL_FALSE"):
values = self._eval_statement(node.condition, var_container)
retvals = []
......
......@@ -475,6 +475,21 @@ class Test(unittest.TestCase):
def test122DoWhileExitsBreak(self):
self._all_fine_test("unitest/test122.c")
def test123ForDefinedOutside(self):
self._generic_test("unitest/test123.c", [ (crust.crust.MSG_ERROR, "Parameter {:d} when calling function '{:s}' at line {:d} was freed at line {:d}", 1, "main", 10, 10) ])
def test124ForDefinedInside(self):
self._generic_test("unitest/test124.c", [ (crust.crust.MSG_ERROR, "Parameter {:d} when calling function '{:s}' at line {:d} was freed at line {:d}", 1, "main", 8, 8) ])
def test125ForDefinedOutside(self):
self._generic_test("unitest/test125.c", [ (crust.crust.MSG_ERROR, "Parameter {:d} when calling function '{:s}' at line {:d} was freed at line {:d}", 1, "main", 10, 10) ])
def test126ForFreesBlocks(self):
self._all_fine_test("unitest/test126.c")
def test127ForProcessesBlocks(self):
self._all_fine_test("unitest/test127.c")
if __name__ == '__main__':
try:
os.remove("error_list.txt")
......
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void main(crust_t param) {
int b;
for(b = 0; b == 0; b++) {
main(param); // ERROR: when executed two times, param is used after being freed
}
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void main(crust_t param) {
for(int b = 0; b == 0; b++) {
main(param); // ERROR: when executed two times, param is used after being freed
}
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void main(crust_t param) {
int b;
for(b = 0; b == 0;) {
main(param); // ERROR: when executed two times, param is used after being freed
}
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void free_block(crust_t block);
void main(crust_t param) {
crust_t looper;
// This loop works fine
for(looper = param; looper != NULL; looper = tmp) {
crust_t tmp = looper->next;
free_block(looper);
}
}
typedef __crust_t__ unsigned char *crust_t;
#define NULL ((void *)0)
void process_block(crust_t __crust_borrow__ block);
void main(crust_t param) {
// This loop works fine
for(__crust_alias__ crust_t looper = param; looper != NULL; looper = looper->next) {
process_block(looper);
}
}
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