From 2568a3657f6bd717d321f8d6679c140bcb506d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Mon, 25 May 2020 07:38:34 +0100 Subject: [PATCH 1/3] return_thru_ptr: fix Wsign-conversion warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compiling a source base / test with Wsign-conversion enabled, gives the following warning: build/test/mocks/mock_logMessages.c: In function ‘countLogMessages’: build/test/mocks/mock_logMessages.c:749:26: warning: conversion to ‘size_t’ {aka ‘long unsigned int’} from ‘int’ may change the sign of the result [-Wsign-conversion] 749 | cmock_call_instance->ReturnThruPtr_fileIn_Size); | ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ The ReturnThruPtr_XXX_Size is used as argument to a call to memcpy(), which expects size_t (unsigned) for a good reason. The size leading to this call is being determined using sizeof(), so there appears no reason to ever convert this to (signed) int. Stop converting size_t to int, and thereby fix the compiler warning. Signed-off-by: André Draszik --- lib/cmock_generator_plugin_return_thru_ptr.rb | 8 ++++---- test/unit/cmock_generator_plugin_return_thru_ptr_test.rb | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/cmock_generator_plugin_return_thru_ptr.rb b/lib/cmock_generator_plugin_return_thru_ptr.rb index 9321559..96b2003 100644 --- a/lib/cmock_generator_plugin_return_thru_ptr.rb +++ b/lib/cmock_generator_plugin_return_thru_ptr.rb @@ -14,7 +14,7 @@ class CMockGeneratorPluginReturnThruPtr lines << " char ReturnThruPtr_#{arg[:name]}_Used;\n" lines << " #{arg[:type]} ReturnThruPtr_#{arg[:name]}_Val;\n" - lines << " int ReturnThruPtr_#{arg[:name]}_Size;\n" + lines << " size_t ReturnThruPtr_#{arg[:name]}_Size;\n" end lines end @@ -33,10 +33,10 @@ class CMockGeneratorPluginReturnThruPtr " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n" end lines << "#define #{function[:name]}_ReturnArrayThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_len)" - lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, (int)(cmock_len * (int)sizeof(*#{arg[:name]})))\n" + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_len * sizeof(*#{arg[:name]}))\n" lines << "#define #{function[:name]}_ReturnMemThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_size)" lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_size)\n" - lines << "void #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg[:name]}, int cmock_size);\n" + lines << "void #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg[:name]}, size_t cmock_size);\n" end lines end @@ -48,7 +48,7 @@ class CMockGeneratorPluginReturnThruPtr arg_name = arg[:name] next unless @utils.ptr_or_str?(arg[:type]) && !(arg[:const?]) - lines << "void #{func_name}_CMockReturnMemThruPtr_#{arg_name}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg_name}, int cmock_size)\n" + lines << "void #{func_name}_CMockReturnMemThruPtr_#{arg_name}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg_name}, size_t cmock_size)\n" lines << "{\n" lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " \ "(CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n" diff --git a/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb b/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb index 3c8b075..03fc5e4 100644 --- a/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb +++ b/test/unit/cmock_generator_plugin_return_thru_ptr_test.rb @@ -73,7 +73,7 @@ describe CMockGeneratorPluginReturnThruPtr, "Verify CMockGeneratorPluginReturnTh complex_func_expect() expected = " char ReturnThruPtr_tofu_Used;\n" + " int* ReturnThruPtr_tofu_Val;\n" + - " int ReturnThruPtr_tofu_Size;\n" + " size_t ReturnThruPtr_tofu_Size;\n" returned = @cmock_generator_plugin_return_thru_ptr.instance_typedefs(@complex_func) assert_equal(expected, returned) end @@ -91,10 +91,10 @@ describe CMockGeneratorPluginReturnThruPtr, "Verify CMockGeneratorPluginReturnTh "#define Pine_ReturnThruPtr_tofu(tofu)" + " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, sizeof(int))\n" + "#define Pine_ReturnArrayThruPtr_tofu(tofu, cmock_len)" + - " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, (int)(cmock_len * (int)sizeof(*tofu)))\n" + + " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, cmock_len * sizeof(*tofu))\n" + "#define Pine_ReturnMemThruPtr_tofu(tofu, cmock_size)" + " Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, cmock_size)\n" + - "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size);\n" + "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, size_t cmock_size);\n" returned = @cmock_generator_plugin_return_thru_ptr.mock_function_declarations(@complex_func) assert_equal(expected, returned) @@ -104,7 +104,7 @@ describe CMockGeneratorPluginReturnThruPtr, "Verify CMockGeneratorPluginReturnTh complex_func_expect(); expected = - "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size)\n" + + "void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, size_t cmock_size)\n" + "{\n" + " CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " + "(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" + From 7ee27d68912a36da1b04f7672995331c756ccb63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Mon, 25 May 2020 08:11:25 +0100 Subject: [PATCH 2/3] cmock: annotate pure & const APIs (fix Wsuggest-attribute= warnings) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC (& Clang) have the notion of pure and const functions [1], where those attributes are intended to help the optimiser. Annotate a few APIs here with the appropriate key words, which also fixes Wsuggest-attribute=pure and Wsuggest-attribute=const warnings, which a source base might have enabled: .../src/cmock.c: In function ‘CMock_Guts_MemNext’: .../src/cmock.c:118:22: warning: function might be candidate for attribute ‘pure’ [-Wsuggest-attribute=pure] 118 | CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index) | ^~~~~~~~~~~~~~~~~~ .../src/cmock.c: In function ‘CMock_Guts_MemEndOfChain’: .../src/cmock.c:140:22: warning: function might be candidate for attribute ‘pure’ if it is known to return normally [-Wsuggest-attribute=pure] 140 | CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) | ^~~~~~~~~~~~~~~~~~~~~~~~ .../src/cmock.c: In function ‘CMock_Guts_GetAddressFor’: .../src/cmock.c:158:7: warning: function might be candidate for attribute ‘pure’ [-Wsuggest-attribute=pure] 158 | void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index) | ^~~~~~~~~~~~~~~~~~~~~~~~ .../src/cmock.c: In function ‘CMock_Guts_MemBytesCapacity’: .../src/cmock.c:173:22: warning: function might be candidate for attribute ‘const’ [-Wsuggest-attribute=const] 173 | CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ .../src/cmock.c: In function ‘CMock_Guts_MemBytesFree’: .../src/cmock.c:181:22: warning: function might be candidate for attribute ‘pure’ [-Wsuggest-attribute=pure] 181 | CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void) | ^~~~~~~~~~~~~~~~~~~~~~~ .../src/cmock.c: In function ‘CMock_Guts_MemBytesUsed’: .../src/cmock.c:189:22: warning: function might be candidate for attribute ‘pure’ [-Wsuggest-attribute=pure] 189 | CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void) | ^~~~~~~~~~~~~~~~~~~~~~~ [1] https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html Signed-off-by: André Draszik --- src/cmock.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cmock.h b/src/cmock.h index 21123e9..027a12f 100644 --- a/src/cmock.h +++ b/src/cmock.h @@ -22,19 +22,25 @@ #define CMOCK_GUTS_NONE (0) +#if defined __GNUC__ +# define CMOCK_FUNCTION_ATTR(a) __attribute__((a)) +#else +# define CMOCK_FUNCTION_ATTR(a) /* ignore */ +#endif + /*------------------------------------------------------- * Memory API *-------------------------------------------------------*/ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size); CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index); -CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index); -CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index) CMOCK_FUNCTION_ATTR(pure); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) CMOCK_FUNCTION_ATTR(pure); -void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index); +void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index) CMOCK_FUNCTION_ATTR(pure); -CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void); -CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void); -CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void) CMOCK_FUNCTION_ATTR(const); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void) CMOCK_FUNCTION_ATTR(pure); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void) CMOCK_FUNCTION_ATTR(pure); void CMock_Guts_MemFreeAll(void); void CMock_Guts_MemFreeFinal(void); From ec6fa2c516b168f7bb6650ed8e5356cb0a4cb209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Mon, 25 May 2020 16:34:29 +0100 Subject: [PATCH 3/3] Revert "drop unnecessary prototype (immediately before definition)" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 7fbeb4096535550af8ff74308107e805088de2d5. This causes compilation warnings / errors when a project uses -Wmissing-prototypes compilation flags for safety reasons: .../test/mocks/mock_logMessages.c:685:6: warning: no previous prototype for ‘CMockExpectParameters_log_message’ [-Wmissing-prototypes] 685 | void CMockExpectParameters_log_message(CMOCK_log_message_CALL_INSTANCE* cmock_call_instance, const char* logMessage, int messageID, severity_t severityIn) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ etc. Signed-off-by: André Draszik --- lib/cmock_generator_utils.rb | 6 ++++-- test/unit/cmock_generator_utils_test.rb | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/cmock_generator_utils.rb b/lib/cmock_generator_utils.rb index 11225d6..27a46f7 100644 --- a/lib/cmock_generator_utils.rb +++ b/lib/cmock_generator_utils.rb @@ -86,11 +86,13 @@ class CMockGeneratorUtils type = arg_type_with_const(m) m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}" end.join(', ') - "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string})\n{\n" + + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string});\n" \ + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string})\n{\n" + function[:args].inject('') { |all, arg| all + code_add_an_arg_expectation(arg, (arg[:ptr?] ? "#{arg[:name]}_Depth" : 1)) } + "}\n\n" else - "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]})\n{\n" + + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]});\n" \ + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]})\n{\n" + function[:args].inject('') { |all, arg| all + code_add_an_arg_expectation(arg) } + "}\n\n" end diff --git a/test/unit/cmock_generator_utils_test.rb b/test/unit/cmock_generator_utils_test.rb index ab9df2a..8c3f0be 100644 --- a/test/unit/cmock_generator_utils_test.rb +++ b/test/unit/cmock_generator_utils_test.rb @@ -153,7 +153,8 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do :args_string => "stuff", :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] } - expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff)\n{\n" + + expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff);\n" + + "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff)\n{\n" + " cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" + " memcpy((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType),\n" + " sizeof(MY_TYPE[sizeof(MyMyType) == sizeof(MY_TYPE) ? 1 : -1])); /* add MY_TYPE to :treat_as_array if this causes an error */\n" + @@ -167,7 +168,8 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do :args_string => "stuff", :args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]] } - expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr)\n{\n" + + expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr);\n" + + "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr)\n{\n" + " cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" + " cmock_call_instance->Expected_MyIntPtr_Depth = MyIntPtr_Depth;\n" + " cmock_call_instance->IgnoreArg_MyIntPtr = 0;\n" + @@ -186,7 +188,8 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do :args_string => "stuff", :args => [test_arg[:const_ptr], test_arg[:double_ptr]] } - expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* const MyConstPtr, int MyConstPtr_Depth, int const** MyDoublePtr, int MyDoublePtr_Depth)\n{\n" + + expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* const MyConstPtr, int MyConstPtr_Depth, int const** MyDoublePtr, int MyDoublePtr_Depth);\n" + + "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* const MyConstPtr, int MyConstPtr_Depth, int const** MyDoublePtr, int MyDoublePtr_Depth)\n{\n" + " cmock_call_instance->Expected_MyConstPtr = MyConstPtr;\n" + " cmock_call_instance->Expected_MyConstPtr_Depth = MyConstPtr_Depth;\n" + " cmock_call_instance->IgnoreArg_MyConstPtr = 0;\n" +