Repository navigation
Fix assert!() and panic!() code generation #687
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
56f2aae
1822891
8cf30c2
10cf2f1
c7d12d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ | |
| //! It would be too nasty if we spread around these sort of undocumented hooks in place, so | ||
| //! this module addresses this issue. | ||
|
|
||
| use crate::utils::{instance_name_is, instance_name_starts_with}; | ||
| use crate::utils::instance_name_starts_with; | ||
| use crate::GotocCtx; | ||
| use cbmc::goto_program::{BuiltinFn, Expr, Location, Stmt, Symbol, Type}; | ||
| use cbmc::NO_PRETTY_NAME; | ||
|
|
@@ -197,9 +197,11 @@ struct Panic; | |
|
|
||
| impl<'tcx> GotocHook<'tcx> for Panic { | ||
| fn hook_applies(&self, tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool { | ||
| output_of_instance_is_never(tcx, instance) | ||
| && (instance_name_is(tcx, instance, "begin_panic") | ||
| || instance_name_is(tcx, instance, "panic")) | ||
| let def_id = instance.def.def_id(); | ||
| Some(def_id) == tcx.lang_items().panic_fn() | ||
| || Some(def_id) == tcx.lang_items().panic_display() | ||
| || Some(def_id) == tcx.lang_items().panic_fmt() | ||
| || Some(def_id) == tcx.lang_items().begin_panic_fn() | ||
| } | ||
|
|
||
| fn handle( | ||
|
|
@@ -231,15 +233,11 @@ impl<'tcx> GotocHook<'tcx> for Nevers { | |
| _target: Option<BasicBlock>, | ||
| span: Option<Span>, | ||
| ) -> Stmt { | ||
| let loc = tcx.codegen_span_option(span); | ||
| // _target must be None due to how rust compiler considers it | ||
| Stmt::assert_false( | ||
| &format!( | ||
| "a panicking function {} is invoked", | ||
| with_no_trimmed_paths(|| tcx.tcx.def_path_str(instance.def_id())) | ||
| ), | ||
| loc, | ||
| ) | ||
| let msg = format!( | ||
| "a panicking function {} is invoked", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we can give a clearer message here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. Can I do it in a follow up PR since this will likely impact a lot of expected tests. I think this PR is already big enough.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| with_no_trimmed_paths(|| tcx.tcx.def_path_str(instance.def_id())) | ||
| ); | ||
| tcx.codegen_fatal_error(&msg, span) | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| line 12 a panicking function std::process::abort is invoked: FAILURE | ||
| line 16 a panicking function std::process::abort is invoked: SUCCESS | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| // | ||
| // Test that the abort() function is respected and nothing beyond it will execute. | ||
|
|
||
| use std::process; | ||
|
|
||
| pub fn main() { | ||
| for i in 0..4 { | ||
| if i == 1 { | ||
| // This comes first and it should be reachable. | ||
| process::abort(); | ||
| } | ||
| if i == 2 { | ||
| // This should never happen. | ||
| process::abort(); | ||
| } | ||
| } | ||
| assert!(false, "This is unreachable"); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| line 12 assertion failed: false: FAILURE | ||
| line 17 This is a placeholder message; RMC doesn't support message formatted at runtime: FAILURE | ||
| line 21 Fail with custom static message: FAILURE | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| // | ||
| // Check the location of the assert statement when using assert!(false); | ||
|
|
||
| fn any_bool() -> bool { | ||
| rmc::nondet() | ||
| } | ||
|
|
||
| pub fn main() { | ||
| if any_bool() { | ||
| assert!(false); | ||
| } | ||
|
|
||
| if any_bool() { | ||
| let s = "Fail with custom runtime message"; | ||
| assert!(false, "{}", s); | ||
| } | ||
|
|
||
| if any_bool() { | ||
| assert!(false, "Fail with custom static message"); | ||
| } | ||
| } | ||
|
|
||
| #[inline(always)] | ||
| #[track_caller] | ||
| fn check_caller(b: bool) { | ||
| assert!(b); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| line 6 This should fail and stop the execution: FAILURE | ||
| line 7 This should be unreachable: SUCCESS | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 OR MIT | ||
|
|
||
| pub fn main() { | ||
| for i in 0..4 { | ||
| debug_assert!(i > 0, "This should fail and stop the execution"); | ||
| assert!(i == 0, "This should be unreachable"); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,19 +56,22 @@ fn ibxor_test(a: i32, b: i32, correct: i32, wrong: i32) { | |
| } | ||
|
|
||
| fn main() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IS this to prevent one failure from hiding others?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. Otherwise everything passed after |
||
| iadd_test(1, 2, 3, 4); | ||
| isub_test(3, 4, -1, 0); | ||
| imul_test(5, 6, 30, 60); | ||
| idiv_test(8, 2, 4, 5); | ||
| idiv_test(9, 2, 4, 5); | ||
| imod_test(9, 3, 0, 1); | ||
| imod_test(10, 3, 1, 2); | ||
| ishl_test(2, 3, 16, 8); | ||
| ishr_test(8, 3, 1, 2); | ||
| ishr_test(-1, 2, -1, 1073741823); | ||
| ushr_test(4294967292, 2, 1073741823, 2); | ||
| iband_test(0, 2389034, 0, 2389034); | ||
| iband_test(3, 10, 2, 3); | ||
| ibor_test(0, 2389034, 2389034, 0); | ||
| ibxor_test(0, 2389034, 2389034, 0); | ||
| match rmc::nondet::<u8>() { | ||
| 0 => iadd_test(1, 2, 3, 4), | ||
| 1 => isub_test(3, 4, -1, 0), | ||
| 2 => imul_test(5, 6, 30, 60), | ||
| 3 => idiv_test(8, 2, 4, 5), | ||
| 4 => idiv_test(9, 2, 4, 5), | ||
| 5 => imod_test(9, 3, 0, 1), | ||
| 6 => imod_test(10, 3, 1, 2), | ||
| 7 => ishl_test(2, 3, 16, 8), | ||
| 8 => ishr_test(8, 3, 1, 2), | ||
| 9 => ishr_test(-1, 2, -1, 1073741823), | ||
| 10 => ushr_test(4294967292, 2, 1073741823, 2), | ||
| 11 => iband_test(0, 2389034, 0, 2389034), | ||
| 12 => iband_test(3, 10, 2, 3), | ||
| 13 => ibor_test(0, 2389034, 2389034, 0), | ||
| 14 => ibxor_test(0, 2389034, 2389034, 0), | ||
| _ => {} | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.