Coverage tests for remaining TerminatorKinds and async, improve Assert
Tested and validate results for panic unwind, panic abort, assert!()
macro, TerminatorKind::Assert (for example, numeric overflow), and
async/await.
Implemented a previous documented idea to change Assert handling to be
the same as FalseUnwind and Goto, so it doesn't get its own
BasicCoverageBlock anymore. This changed a couple of coverage regions,
but I validated those changes are not any worse than the prior results,
and probably help assure some consistency (even if some people might
disagree with how the code region is consistently computed).
Fixed issue with async/await. AggregateKind::Generator needs to be
handled like AggregateKind::Closure; coverage span for the outer async
function should not "cover" the async body, which is actually executed
in a separate "closure" MIR.
2020-11-16 11:14:28 -06:00
|
|
|
#![allow(unused_assignments)]
|
|
|
|
|
2021-06-08 13:23:58 -05:00
|
|
|
extern "C" fn might_abort(should_abort: bool) {
|
Coverage tests for remaining TerminatorKinds and async, improve Assert
Tested and validate results for panic unwind, panic abort, assert!()
macro, TerminatorKind::Assert (for example, numeric overflow), and
async/await.
Implemented a previous documented idea to change Assert handling to be
the same as FalseUnwind and Goto, so it doesn't get its own
BasicCoverageBlock anymore. This changed a couple of coverage regions,
but I validated those changes are not any worse than the prior results,
and probably help assure some consistency (even if some people might
disagree with how the code region is consistently computed).
Fixed issue with async/await. AggregateKind::Generator needs to be
handled like AggregateKind::Closure; coverage span for the outer async
function should not "cover" the async body, which is actually executed
in a separate "closure" MIR.
2020-11-16 11:14:28 -06:00
|
|
|
if should_abort {
|
|
|
|
println!("aborting...");
|
|
|
|
panic!("panics and aborts");
|
|
|
|
} else {
|
|
|
|
println!("Don't Panic");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-15 20:40:01 -06:00
|
|
|
#[rustfmt::skip]
|
2020-12-01 01:58:08 -06:00
|
|
|
fn main() -> Result<(), u8> {
|
Coverage tests for remaining TerminatorKinds and async, improve Assert
Tested and validate results for panic unwind, panic abort, assert!()
macro, TerminatorKind::Assert (for example, numeric overflow), and
async/await.
Implemented a previous documented idea to change Assert handling to be
the same as FalseUnwind and Goto, so it doesn't get its own
BasicCoverageBlock anymore. This changed a couple of coverage regions,
but I validated those changes are not any worse than the prior results,
and probably help assure some consistency (even if some people might
disagree with how the code region is consistently computed).
Fixed issue with async/await. AggregateKind::Generator needs to be
handled like AggregateKind::Closure; coverage span for the outer async
function should not "cover" the async body, which is actually executed
in a separate "closure" MIR.
2020-11-16 11:14:28 -06:00
|
|
|
let mut countdown = 10;
|
|
|
|
while countdown > 0 {
|
|
|
|
if countdown < 5 {
|
|
|
|
might_abort(false);
|
|
|
|
}
|
2020-12-01 01:58:08 -06:00
|
|
|
// See discussion (below the `Notes` section) on coverage results for the closing brace.
|
2021-08-04 09:43:28 -05:00
|
|
|
if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
|
2020-12-01 01:58:08 -06:00
|
|
|
// For the following example, the closing brace is the last character on the line.
|
|
|
|
// This shows the character after the closing brace is highlighted, even if that next
|
|
|
|
// character is a newline.
|
2021-08-04 09:43:28 -05:00
|
|
|
if countdown < 5 { might_abort(false); }
|
Coverage tests for remaining TerminatorKinds and async, improve Assert
Tested and validate results for panic unwind, panic abort, assert!()
macro, TerminatorKind::Assert (for example, numeric overflow), and
async/await.
Implemented a previous documented idea to change Assert handling to be
the same as FalseUnwind and Goto, so it doesn't get its own
BasicCoverageBlock anymore. This changed a couple of coverage regions,
but I validated those changes are not any worse than the prior results,
and probably help assure some consistency (even if some people might
disagree with how the code region is consistently computed).
Fixed issue with async/await. AggregateKind::Generator needs to be
handled like AggregateKind::Closure; coverage span for the outer async
function should not "cover" the async body, which is actually executed
in a separate "closure" MIR.
2020-11-16 11:14:28 -06:00
|
|
|
countdown -= 1;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Notes:
|
|
|
|
// 1. Compare this program and its coverage results to those of the similar tests
|
|
|
|
// `panic_unwind.rs` and `try_error_result.rs`.
|
2023-04-05 03:17:40 -05:00
|
|
|
// 2. This test confirms the coverage generated when a program includes `UnwindAction::Terminate`.
|
Coverage tests for remaining TerminatorKinds and async, improve Assert
Tested and validate results for panic unwind, panic abort, assert!()
macro, TerminatorKind::Assert (for example, numeric overflow), and
async/await.
Implemented a previous documented idea to change Assert handling to be
the same as FalseUnwind and Goto, so it doesn't get its own
BasicCoverageBlock anymore. This changed a couple of coverage regions,
but I validated those changes are not any worse than the prior results,
and probably help assure some consistency (even if some people might
disagree with how the code region is consistently computed).
Fixed issue with async/await. AggregateKind::Generator needs to be
handled like AggregateKind::Closure; coverage span for the outer async
function should not "cover" the async body, which is actually executed
in a separate "closure" MIR.
2020-11-16 11:14:28 -06:00
|
|
|
// 3. The test does not invoke the abort. By executing to a successful completion, the coverage
|
|
|
|
// results show where the program did and did not execute.
|
|
|
|
// 4. If the program actually aborted, the coverage counters would not be saved (which "works as
|
|
|
|
// intended"). Coverage results would show no executed coverage regions.
|
|
|
|
// 6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
|
|
|
|
// (on Linux at least).
|
2020-12-01 01:58:08 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Expect the following coverage results:
|
|
|
|
|
|
|
|
```text
|
|
|
|
16| 11| while countdown > 0 {
|
|
|
|
17| 10| if countdown < 5 {
|
|
|
|
18| 4| might_abort(false);
|
|
|
|
19| 6| }
|
|
|
|
```
|
|
|
|
|
|
|
|
This is actually correct.
|
|
|
|
|
|
|
|
The condition `countdown < 5` executed 10 times (10 loop iterations).
|
|
|
|
|
|
|
|
It evaluated to `true` 4 times, and executed the `might_abort()` call.
|
|
|
|
|
|
|
|
It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
|
|
|
|
`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
|
|
|
|
closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
|
|
|
|
non-true condition.
|
|
|
|
|
|
|
|
As another example of why this is important, say the condition was `countdown < 50`, which is always
|
|
|
|
`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
|
|
|
|
The closing brace would have a count of `0`, highlighting the missed coverage.
|
|
|
|
*/
|