Skip to content

Conversation

Szapi
Copy link
Contributor

@Szapi Szapi commented Jul 24, 2025

Description

Forbid deducing reference types for m_predicate in FilterGenerator to prevent dangling references.
This is needed for out-of-line predicates to work correctly instead of undefined behavior or crashes.

GitHub Issues

Closes #3002

Copy link

codecov bot commented Jul 24, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.93%. Comparing base (582200a) to head (76862dc).
⚠️ Report is 1 commits behind head on devel.

Additional details and impacted files
@@            Coverage Diff             @@
##            devel    #3005      +/-   ##
==========================================
- Coverage   90.97%   90.93%   -0.03%     
==========================================
  Files         201      201              
  Lines        8681     8681              
==========================================
- Hits         7897     7894       -3     
- Misses        784      787       +3     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@horenmar
Copy link
Member

horenmar commented Aug 8, 2025

Thanks, this is useful change.

To avoid splitting the discussion into two places, I am gonna comment on the issue here instead.

  • The reproducer does not compile, you cannot have || or && in assertion.
  • The issue is real. The lifetime of the lambda that creates the generator ends before the generator's lifetime does, which means that if the generator takes a reference to its capture (the way filter currently does with the predicate), it will be a dead reference.
  • The test in this PR is a bit lacking. The behaviour you've observed was caused by the difference in stack layout/usage between difference compilers and configurations. A better test would be to create the generator in a function, and then call different function between calls to next, to overwrite the stack memory.

@@ -91,7 +92,7 @@ namespace Generators {

template <typename T, typename Predicate>
GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, Predicate>>(CATCH_FORWARD(pred), CATCH_MOVE(generator)));
return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, typename std::remove_reference<Predicate>::type>>(CATCH_FORWARD(pred), CATCH_MOVE(generator)));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, typename std::remove_reference<Predicate>::type>>(CATCH_FORWARD(pred), CATCH_MOVE(generator)));
return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, typename std::remove_reference_t<Predicate>>>(CATCH_FORWARD(pred), CATCH_MOVE(generator)));

@horenmar horenmar merged commit 85c4bad into catchorg:devel Aug 23, 2025
84 checks passed
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.

Possible undefined behavior with filter generator
2 participants