From ccabd4de891e749f472121497941bb9437b83c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Tue, 29 Jul 2025 23:51:13 +0200 Subject: [PATCH] Add enum types to what is captured by value by default As it turns out, enums can be used to declare bitfields, and we cannot form a reference to a bitfield in the cpature. Thus, we add `std::is_enum` as a criteria to the default for `capture_by_value`, so that enum-based bitfields are also captured by value and thus decomposable. Closes #3001 --- src/catch2/internal/catch_decomposer.hpp | 28 +++++++++++++------ .../Baselines/automake.sw.approved.txt | 1 + .../Baselines/automake.sw.multi.approved.txt | 1 + .../Baselines/compact.sw.approved.txt | 6 ++-- .../Baselines/compact.sw.multi.approved.txt | 6 ++-- .../Baselines/console.std.approved.txt | 4 +-- .../Baselines/console.sw.approved.txt | 20 +++++++++++-- .../Baselines/console.sw.multi.approved.txt | 20 +++++++++++-- .../Baselines/console.swa4.approved.txt | 20 +++++++++++-- .../SelfTest/Baselines/junit.sw.approved.txt | 3 +- .../Baselines/junit.sw.multi.approved.txt | 3 +- .../Baselines/sonarqube.sw.approved.txt | 1 + .../Baselines/sonarqube.sw.multi.approved.txt | 1 + tests/SelfTest/Baselines/tap.sw.approved.txt | 6 +++- .../Baselines/tap.sw.multi.approved.txt | 6 +++- .../Baselines/teamcity.sw.approved.txt | 2 ++ .../Baselines/teamcity.sw.multi.approved.txt | 2 ++ tests/SelfTest/Baselines/xml.sw.approved.txt | 23 +++++++++++++-- .../Baselines/xml.sw.multi.approved.txt | 23 +++++++++++++-- .../SelfTest/UsageTests/Compilation.tests.cpp | 17 +++++++++++ 20 files changed, 164 insertions(+), 29 deletions(-) diff --git a/src/catch2/internal/catch_decomposer.hpp b/src/catch2/internal/catch_decomposer.hpp index b6592c54..fcc017dd 100644 --- a/src/catch2/internal/catch_decomposer.hpp +++ b/src/catch2/internal/catch_decomposer.hpp @@ -78,10 +78,11 @@ * * 3) If a type has no linkage, we also cannot capture it by reference. * The solution is once again to capture them by value. We handle - * the common cases by using `std::is_arithmetic` as the default - * for `Catch::capture_by_value`, but that is only a some-effort - * heuristic. But as with 2), users can specialize `capture_by_value` - * for their own types as needed. + * the common cases by using `std::is_arithmetic` and `std::is_enum` + * as the default for `Catch::capture_by_value`, but that is only a + * some-effort heuristic. These combine to capture all possible bitfield + * bases, and also some trait-like types. As with 2), users can + * specialize `capture_by_value` for their own types as needed. * * 4) To support C++20 and make the SFINAE on our decomposing operators * work, the SFINAE has to happen in return type, rather than in @@ -133,13 +134,22 @@ namespace Catch { using RemoveCVRef_t = std::remove_cv_t>; } - // Note: There is nothing that stops us from extending this, - // e.g. to `std::is_scalar`, but the more encompassing - // traits are usually also more expensive. For now we - // keep this as it used to be and it can be changed later. + // Note: This is about as much as we can currently reasonably support. + // In an ideal world, we could capture by value small trivially + // copyable types, but the actual `std::is_trivially_copyable` + // trait is a huge mess with standard-violating results on + // GCC and Clang, which are unlikely to be fixed soon due to ABI + // concerns. + // `std::is_scalar` also causes issues due to the `is_pointer` + // component, which causes ambiguity issues with (references-to) + // function pointer. If those are resolved, we still need to + // disambiguate the overload set for arrays, through explicit + // overload for references to sized arrays. template struct capture_by_value - : std::integral_constant{}> {}; + : std::integral_constant::value || + std::is_enum::value> {}; #if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS ) template <> diff --git a/tests/SelfTest/Baselines/automake.sw.approved.txt b/tests/SelfTest/Baselines/automake.sw.approved.txt index 63420188..f04cd867 100644 --- a/tests/SelfTest/Baselines/automake.sw.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.approved.txt @@ -26,6 +26,7 @@ Nor would this :test-result: PASS #2152 - ULP checks between differently signed values were wrong - double :test-result: PASS #2152 - ULP checks between differently signed values were wrong - float :test-result: XFAIL #2615 - Throwing in constructor generator fails test case but does not abort +:test-result: PASS #3001: Enum-based bitfields can be captured :test-result: XFAIL #748 - captures with unexpected exceptions :test-result: PASS #809 :test-result: PASS #833 diff --git a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt index 21725c68..7da3c913 100644 --- a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt @@ -24,6 +24,7 @@ :test-result: PASS #2152 - ULP checks between differently signed values were wrong - double :test-result: PASS #2152 - ULP checks between differently signed values were wrong - float :test-result: XFAIL #2615 - Throwing in constructor generator fails test case but does not abort +:test-result: PASS #3001: Enum-based bitfields can be captured :test-result: XFAIL #748 - captures with unexpected exceptions :test-result: PASS #809 :test-result: PASS #833 diff --git a/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/SelfTest/Baselines/compact.sw.approved.txt index 84b00a50..fbf249c1 100644 --- a/tests/SelfTest/Baselines/compact.sw.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.approved.txt @@ -85,6 +85,8 @@ Matchers.tests.cpp:: passed: smallest_non_zero, !WithinULP( -smalle Matchers.tests.cpp:: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45]) Matchers.tests.cpp:: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00]) Generators.tests.cpp:: failed: unexpected exception with message: 'failure to init'; expression was: {Unknown expression after the reported line} +Compilation.tests.cpp:: passed: bf.e == 1 for: 1 == 1 +Compilation.tests.cpp:: passed: 1 == bf.e for: 1 == 1 Exception.tests.cpp:: failed: unexpected exception with message: 'expected exception'; expression was: {Unknown expression after the reported line} Exception.tests.cpp:: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception' Exception.tests.cpp:: passed: thisThrows() with 1 message: 'answer := 42' @@ -2869,7 +2871,7 @@ InternalBenchmark.tests.cpp:: passed: med == 18. for: 18.0 == 18.0 InternalBenchmark.tests.cpp:: passed: q3 == 23. for: 23.0 == 23.0 Misc.tests.cpp:: passed: Misc.tests.cpp:: passed: -test cases: 431 | 313 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2288 | 2090 passed | 157 failed | 41 failed as expected +test cases: 432 | 314 passed | 95 failed | 6 skipped | 17 failed as expected +assertions: 2290 | 2092 passed | 157 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt index dc500516..f0e75afa 100644 --- a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt @@ -83,6 +83,8 @@ Matchers.tests.cpp:: passed: smallest_non_zero, !WithinULP( -smalle Matchers.tests.cpp:: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45]) Matchers.tests.cpp:: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00]) Generators.tests.cpp:: failed: unexpected exception with message: 'failure to init'; expression was: {Unknown expression after the reported line} +Compilation.tests.cpp:: passed: bf.e == 1 for: 1 == 1 +Compilation.tests.cpp:: passed: 1 == bf.e for: 1 == 1 Exception.tests.cpp:: failed: unexpected exception with message: 'expected exception'; expression was: {Unknown expression after the reported line} Exception.tests.cpp:: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception' Exception.tests.cpp:: passed: thisThrows() with 1 message: 'answer := 42' @@ -2858,7 +2860,7 @@ InternalBenchmark.tests.cpp:: passed: med == 18. for: 18.0 == 18.0 InternalBenchmark.tests.cpp:: passed: q3 == 23. for: 23.0 == 23.0 Misc.tests.cpp:: passed: Misc.tests.cpp:: passed: -test cases: 431 | 313 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2288 | 2090 passed | 157 failed | 41 failed as expected +test cases: 432 | 314 passed | 95 failed | 6 skipped | 17 failed as expected +assertions: 2290 | 2092 passed | 157 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/console.std.approved.txt b/tests/SelfTest/Baselines/console.std.approved.txt index 96f43224..92d58aaa 100644 --- a/tests/SelfTest/Baselines/console.std.approved.txt +++ b/tests/SelfTest/Baselines/console.std.approved.txt @@ -1719,6 +1719,6 @@ due to unexpected exception with message: Why would you throw a std::string? =============================================================================== -test cases: 431 | 331 passed | 76 failed | 7 skipped | 17 failed as expected -assertions: 2267 | 2090 passed | 136 failed | 41 failed as expected +test cases: 432 | 332 passed | 76 failed | 7 skipped | 17 failed as expected +assertions: 2269 | 2092 passed | 136 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt index efb96e04..0bc35756 100644 --- a/tests/SelfTest/Baselines/console.sw.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.approved.txt @@ -772,6 +772,22 @@ Generators.tests.cpp:: FAILED: due to unexpected exception with message: failure to init +------------------------------------------------------------------------------- +#3001: Enum-based bitfields can be captured +------------------------------------------------------------------------------- +Compilation.tests.cpp: +............................................................................... + +Compilation.tests.cpp:: PASSED: + REQUIRE( bf.e == 1 ) +with expansion: + 1 == 1 + +Compilation.tests.cpp:: PASSED: + REQUIRE( 1 == bf.e ) +with expansion: + 1 == 1 + ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions outside assertions @@ -19184,6 +19200,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 431 | 313 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2288 | 2090 passed | 157 failed | 41 failed as expected +test cases: 432 | 314 passed | 95 failed | 6 skipped | 17 failed as expected +assertions: 2290 | 2092 passed | 157 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.multi.approved.txt b/tests/SelfTest/Baselines/console.sw.multi.approved.txt index 0a84798a..6d853f1b 100644 --- a/tests/SelfTest/Baselines/console.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.multi.approved.txt @@ -770,6 +770,22 @@ Generators.tests.cpp:: FAILED: due to unexpected exception with message: failure to init +------------------------------------------------------------------------------- +#3001: Enum-based bitfields can be captured +------------------------------------------------------------------------------- +Compilation.tests.cpp: +............................................................................... + +Compilation.tests.cpp:: PASSED: + REQUIRE( bf.e == 1 ) +with expansion: + 1 == 1 + +Compilation.tests.cpp:: PASSED: + REQUIRE( 1 == bf.e ) +with expansion: + 1 == 1 + ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions outside assertions @@ -19173,6 +19189,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 431 | 313 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2288 | 2090 passed | 157 failed | 41 failed as expected +test cases: 432 | 314 passed | 95 failed | 6 skipped | 17 failed as expected +assertions: 2290 | 2092 passed | 157 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/console.swa4.approved.txt b/tests/SelfTest/Baselines/console.swa4.approved.txt index c3a2676b..63fb2113 100644 --- a/tests/SelfTest/Baselines/console.swa4.approved.txt +++ b/tests/SelfTest/Baselines/console.swa4.approved.txt @@ -772,6 +772,22 @@ Generators.tests.cpp:: FAILED: due to unexpected exception with message: failure to init +------------------------------------------------------------------------------- +#3001: Enum-based bitfields can be captured +------------------------------------------------------------------------------- +Compilation.tests.cpp: +............................................................................... + +Compilation.tests.cpp:: PASSED: + REQUIRE( bf.e == 1 ) +with expansion: + 1 == 1 + +Compilation.tests.cpp:: PASSED: + REQUIRE( 1 == bf.e ) +with expansion: + 1 == 1 + ------------------------------------------------------------------------------- #748 - captures with unexpected exceptions outside assertions @@ -952,6 +968,6 @@ Condition.tests.cpp:: FAILED: CHECK( true != true ) =============================================================================== -test cases: 33 | 27 passed | 3 failed | 3 failed as expected -assertions: 102 | 94 passed | 4 failed | 4 failed as expected +test cases: 34 | 28 passed | 3 failed | 3 failed as expected +assertions: 104 | 96 passed | 4 failed | 4 failed as expected diff --git a/tests/SelfTest/Baselines/junit.sw.approved.txt b/tests/SelfTest/Baselines/junit.sw.approved.txt index 5c3af7bb..181c0809 100644 --- a/tests/SelfTest/Baselines/junit.sw.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -60,6 +60,7 @@ failure to init at Generators.tests.cpp: + diff --git a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt index 7b4563ff..8d90d575 100644 --- a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt @@ -1,6 +1,6 @@ - + @@ -59,6 +59,7 @@ failure to init at Generators.tests.cpp: + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt index b97312d2..fcc57d42 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt @@ -655,6 +655,7 @@ at Class.tests.cpp: + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt index 43493ebf..9afa17f1 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt @@ -654,6 +654,7 @@ at Class.tests.cpp: + diff --git a/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/SelfTest/Baselines/tap.sw.approved.txt index ed79ca8d..bd797da8 100644 --- a/tests/SelfTest/Baselines/tap.sw.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.approved.txt @@ -166,6 +166,10 @@ ok {test-number} - smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0. ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00]) # #2615 - Throwing in constructor generator fails test case but does not abort not ok {test-number} - unexpected exception with message: 'failure to init'; expression was: {Unknown expression after the reported line} +# #3001: Enum-based bitfields can be captured +ok {test-number} - bf.e == 1 for: 1 == 1 +# #3001: Enum-based bitfields can be captured +ok {test-number} - 1 == bf.e for: 1 == 1 # #748 - captures with unexpected exceptions not ok {test-number} - unexpected exception with message: 'expected exception'; expression was: {Unknown expression after the reported line} # #748 - captures with unexpected exceptions @@ -4597,5 +4601,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2300 +1..2302 diff --git a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt index 901b458a..9f2ec42c 100644 --- a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt @@ -164,6 +164,10 @@ ok {test-number} - smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0. ok {test-number} - smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00]) # #2615 - Throwing in constructor generator fails test case but does not abort not ok {test-number} - unexpected exception with message: 'failure to init'; expression was: {Unknown expression after the reported line} +# #3001: Enum-based bitfields can be captured +ok {test-number} - bf.e == 1 for: 1 == 1 +# #3001: Enum-based bitfields can be captured +ok {test-number} - 1 == bf.e for: 1 == 1 # #748 - captures with unexpected exceptions not ok {test-number} - unexpected exception with message: 'expected exception'; expression was: {Unknown expression after the reported line} # #748 - captures with unexpected exceptions @@ -4586,5 +4590,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2300 +1..2302 diff --git a/tests/SelfTest/Baselines/teamcity.sw.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.approved.txt index 87560b63..39bceb12 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.approved.txt @@ -55,6 +55,8 @@ ##teamcity[testStarted name='#2615 - Throwing in constructor generator fails test case but does not abort'] ##teamcity[testIgnored name='#2615 - Throwing in constructor generator fails test case but does not abort' message='Generators.tests.cpp:|n...............................................................................|n|nGenerators.tests.cpp:|nunexpected exception with message:|n "failure to init"|n {Unknown expression after the reported line}|nwith expansion:|n {Unknown expression after the reported line}|n- failure ignore as test marked as |'ok to fail|'|n'] ##teamcity[testFinished name='#2615 - Throwing in constructor generator fails test case but does not abort' duration="{duration}"] +##teamcity[testStarted name='#3001: Enum-based bitfields can be captured'] +##teamcity[testFinished name='#3001: Enum-based bitfields can be captured' duration="{duration}"] ##teamcity[testStarted name='#748 - captures with unexpected exceptions'] ##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|noutside assertions|n-------------------------------------------------------------------------------|nException.tests.cpp:|n...............................................................................|n|nException.tests.cpp:|nunexpected exception with message:|n "expected exception"|n {Unknown expression after the reported line}|nwith expansion:|n {Unknown expression after the reported line}|n- failure ignore as test marked as |'ok to fail|'|n'] ##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|ninside REQUIRE_NOTHROW|n-------------------------------------------------------------------------------|nException.tests.cpp:|n...............................................................................|n|nException.tests.cpp:|nunexpected exception with messages:|n "answer := 42"|n "expected exception"|n REQUIRE_NOTHROW( thisThrows() )|nwith expansion:|n thisThrows()|n- failure ignore as test marked as |'ok to fail|'|n'] diff --git a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt index 228deda4..e9b5fee9 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt @@ -55,6 +55,8 @@ ##teamcity[testStarted name='#2615 - Throwing in constructor generator fails test case but does not abort'] ##teamcity[testIgnored name='#2615 - Throwing in constructor generator fails test case but does not abort' message='Generators.tests.cpp:|n...............................................................................|n|nGenerators.tests.cpp:|nunexpected exception with message:|n "failure to init"|n {Unknown expression after the reported line}|nwith expansion:|n {Unknown expression after the reported line}|n- failure ignore as test marked as |'ok to fail|'|n'] ##teamcity[testFinished name='#2615 - Throwing in constructor generator fails test case but does not abort' duration="{duration}"] +##teamcity[testStarted name='#3001: Enum-based bitfields can be captured'] +##teamcity[testFinished name='#3001: Enum-based bitfields can be captured' duration="{duration}"] ##teamcity[testStarted name='#748 - captures with unexpected exceptions'] ##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|noutside assertions|n-------------------------------------------------------------------------------|nException.tests.cpp:|n...............................................................................|n|nException.tests.cpp:|nunexpected exception with message:|n "expected exception"|n {Unknown expression after the reported line}|nwith expansion:|n {Unknown expression after the reported line}|n- failure ignore as test marked as |'ok to fail|'|n'] ##teamcity[testIgnored name='#748 - captures with unexpected exceptions' message='-------------------------------------------------------------------------------|ninside REQUIRE_NOTHROW|n-------------------------------------------------------------------------------|nException.tests.cpp:|n...............................................................................|n|nException.tests.cpp:|nunexpected exception with messages:|n "answer := 42"|n "expected exception"|n REQUIRE_NOTHROW( thisThrows() )|nwith expansion:|n thisThrows()|n- failure ignore as test marked as |'ok to fail|'|n'] diff --git a/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/SelfTest/Baselines/xml.sw.approved.txt index f5433e33..44cd5fc3 100644 --- a/tests/SelfTest/Baselines/xml.sw.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.approved.txt @@ -681,6 +681,25 @@ Nor would this + + + + bf.e == 1 + + + 1 == 1 + + + + + 1 == bf.e + + + 1 == 1 + + + +
@@ -22182,6 +22201,6 @@ Approx( -1.95996398454005449 )
- - + + diff --git a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt index cfbbe39b..6e4a78b7 100644 --- a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt @@ -681,6 +681,25 @@ Nor would this
+ + + + bf.e == 1 + + + 1 == 1 + + + + + 1 == bf.e + + + 1 == 1 + + + +
@@ -22181,6 +22200,6 @@ Approx( -1.95996398454005449 )
- - + + diff --git a/tests/SelfTest/UsageTests/Compilation.tests.cpp b/tests/SelfTest/UsageTests/Compilation.tests.cpp index 7a6a1f25..d8813353 100644 --- a/tests/SelfTest/UsageTests/Compilation.tests.cpp +++ b/tests/SelfTest/UsageTests/Compilation.tests.cpp @@ -144,6 +144,23 @@ TEST_CASE("#1027: Bitfields can be captured") { REQUIRE(0 == y.v); } +TEST_CASE( "#3001: Enum-based bitfields can be captured" ) { + enum E { + ZERO = 0, + ONE = 1, + TWO = 2, + }; + + struct BF { + E e : 2; + }; + + BF bf{}; + bf.e = ONE; + REQUIRE( bf.e == 1 ); + REQUIRE( 1 == bf.e ); +} + // Comparison operators can return non-booleans. // This is unusual, but should be supported. TEST_CASE("#1147") {