Commit 05147f82 authored by Sergio Costas's avatar Sergio Costas

Merge branch 'override_signatures'

parents 04e02a9d b15be6bf
......@@ -1118,7 +1118,7 @@ class crust(object):
alias: the variable is an alias type
"""
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, "array": False, "function": False, "function_params": None, "ellipsis": False, "init_line": -1, "global": False, "uid": None, "alias": False }
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 }
if not isinstance(node, self.AST_node):
return retval
......@@ -1152,6 +1152,9 @@ class crust(object):
else:
self._add_error(thread_status, self.MSG_CRITICAL, "An argument can be BORROW or RECYCLE, not both. (argument '{:s}' at line {:d})", node.name, node.line)
if node.t_override:
retval["override"] = True
if node.t_crust_borrow:
retval["borrowed"] = True
......@@ -1291,20 +1294,26 @@ class crust(object):
tmpparams["ellipsis"] = node.t_ellipsis
tmpparams["definition_line"] = node.line
tmpparams["definition_file"] = node.filename
tmpparams["override"] = node.t_override
if node.name in thread_status["variables"][0]:
function_data = thread_status["variables"][0][node.name]
differ = False
if function_data["ellipsis"] != tmpparams["ellipsis"]:
differ = True
elif len(function_data["function_params"]) != len(tmpparams["function_params"]):
differ = True
if tmpparams["override"]:
del thread_status["variables"][0][node.name]
thread_status["variables"][0][node.name] = tmpparams
else:
for c in range(len(function_data["function_params"])):
if not self._compare_types(function_data["function_params"][c], tmpparams["function_params"][c], True):
if not function_data["override"]:
differ = False
if function_data["ellipsis"] != tmpparams["ellipsis"]:
differ = True
elif len(function_data["function_params"]) != len(tmpparams["function_params"]):
differ = True
break
if differ:
self._add_error(thread_status, self.MSG_CRITICAL, "Function definition for '{:s}' at line {:d}, file '{:s}' differs from definition at line {:d}, file '{:s}'", node.name, node.line, node.filename, function_data["definition_line"], function_data["definition_file"])
else:
for c in range(len(function_data["function_params"])):
if not self._compare_types(function_data["function_params"][c], tmpparams["function_params"][c], True):
differ = True
break
if differ:
self._add_error(thread_status, self.MSG_CRITICAL, "Function definition for '{:s}' at line {:d}, file '{:s}' differs from definition at line {:d}, file '{:s}'", node.name, node.line, node.filename, function_data["definition_line"], function_data["definition_file"])
else:
thread_status["variables"][0][node.name] = tmpparams
continue
......
......@@ -94,6 +94,7 @@ class tokens(object):
347:'CRUST_NO_ZERO',
348:'CRUST_SET_NULL',
349:'CRUST_SET_NOT_NULL',
350:'CRUST_OVERRIDE',
'IDENTIFIER':258,
'CONSTANT':259,
'STRING_LITERAL':260,
......@@ -186,6 +187,7 @@ class tokens(object):
'CRUST_NO_ZERO':347,
'CRUST_SET_NULL':348,
'CRUST_SET_NOT_NULL':349,
'CRUST_OVERRIDE':350,
}
@staticmethod
......
......@@ -107,6 +107,7 @@ struct AST * new_leaf(int type, struct AST *template) {
ast->t_null = false;
ast->t_ellipsis = false;
ast->t_label = false;
ast->t_override = false;
return ast;
}
......@@ -158,6 +159,7 @@ void mix_ast_leaves(struct AST *base, struct AST *origin_leaf) {
base->t_null |= origin_leaf->t_null;
base->t_ellipsis |= origin_leaf->t_ellipsis;
base->t_label |= origin_leaf->t_label;
base->t_override |= origin_leaf->t_override;
if (base->function_params == NULL) {
base->function_params = copy_leaf(origin_leaf->function_params, true);
}
......@@ -208,6 +210,7 @@ void copy_ast_data(struct AST *base, struct AST *new_leaf) {
base->t_null = new_leaf->t_null;
base->t_ellipsis = new_leaf->t_ellipsis;
base->t_label = new_leaf->t_label;
base->t_override = new_leaf->t_override;
//base->t_ |= new_leaf->t_;
}
......
......@@ -63,6 +63,7 @@ struct AST {
bool t_null;
bool t_ellipsis;
bool t_label;
bool t_override;
long long int intval;
double floatval;
......
......@@ -121,6 +121,7 @@ void find_close_parentheses(int);
"__crust_not_null__" { return prepare_leaf(0,0.0,CRUST_NOT_NULL); }
"__crust_set_null__" { return prepare_leaf(0,0.0,CRUST_SET_NULL); }
"__crust_set_not_null__" { return prepare_leaf(0,0.0,CRUST_SET_NOT_NULL); }
"__crust_override__" { return prepare_leaf(0,0.0,CRUST_OVERRIDE); }
{L}({L}|{D})* { return prepare_leaf(0,0.0,TYPENAME_IDENTIFIER); }
......@@ -397,6 +398,9 @@ int prepare_leaf(unsigned long long int v1, double v2, int current_token) {
yylval->t_crust_not_null = true;
yylval->t_crust = true;
break;
case CRUST_OVERRIDE:
yylval->t_override = true;
break;
case T_NULL:
yylval->t_null = true;
free(yylval->data);
......
......@@ -75,6 +75,7 @@ void add_type_element(char *);
%token CRUST_NO_ZERO
%token CRUST_SET_NULL
%token CRUST_SET_NOT_NULL
%token CRUST_OVERRIDE
//%start translation_unit
%start start_unit
......@@ -101,7 +102,8 @@ primary_expression
long_string_literal
: STRING_LITERAL { $$ = $1; show_debug(__LINE__, $$, "long_string_literal"); }
| long_string_literal STRING_LITERAL { int size1 = strlen($1->data);
| long_string_literal STRING_LITERAL { /* support for "xxxxx""yyy" strings */
int size1 = strlen($1->data);
char *data = (char *)malloc(size1 + strlen($2->data) - 1);
strcpy(data,$1->data);
data[size1 - 1] = 0; // remove the last double quote
......@@ -375,6 +377,9 @@ declaration
}
;
override_declaration
: CRUST_OVERRIDE declaration { $$ = $2; $$->t_override = true; }
declaration_specifiers
: storage_class_specifier { $$ = $1; show_debug(__LINE__, $$, "declaration_specifiers"); }
| storage_class_specifier declaration_specifiers { $$ = $1; show_debug(__LINE__, $$, "declaration_specifiers");
......@@ -1033,6 +1038,7 @@ translation_unit
external_declaration
: function_definition { $$ = $1; show_debug(__LINE__, $$, "external_declaration"); }
| declaration { $$ = $1; show_debug(__LINE__, $$, "external_declaration"); }
| override_declaration { $$ = $1; show_debug(__LINE__, $$, "external_declaration"); }
;
function_definition
......
......@@ -940,6 +940,17 @@ class Test(unittest.TestCase):
def test222TestConditionTrue(self):
self._generic_test("unitest/test222.c", [ (crust.crust.MSG_ERROR, "Memory block '{:s}', initialized at line {:d}, is still in use at exit point in line {:d}", "var", 11, 21) ])
def test223TestOverrideSignature(self):
self._all_fine_test("unitest/test223.c")
def test224TestOverrideSignature2(self):
self._all_fine_test("unitest/test224.c")
def test225TestNotOverrideSignature(self):
self._generic_test("unitest/test225.c", [ (crust.crust.MSG_CRITICAL, "Function definition for '{:s}' at line {:d}, file '{:s}' differs from definition at line {:d}, file '{:s}'", "test_function", 4, "unitest/test225.c", 3, "unitest/test225.c"), (crust.crust.MSG_CRITICAL, "Expected a non __crust__ variable as argument {:d} when calling function '{:s}' at line {:d}, but passed a __crust__ variable", 1, "test_function", 9) ])
def test226TestNotOverrideSignature2(self):
self._generic_test("unitest/test226.c", [ (crust.crust.MSG_CRITICAL, "Function definition for '{:s}' at line {:d}, file '{:s}' differs from definition at line {:d}, file '{:s}'", "test_function", 4, "unitest/test226.c", 3, "unitest/test226.c") ])
if __name__ == '__main__':
try:
......
......@@ -18,6 +18,5 @@ int main(crust_t var) {
}
a++;
}
return 0;
}
typedef __crust__ unsigned char *crust_t;
__crust_override__ void test_function(crust_t __crust_borrow__ param);
void test_function(unsigned char *param); // this one must be ignored
#define NULL ((void *)0)
void main(crust_t __crust_borrow__ param) {
test_function(param);
}
typedef __crust__ unsigned char *crust_t;
void test_function(unsigned char *param); // this one must be ignored
__crust_override__ void test_function(crust_t __crust_borrow__ param);
#define NULL ((void *)0)
void main(crust_t __crust_borrow__ param) {
test_function(param);
}
typedef __crust__ unsigned char *crust_t;
void test_function(unsigned char *param);
void test_function(crust_t __crust_borrow__ param); // this one must fail
#define NULL ((void *)0)
void main(crust_t __crust_borrow__ param) {
test_function(param); // this one must also fail
}
typedef __crust__ unsigned char *crust_t;
void test_function(crust_t __crust_borrow__ param);
void test_function(unsigned char *param); // this one must fail
#define NULL ((void *)0)
void main(crust_t __crust_borrow__ param) {
test_function(param); // this one must not fail
}
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