Skip to content

Commit d6d1ebf

Browse files
authored
Add missing padding needded for alignment (#3401)
This PR adds extra padding for enums when needed for alignment. The missing alignment was exposed in #2857 where the layout size from MIR for `der::error::ErrorKind` was 48 bytes, and from `codegen_enum` was only 41 bytes. The difference turned out to be caused by an 8-byte alignment that the compiler uses for this enum. Resolves #2857 Resolves #3318
1 parent e980aa2 commit d6d1ebf

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

kani-compiler/src/codegen_cprover_gotoc/codegen/typ.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1140,7 +1140,7 @@ impl<'tcx> GotocCtx<'tcx> {
11401140

11411141
/// Mapping enums to CBMC types is rather complicated. There are a few cases to consider:
11421142
/// 1. When there is only 0 or 1 variant, this is straightforward as the code shows
1143-
/// 2. When there are more variants, rust might decides to apply the typical encoding which
1143+
/// 2. When there are more variants, rust might decide to apply the typical encoding which
11441144
/// regard enums as tagged union, or an optimized form, called niche encoding.
11451145
///
11461146
/// The direct encoding is straightforward. Enums are just mapped to C as a struct of union of structs.
@@ -1242,6 +1242,23 @@ impl<'tcx> GotocCtx<'tcx> {
12421242
)
12431243
}),
12441244
));
1245+
// Check if any padding is needed for alignment. This is needed for
1246+
// https://github.com/model-checking/kani/issues/2857 for example.
1247+
// The logic for determining the maximum variant size is taken from:
1248+
// https://github.com/rust-lang/rust/blob/e60ebb2f2c1facba87e7971798f3cbdfd309cd23/compiler/rustc_session/src/code_stats.rs#L166
1249+
let max_variant_size = variants
1250+
.iter()
1251+
.map(|l: &LayoutS<FieldIdx, VariantIdx>| l.size)
1252+
.max()
1253+
.unwrap();
1254+
let max_variant_size = std::cmp::max(max_variant_size, discr_offset);
1255+
if let Some(padding) = gcx.codegen_alignment_padding(
1256+
max_variant_size,
1257+
&layout,
1258+
fields.len(),
1259+
) {
1260+
fields.push(padding);
1261+
}
12451262
fields
12461263
})
12471264
}

tests/cargo-kani/iss2857/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
[package]
4+
name = "iss2857"
5+
version = "0.1.0"
6+
edition = "2021"
7+
8+
[dependencies]
9+
sec1 = "0.7.3"

tests/cargo-kani/iss2857/expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
VERIFICATION:- SUCCESSFUL

tests/cargo-kani/iss2857/src/main.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// This test checks that https://github.com/model-checking/kani/issues/2857 is
5+
// fixed
6+
7+
#[kani::proof]
8+
fn check_der_error() {
9+
let e = sec1::der::Error::incomplete(sec1::der::Length::ZERO);
10+
let _ = format!("{e:?}");
11+
}
12+
13+
fn main() {}

0 commit comments

Comments
 (0)