Skip to content

Avoid Mimick argument matching for unconditional patches - #3221

Open
ukis666 wants to merge 1 commit into
ros2:rollingfrom
ukis666:fix/clang-function-pointer-warning-2488-clean
Open

Avoid Mimick argument matching for unconditional patches#3221
ukis666 wants to merge 1 commit into
ros2:rollingfrom
ukis666:fix/clang-function-pointer-warning-2488-clean

Conversation

@ukis666

@ukis666 ukis666 commented Aug 11, 2026

Copy link
Copy Markdown

Description

mocking_utils::Patch currently configures unconditional replacements through
mmk_when(..., mmk_any(...)). Although every argument is matched as ANY,
Mimick still instantiates its generic argument-comparison machinery.

For rcl_logging_configure_with_output_handler, one of the arguments is a
function pointer. With Clang, this causes ordered comparisons of function
pointers to be instantiated and triggers
-Wordered-compare-function-pointers.

This change removes the unconditional patch path from Mimick's generic argument
matcher and implements it using Mimick's public stub API:

  • mmk_stub_create()
  • mmk_stub_destroy()
  • MMK_STUB_INVALID

For non-self scopes, the patch installs a stub for both the scoped symbol and
the bare symbol in the test executable. This is required for calls originating
through header/template code, which may resolve through the executable rather
than the scoped library.

The implementation also preserves the existing safety properties of Patch:

  • failed stub installation is detected,
  • partially installed stubs are cleaned up,
  • repeated configuration is rejected,
  • stub handles are transferred correctly during moves,
  • installed stubs are destroyed through RAII.

Since the generic argument-matching path is no longer instantiated, the
Clang-specific diagnostic suppression in test_utilities.cpp is no longer
needed and has been removed.

Regression coverage was also added for the failure path and the
function-pointer callback case.

Fixes #2488

Is this user-facing behavior change?

No. This only changes the internal test mocking utility.

Did you use Generative AI?

Yes. GPT-5.6 Sol in Ultra mode was used to accelerate analysis, implementation iteration, and test/validation workflows.

Additional Information

The revised implementation was validated against a current ROS 2 Rolling source
build on Ubuntu 24.04 Noble.

Validation included:

  • ROS 2 Rolling built from source successfully (372 packages).
  • rclcpp, rclcpp_action, rclcpp_components, and rclcpp_lifecycle
    build successfully with both GCC 13.3.0 and Clang 18.1.3.
  • test_utilities passes with Clang and
    -Werror=ordered-compare-function-pointers.
  • Full GCC repository tests:
    3,167 passed, 0 failed, 529 skipped.
  • Full Clang repository tests:
    3,167 passed, 0 failed, 529 skipped.
  • A single-stub implementation exposed 9 affected test targets; the final
    dual-public-stub implementation passes all 9, as does a matched clean
    upstream control.
  • copyright, cpplint, lint_cmake, uncrustify, xmllint, and
    git diff --check pass.

No Mimick source code or unrelated ROS 2 packages were modified.

@ukis666
ukis666 marked this pull request as ready for review August 11, 2026 10:21
@mergify

mergify Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

Comment thread rclcpp/test/mocking_utils/patch.hpp Outdated
mmk_when(proxy_(any<ArgTs>()...), .then_call = type_erased_trampoline);
struct mmk_mock_options options {};
options.sentinel_ = 1;
mock_ = mmk_mock_create_internal(target_.c_str(), type_erased_trampoline, options);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a broken patch could never go unnoticed before.
the raw internal call sidesteps that safety net, i believe.
it can return an invalid handle, mock_ stays useless, and replace_with returns as if everything worked.
the consequence is nasty specifically because this is a test utility...

Comment thread rclcpp/test/mocking_utils/patch.hpp Outdated
mmk_when(proxy_(any<ArgTs>()...), .then_call = type_erased_trampoline);
struct mmk_mock_options options {};
options.sentinel_ = 1;
mock_ = mmk_mock_create_internal(target_.c_str(), type_erased_trampoline, options);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i do not think using internal methods and members are correct thing to do here. could it use public stub APIs instead of mmk_mock_create_internal especially with options.sentinel_?

@fujitatomoya

Copy link
Copy Markdown
Collaborator

Yes. Generative AI was used to assist with analysis and validation of the change.

can you disclose which AI tools and models are used to create this PR?

@fujitatomoya

Copy link
Copy Markdown
Collaborator

according to the test, i think we need to do the test with source build instead of released pacakges.
can you go through https://docs.ros.org/en/rolling//Get-Started/Installation/Alternatives/Ubuntu-Development-Setup.html to make sure all the tests are pass?

Replace the internal mock creation workaround with Mimick’s supported stub API. Install both scoped and self stubs to preserve existing call-site behavior, fail explicitly on installation errors, and avoid instantiating argument matchers for function-pointer arguments.

Remove the Clang diagnostic suppression and add regression coverage for installation failure and the function-pointer callback.

Signed-off-by: Ulaş <36420486+ukis666@users.noreply.github.com>
@ukis666
ukis666 force-pushed the fix/clang-function-pointer-warning-2488-clean branch from 6c36aa0 to 9b75d07 Compare September 4, 2026 06:25
@ukis666

ukis666 commented Sep 4, 2026

Copy link
Copy Markdown
Author

Thanks for the review. I reworked the implementation to address the requested changes.

The patch no longer uses mmk_mock_create_internal() or accesses internal Mimick members. It now uses the public stub API (mmk_stub_create(), mmk_stub_destroy(), and MMK_STUB_INVALID) while preserving failure detection and RAII cleanup.

I also repeated the validation using a current ROS 2 Rolling source build, rather than released packages. On Ubuntu 24.04 Noble, all 372 source packages built successfully. The rclcpp repository packages build and test cleanly with both GCC 13.3.0 and Clang 18.1.3, including test_utilities with -Werror=ordered-compare-function-pointers.

Full repository test results were 3,167 passed, 0 failed, 529 skipped with both GCC and Clang.

Regarding the AI disclosure: GPT-5.6 Sol in Ultra mode was used to accelerate analysis, implementation iteration, and test/validation workflows.

The PR description has been updated with the implementation and validation details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clang warning: ordered comparison of function pointers (Rolling)

2 participants