Commit ed51f94c authored by Sergio Costas's avatar Sergio Costas

Now only allows to set as NULL or NOT_NULL a global variable if it hasn't been accessed before

parent 2e259756
......@@ -317,9 +317,11 @@ class crust(object):
def _find_variable(self, thread_status, var_name, line_number, searching_function = False):
def _find_variable(self, thread_status, var_name, line_number, searching_function = False, set_used = True):
for var_group in thread_status["variables"]:
if var_name in var_group:
if set_used:
var_group[var_name]["accessed"] = True
return var_group[var_name]
if not searching_function:
self._add_error(thread_status, self.MSG_CRITICAL, "Unknown variable '{:s}' at line {:d}", str(var_name), line_number)
......@@ -1133,6 +1135,7 @@ class crust(object):
global: whether this variable is or not a global variable
uid: the Unique ID of the block stored in this variable, or None if there is no block
alias: the variable is an alias type
accessed: TRUE if the variable has been accessed (read or write)
"""
retval = {"name": None, "crust": False, "borrowed": False, "recycle": False, "not_null": False, "is_parameter": is_parameter, "void": False, "enum": False, "value": self.VALUE_UNINITIALIZED, "pointer": pointers, "struct": False, "override": False, "array": False, "function": False, "function_params": None, "ellipsis": False, "init_line": -1, "global": False, "uid": None, "alias": False }
......@@ -1196,6 +1199,7 @@ class crust(object):
if node.t_crust_alias:
retval["alias"] = True
retval["accessed"] = False
retval = self._node_fill_parameters(thread_status, node, retval)
return retval
......@@ -1218,7 +1222,7 @@ class crust(object):
counter = 0
for node in enum_node.enum_data:
tmpdata = self._get_variable_properties(thread_status, None, 0, False)
tmpdata["value"] = crust.VALUE_GLOBAL
tmpdata["value"] = self.VALUE_GLOBAL
tmpdata["init_line"] = node.line
tmpdata["enum"] = True
thread_status["variables"][0][node.name] = tmpdata
......@@ -1848,8 +1852,10 @@ class crust(object):
if node.type == "CRUST_SET_NULL":
var_name = node.child1[0].name
var_data = self._find_variable(thread_status, var_name, node.line)
var_data = self._find_variable(thread_status, var_name, node.line, False, False)
if var_data["global"]:
if var_data["accessed"]:
self._add_error(thread_status, self.MSG_CRITICAL, "Trying to set to NULL the state of the already accessed global variable '{:s}' at line {:d}", var_name, node.line)
self._set_var_value(thread_status, var_name, self.VALUE_NULL, node.line, True)
else:
self._add_error(thread_status, self.MSG_CRITICAL, "Trying to set to NULL the state of the non-global variable '{:s}' at line {:d}", var_name, node.line)
......@@ -1857,8 +1863,10 @@ class crust(object):
if node.type == "CRUST_SET_NOT_NULL":
var_name = node.child1[0].name
var_data = self._find_variable(thread_status, var_name, node.line)
var_data = self._find_variable(thread_status, var_name, node.line, False, False)
if var_data["global"]:
if var_data["accessed"]:
self._add_error(thread_status, self.MSG_CRITICAL, "Trying to set to NOT_NULL the state of the already accessed global variable '{:s}' at line {:d}", var_name, node.line)
self._set_var_value(thread_status, var_name, self.VALUE_NOT_NULL, node.line, True)
else:
self._add_error(thread_status, self.MSG_CRITICAL, "Trying to set to NOT_NULL the state of the non-global variable '{:s}' at line {:d}", var_name, node.line)
......
......@@ -961,6 +961,12 @@ class Test(unittest.TestCase):
def test229UseGlobalVarNotNull(self):
self._generic_test("unitest/test229.c", [ (crust.crust.MSG_ERROR, "At exit point in line {:d}, global variable '{:s}' points to a block freed at line {:d}.", 16, "var1", 11) ])
def test230SetGlobalToNullAfterUse(self):
self._generic_test("unitest/test230.c", [ (crust.crust.MSG_CRITICAL, "Trying to set to NULL the state of the already accessed global variable '{:s}' at line {:d}", "var1", 10) ])
def test231SetGlobalToNullAfterUse(self):
self._generic_test("unitest/test231.c", [ (crust.crust.MSG_CRITICAL, "Trying to set to NOT_NULL the state of the already accessed global variable '{:s}' at line {:d}", "var1", 10) ])
if __name__ == '__main__':
try:
os.remove("error_list.txt")
......
typedef __crust__ unsigned char *crust_t;
crust_t var1;
void main() {
if (var1 == NULL) {
var1 = NULL; // just to access the variable
}
__crust_set_null__(var1); // this is not allowed because we already have accessed the globar variable
}
typedef __crust__ unsigned char *crust_t;
crust_t var1;
void main() {
if (var1 == NULL) {
var1 = NULL; // just to access the variable
}
__crust_set_not_null__(var1); // this is not allowed because we already have accessed the globar variable
}
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