Commit b94c3edb authored by Sergio Costas's avatar Sergio Costas

Added support for SIZEOF statement

Now knows that an element from an uninitialized struct can be assigned without warning
parent d876a095
......@@ -426,6 +426,8 @@ class crust(object):
else:
return [ {"thread_status":thread_status, "value":self.VALUE_NOT_NULL, "type":self.TYPE_NO_CRUST, "condition":self.CONDITION_TRUE, "node":None} ]
if statement.type == "SIZEOF":
return [ {"thread_status":thread_status, "value":self.VALUE_NOT_NULL, "type":self.TYPE_NO_CRUST, "condition":self.CONDITION_TRUE, "node":None} ]
if statement.type == "FCONSTANT":
if statement.floatval == 0.0:
......@@ -552,7 +554,7 @@ class crust(object):
if (orig_type == self.TYPE_NO_CRUST) and (dest_type == self.TYPE_CRUST):
self._add_error(v["thread_status"], self.MSG_CRITICAL, "Assigning a non-crust value to the crust variable '{:s}' at line {:d}", dest_data["name"], statement.line)
if dest_var.right is not None:
if (dest_var.right is not None) and (dest_data["pointer"] != 0):
if dest_data["value"] == self.VALUE_NULL:
self._add_error(thread_status, self.MSG_ERROR, "Using variable '{:s}' at line {:d} with a NULL value", dest_data["name"], statement.line)
elif dest_data["value"] == self.VALUE_NOT_NULL_OR_NULL:
......@@ -615,9 +617,14 @@ class crust(object):
# stores the execution branches and the return value for each one, in case there is a recycle parameter
retvals = [ {"thread_status":thread_status, "value":self.VALUE_NOT_NULL_OR_NULL, "type": retval_type, "condition":self.CONDITION_FALSE_TRUE, "node":statement} ]
error_found = False
if function_data is None:
lenfunction_data = 0
else:
lenfunction_data = len(function_data) - 1
if statement.function_params is not None:
for pos in range(len(statement.function_params)):
if pos < (len(function_data) - 1):
if pos < lenfunction_data:
param_is_crust = function_data[pos+1]["crust"]
param_is_borrowed = function_data[pos+1]["borrowed"]
param_is_recycled = function_data[pos+1]["recycle"]
......
......@@ -713,6 +713,9 @@ class Test(unittest.TestCase):
def test147CheckAssignToElementOfUninitializedPointer(self):
self._generic_test("unitest/test147.c", [ (crust.crust.MSG_ERROR, "Using variable '{:s}' at line {:d}, but it hasn't been initialized yet", "param1", 15) ])
def test148CheckStructAccessWithoutPointer(self):
self._all_fine_test("unitest/test148.c")
if __name__ == '__main__':
try:
os.remove("error_list.txt")
......
......@@ -2,15 +2,15 @@ typedef __crust_t__ unsigned char *crust_t;
typedef crust_t (*prueba)();
__crust_t__ struct tmp {
typedef __crust_t__ struct {
prueba function_p;
};
} *tmp;
#define NULL ((void *)0)
crust_t function();
void main(struct tmp param1) {
void main(tmp param1) {
param1->function_p = function;
param1->function_p();
__crust_disable__
......
typedef __crust_t__ unsigned char *crust_t;
typedef crust_t (*prueba)();
typedef struct {
prueba function_p;
} tmp_struct;
#define NULL ((void *)0)
crust_t function();
void main() {
tmp_struct data1;
data1.function_p = function; // This is legal
__crust_disable__
}
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