diff --git a/lib/cmock_generator_plugin_cexception.rb b/lib/cmock_generator_plugin_cexception.rb index b90ba59..232c5f1 100644 --- a/lib/cmock_generator_plugin_cexception.rb +++ b/lib/cmock_generator_plugin_cexception.rb @@ -29,7 +29,7 @@ class CMockGeneratorPluginCexception "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, CEXCEPTION_T cmock_to_throw);\n" else "#define #{function[:name]}_ExpectAndThrow(#{function[:args_call]}, cmock_to_throw) #{function[:name]}_CMockExpectAndThrow(__LINE__, #{function[:args_call]}, cmock_to_throw)\n" \ - "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, CEXCEPTION_T cmock_to_throw);\n" + "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, #{helper_args_string(function)}, CEXCEPTION_T cmock_to_throw);\n" end end @@ -40,11 +40,20 @@ class CMockGeneratorPluginCexception end def mock_interfaces(function) - arg_insert = function[:args_string] == 'void' ? '' : "#{function[:args_string]}, " + arg_insert = function[:args_string] == 'void' ? '' : "#{helper_args_string(function)}, " ["void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, #{arg_insert}CEXCEPTION_T cmock_to_throw)\n{\n", @utils.code_add_base_expectation(function[:name]), @utils.code_call_argument_loader(function), " cmock_call_instance->ExceptionToThrow = cmock_to_throw;\n", "}\n\n"].join end + + private + + def helper_args_string(function) + return function[:args_string] if function[:args_string] == 'void' + return function[:args_string] unless function[:args]&.any? { |m| m.is_a?(Hash) && m[:array_dims] } + + function[:args].map { |m| CMockGeneratorUtils.arg_declaration(m) }.join(', ') + end end diff --git a/lib/cmock_generator_plugin_expect.rb b/lib/cmock_generator_plugin_expect.rb index f4ada42..2255012 100644 --- a/lib/cmock_generator_plugin_expect.rb +++ b/lib/cmock_generator_plugin_expect.rb @@ -51,11 +51,11 @@ class CMockGeneratorPluginExpect elsif function[:return][:void?] lines << "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _Expect (not AndReturn)\");\n" if @error_stubs lines << "#define #{function[:name]}_Expect(#{function[:args_call]}) #{function[:name]}_CMockExpect(__LINE__, #{function[:args_call]})\n" - lines << "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]});\n" + lines << "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{helper_args_string(function)});\n" else lines << "#define #{function[:name]}_Expect(#{function[:args_call]}) TEST_FAIL_MESSAGE(\"#{function[:name]} requires _ExpectAndReturn\");\n" if @error_stubs lines << "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, #{function[:args_call]}, cmock_retval)\n" - lines << "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]});\n" + lines << "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{helper_args_string(function)}, #{function[:return][:str]});\n" end lines end @@ -86,12 +86,12 @@ class CMockGeneratorPluginExpect if function[:args_string] == 'void' "void #{func_name}_CMockExpect(UNITY_LINE_TYPE cmock_line)\n{\n" else - "void #{func_name}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]})\n{\n" + "void #{func_name}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{helper_args_string(function)})\n{\n" end elsif function[:args_string] == 'void' "void #{func_name}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n" else - "void #{func_name}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]})\n{\n" + "void #{func_name}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{helper_args_string(function)}, #{function[:return][:str]})\n{\n" end lines << " TEST_MESSAGE(\"CMock: #{func_name}_#{function[:return][:void?] ? 'Expect' : 'ExpectAndReturn'} called\");\n" if @debug_output lines << @utils.code_add_base_expectation(func_name) @@ -107,4 +107,17 @@ class CMockGeneratorPluginExpect " UNITY_TEST_FAIL(cmock_line, CMockStringCalledLess);\n" \ " }\n" end + + private + + # Build args string for generated _CMockExpect/_CMockExpectAndReturn helper signatures. + # Converts flat array parameters (e.g. POINT_T a[N]) to pointer notation (POINT_T* a) + # to avoid GCC -Wstringop-overflow, which treats static array sizes in function + # parameters as bounds hints and errors when callers pass smaller objects. + def helper_args_string(function) + return function[:args_string] if function[:args_string] == 'void' + return function[:args_string] unless function[:args]&.any? { |m| m.is_a?(Hash) && m[:array_dims] } + + function[:args].map { |m| CMockGeneratorUtils.arg_declaration(m) }.join(', ') + end end diff --git a/lib/cmock_generator_utils.rb b/lib/cmock_generator_utils.rb index d4547f8..edd7db7 100644 --- a/lib/cmock_generator_utils.rb +++ b/lib/cmock_generator_utils.rb @@ -43,11 +43,15 @@ class CMockGeneratorUtils base_type = arg_type_with_const(arg).sub(/\*$/, '').strip dims_str = arg[:array_dims].map { |d| "[#{d}]" }.join "#{base_type} (*#{arg[:name]})#{dims_str}" - elsif arg[:array_dims] + elsif arg[:array_dims] && arg[:array_dims].length > 1 + # Multi-dimensional array (e.g. int matrix[13][4]): must preserve trailing + # dimensions so the parameter type decays correctly (int (*)[4], not int*). base_type = arg_type_with_const(arg).sub(/\*$/, '').strip dims_str = arg[:array_dims].map { |d| "[#{d}]" }.join "#{base_type} #{arg[:name]}#{dims_str}" else + # Plain param or 1D array param: arg[:type] is already the pointer type + # (parser converts T name[N] -> T*), so arg_type_with_const gives T*. "#{arg_type_with_const(arg)} #{arg[:name]}" end end