...
 
Commits (2)
# History of versions #
* version 0.5 (2018-10-01)
* Only checks function declarations in external files if their definition is in the current file
* version 0.4 (2018-09-27)
* Forbides to define functions with empty parameters list; they must have, in case they don't need parameters, 'void'
* Forbides to define functions with empty parameters list; they must have, in case they don't need parameters, 'void'
* version 0.3 (2018-08-25)
* Allows to generate the *crust.h* file just calling crust, instead of having to copy it from elsewhere
* Allows to generate the *crust.h* file just calling crust, instead of having to copy it from elsewhere
* version 0.2 (2018-08-23)
* First public version
* First public version
......@@ -650,6 +650,7 @@ class crust(crust_helpers):
self._add_builtin_function(thread_status, "__builtin_bswap64", "uint64_t", ["uint64_t"])
self._add_builtin_function(thread_status, "__builtin_clz", "int", ["unsigned int"])
function_list = []
# First fill all the global variables and the function declarations
for node in tree:
if (node.type == "TYPE_SPECIFIER"):
......@@ -682,8 +683,9 @@ class crust(crust_helpers):
continue
if parameter.t_crust_recycle:
counter += 1
if (node.function_params is None) or (len(node.function_params) == 0):
self._add_error({"debug_level": 0}, self.MSG_ERROR, "Function '{:s}' at line {:d} has no parameters (must have 'void' inside the parentheses)", node.name, node.line)
if (node.type == "FUNCTION_DEFINITION") and (node.filename == filename):
# add only the functions defined in this file, to check their declarations in other files
function_list.append(node.name)
if counter > 1:
self._add_error(thread_status, self.MSG_CRITICAL, "The function '{:s}', at line {:d}, has more than one RECYCLE argument", node.name, node.line)
if (counter != 0) and (not self._check_statement_is_crust(node.return_value[0])):
......@@ -731,6 +733,17 @@ class crust(crust_helpers):
if node.type == "CRUST_DEBUG":
self._do_debug(thread_status)
continue
# Check for functions that have no parameters
for node in tree:
if (node.type != "FUNCTION_DECLARATION") and (node.type != "FUNCTION_DEFINITION"):
continue
if (node.name in function_list) or (node.filename == filename):
# if a definition or declaration is in this file, or if the declaration is in another file but the definition is here, check if it has no parameters
if (node.function_params is None) or (len(node.function_params) == 0):
if node.filename == filename:
self._add_error({"debug_level": 0}, self.MSG_ERROR, "Function '{:s}' at line {:d} has no parameters (must have 'void' inside the parentheses)", node.name, node.line)
else:
self._add_error({"debug_level": 0}, self.MSG_ERROR, "Function '{:s}' at line {:d} in file '{:s}' has no parameters (must have 'void' inside the parentheses)", node.name, node.line, node.filename)
return thread_status
......
......@@ -19,7 +19,7 @@
class crust_definitions(object):
version = "0.4"
version = "0.5"
# when a variable hasn't been assigned yet
VALUE_UNINITIALIZED = 0
......
......@@ -1024,6 +1024,9 @@ class Test(unittest.TestCase):
def test250NoVoidOnEmptyParameterFunctionDefinition(self):
self._generic_test("unitest/test250.c", [ (crust.crust.MSG_ERROR, "Function '{:s}' at line {:d} has no parameters (must have 'void' inside the parentheses)", 'function', 9) ])
def test251NoVoidOnEmptyParameterFunctionAndDefinitionInHeader(self):
self._generic_test("unitest/test251.c", [ (crust.crust.MSG_ERROR, "Function '{:s}' at line {:d} in file '{:s}' has no parameters (must have 'void' inside the parentheses)", 'function', 4, 'unitest/test251.h'), (crust.crust.MSG_ERROR, "Function '{:s}' at line {:d} has no parameters (must have 'void' inside the parentheses)", 'function', 12) ])
if __name__ == '__main__':
try:
os.remove("error_list.txt")
......
// not allowed: C doesn't check that calls to functions without parameters honors the signature
// Thus, it is possible to call this function with several parameters, or assign it to a pointer
// to function with any type and number of parameters.
// To avoid this, it is a must to add "void" inside the parameter list;
// this is, the right definition is:
// int function(void) {}
// and also in the declaration in test251.h
#include "test251.h"
void function() {
}
\ No newline at end of file
// this declaration will trigger an error because, although it is outside the file being analyzed,
// the function definition IS in the analyzed file
void function();
\ No newline at end of file