Using `REQUIRE` in a destructor breaks tests
- Dominant language
- C++
- Stars
- 21.5k
- Forks
- 3.5k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 2
Description
**Describe the bug**
This example (where the destructor of an object during unwind has a failing `CHECK`) works gracefully:
```cpp
#include
struct Guard {
~Guard() {
CHECK(3 == 4);
}
};
TEST_CASE("throwing into check") {
Guard g;
throw std::runtime_error("hi");
}
```
I get output like:
```
-------------------------------------------------------------------------------
throwing into check
-------------------------------------------------------------------------------
catch-throw.cxx:9
...............................................................................
catch-throw.cxx:5: FAILED:
CHECK( 3 == 4 )
catch-throw.cxx:5: FAILED:
{Unknown expression after the reported line}
due to unexpected exception with message:
hi
```
But this version (changing the `CHECK` for a `REQUIRE`):
```cpp
#include
struct Guard {
~Guard() {
REQUIRE(3 == 4);
}
};
TEST_CASE("throwing into require") {
Guard g;
throw std::runtime_error("hi");
}
```
explodes:
```
-------------------------------------------------------------------------------
throwing into require
-------------------------------------------------------------------------------
catch-throw.cxx:9
...............................................................................
catch-throw.cxx:5: FAILED:
REQUIRE( 3 == 4 )
terminate called after throwing an instance of 'Catch::TestFailureException'
catch-throw.cxx:5: FAILED:
{Unknown expression after the reported line}
due to a fatal error condition:
SIGABRT - Abort (abnormal termination) signal
===============================================================================
test cases: 1 | 1 failed
assertions: 2 | 2 failed
```
**Expected behavior**
I'd expect the `CHECK` and `REQUIRE` cases to behave similarly. In this case the test is already halting due to the throw, so it should not halt even harder. Replace the `throw` with a _passing_ `CHECK`, and the test still aborts, rather than gracefully failing.
**Reproduction steps**
The above are two complete test cases. Just compile and run (linking against both `libCatch2.a` and `libCatch2Main.a`
**Platform information:**
Catch 3.3.1.
This was using gcc 11 C++17 with the old ABI (`-D_GLIBCXX_USE_CXX11_ABI=0`).
Contributor guide
Research direction
Start by compiling and running the two complete reproductions using the Catch test macros, linked against libCatch2.a and libCatch2Main.a, with the reported GCC 11/C++17 settings. Compare CHECK and REQUIRE during destructor unwinding; done means the REQUIRE case no longer aborts unexpectedly and behaves consistently with the CHECK case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100