Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions kani-driver/src/call_cbmc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ pub enum FailedProperties {
PanicsOnly,
// One or more failures that aren't panic-related
Other,
// One or more properties resulted in an ERROR rather than a failing/successful verification
Error,
}

/// The possible CBMC exit statuses
Expand Down Expand Up @@ -440,11 +442,13 @@ fn verification_outcome_from_properties(
let failed_properties = determine_failed_properties(properties);
let status = if should_panic {
match failed_properties {
FailedProperties::Error => VerificationStatus::Failure,
FailedProperties::None | FailedProperties::Other => VerificationStatus::Failure,
FailedProperties::PanicsOnly => VerificationStatus::Success,
}
} else {
match failed_properties {
FailedProperties::Error => VerificationStatus::Failure,
FailedProperties::None => VerificationStatus::Success,
FailedProperties::PanicsOnly | FailedProperties::Other => VerificationStatus::Failure,
}
Expand All @@ -454,6 +458,9 @@ fn verification_outcome_from_properties(

/// Determines the `FailedProperties` variant that corresponds to an array of properties
fn determine_failed_properties(properties: &[Property]) -> FailedProperties {
if properties.iter().any(|prop| prop.status == CheckStatus::Error) {
return FailedProperties::Error;
};
let failed_properties: Vec<&Property> =
properties.iter().filter(|prop| prop.status == CheckStatus::Failure).collect();
// Return `FAILURE` if there isn't at least one failed property
Expand Down
3 changes: 3 additions & 0 deletions kani-driver/src/cbmc_output_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ pub enum CheckStatus {
Unreachable,
Uncovered, // for `code_coverage` properties only
Unsatisfiable, // for `cover` properties only
Error, // returned by CBMC when using SMT solvers
}

impl std::fmt::Display for CheckStatus {
Expand All @@ -357,6 +358,8 @@ impl std::fmt::Display for CheckStatus {
// impossible to definitively conclude whether other properties hold or not.
CheckStatus::Unknown => style("UNDETERMINED").yellow(),
CheckStatus::Unsatisfiable => style("UNSATISFIABLE").yellow(),
// CBMC returns ERROR when using SMT solvers and the solver encounters an error.
CheckStatus::Error => style("ERROR").red(),
};
write!(f, "{check_str}")
}
Expand Down
1 change: 1 addition & 0 deletions kani-driver/src/cbmc_property_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ pub fn format_result(
FailedProperties::Other => {
" (encountered failures other than panics, which were unexpected)"
}
FailedProperties::Error => " (encountered a solver error)",
}
} else {
""
Expand Down
2 changes: 2 additions & 0 deletions tests/expected/smt-solver-error-status/expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Running SMT2 QF_AUFBV (with FPA) using Bitwuzla
VERIFICATION:- FAILED
13 changes: 13 additions & 0 deletions tests/expected/smt-solver-error-status/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! Regression test for issue #4519.
//! Ensures that Kani properly handles the ERROR status returned by CBMC
//! when using SMT solvers (z3, bitwuzla, cvc5) instead of panicking with:
//! "unknown variant `ERROR`, expected one of `FAILURE`, `COVERED`, ..."

#[kani::proof]
#[kani::solver(bitwuzla)]
pub fn check_smt_solver_error_status() {
assert!(false);
}
3 changes: 3 additions & 0 deletions tools/kani-cov/src/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub enum CheckStatus {
Unreachable,
Uncovered, // for `code_coverage` properties only
Unsatisfiable, // for `cover` properties only
Error, // returned by CBMC when using SMT solvers
}

/// Kani coverage check.
Expand Down Expand Up @@ -60,6 +61,8 @@ impl std::fmt::Display for CheckStatus {
CheckStatus::Unreachable => style("UNREACHABLE").yellow(),
CheckStatus::Undetermined => style("UNDETERMINED").yellow(),
CheckStatus::Unsatisfiable => style("UNSATISFIABLE").yellow(),
// CBMC returns ERROR when using SMT solvers and the solver encounters an error.
CheckStatus::Error => style("ERROR").red(),
};
write!(f, "{check_str}")
}
Expand Down
Loading