Commit a9d92528 authored by Sergio Costas's avatar Sergio Costas

Now only reports missing void in header files when the definition is in the C file

parent 26fa406c
......@@ -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
......
......@@ -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
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