Skip to content

Commit 6a5c3a9

Browse files
chrysnfw-immunant
authored andcommitted
Transfer the packed attribute on unions to repr(packed)
Closes: #346
1 parent b3dad71 commit 6a5c3a9

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

c2rust-transpile/src/c_ast/conversion.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1946,6 +1946,8 @@ impl ConversionContext {
19461946
let name = expect_opt_str(&node.extras[0]).unwrap().map(str::to_string);
19471947
let has_def = from_value(node.extras[1].clone())
19481948
.expect("Expected has_def flag on struct");
1949+
let attrs = from_value::<Vec<Value>>(node.extras[2].clone())
1950+
.expect("Expected attribute array on record");
19491951
let fields: Option<Vec<CDeclId>> = if has_def {
19501952
Some(
19511953
node.children
@@ -1962,7 +1964,18 @@ impl ConversionContext {
19621964
None
19631965
};
19641966

1965-
let record = CDeclKind::Union { name, fields };
1967+
let mut is_packed = false;
1968+
for attr in attrs {
1969+
match from_value::<String>(attr.clone())
1970+
.expect("Records attributes should be strings")
1971+
.as_str()
1972+
{
1973+
"packed" => is_packed = true,
1974+
_ => {}
1975+
}
1976+
}
1977+
1978+
let record = CDeclKind::Union { name, fields, is_packed };
19661979

19671980
self.add_decl(new_id, located(node, record));
19681981
self.processed_nodes.insert(new_id, RECORD_DECL);

c2rust-transpile/src/c_ast/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ pub enum CDeclKind {
933933
Union {
934934
name: Option<String>,
935935
fields: Option<Vec<CFieldId>>,
936+
is_packed: bool,
936937
},
937938

938939
// Field

c2rust-transpile/src/translator/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,6 +1614,7 @@ impl<'c> Translation<'c> {
16141614

16151615
CDeclKind::Union {
16161616
fields: Some(ref fields),
1617+
is_packed,
16171618
..
16181619
} => {
16191620
let name = self
@@ -1642,21 +1643,26 @@ impl<'c> Translation<'c> {
16421643
}
16431644
}
16441645

1646+
let mut repr = vec!["C"];
1647+
if is_packed {
1648+
repr.push("packed");
1649+
}
1650+
16451651
Ok(if field_syns.is_empty() {
16461652
// Empty unions are a GNU extension, but Rust doesn't allow empty unions.
16471653
ConvertedDecl::Item(
16481654
mk().span(s)
16491655
.pub_()
16501656
.call_attr("derive", vec!["Copy", "Clone"])
1651-
.call_attr("repr", vec!["C"])
1657+
.call_attr("repr", repr)
16521658
.struct_item(name, vec![], false),
16531659
)
16541660
} else {
16551661
ConvertedDecl::Item(
16561662
mk().span(s)
16571663
.pub_()
16581664
.call_attr("derive", vec!["Copy", "Clone"])
1659-
.call_attr("repr", vec!["C"])
1665+
.call_attr("repr", repr)
16601666
.union_item(name, field_syns),
16611667
)
16621668
})

0 commit comments

Comments
 (0)