about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-11-27 14:23:02 +0000
committerbors <bors@rust-lang.org>2017-11-27 14:23:02 +0000
commit58e1234cddd996378cb9df6bed537b9c08a6df73 (patch)
treee728b9ff4fed7dd6ab051b63167ee379075edeb8 /src/libstd
parent5face5f4f58ceb6e68b44594489cafb6eb2e718e (diff)
parentf3b2d7f3a7b4dfcce46f3ad139717e8a9e3c9518 (diff)
downloadrust-58e1234cddd996378cb9df6bed537b9c08a6df73.tar.gz
rust-58e1234cddd996378cb9df6bed537b9c08a6df73.zip
Auto merge of #44884 - arielb1:pack-safe, r=nikomatsakis,eddyb
Make accesses to fields of packed structs unsafe

To handle packed structs with destructors (which you'll think are a rare
case, but the `#[repr(packed)] struct Packed<T>(T);` pattern is
ever-popular, which requires handling packed structs with destructors to
avoid monomorphization-time errors), drops of subfields of packed
structs should drop a local move of the field instead of the original
one.

That's it, I think I'll use a strategy suggested by @Zoxc, where this mir
```
drop(packed_struct.field)
```

is replaced by
```
tmp0 = packed_struct.field;
drop tmp0
```

cc #27060 - this should deal with that issue after codegen of drop glue
is updated.

The new errors need to be changed to future-compatibility warnings, but
I'll rather do a crater run first with them as errors to assess the
impact.

cc @eddyb

Things which still need to be done for this:
 - [ ] - handle `repr(packed)` structs in `derive` the same way I did in `Span`, and use derive there again
 - [ ] - implement the "fix packed drops" pass and call it in both the MIR shim and validated MIR pipelines
 - [ ] - do a crater run
 - [ ] - convert the errors to compatibility warnings
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/net/ip.rs3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index eea604943af..c832f8a934d 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -719,7 +719,8 @@ impl Eq for Ipv4Addr {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl hash::Hash for Ipv4Addr {
     fn hash<H: hash::Hasher>(&self, s: &mut H) {
-        self.inner.s_addr.hash(s)
+        // `inner` is #[repr(packed)], so we need to copy `s_addr`.
+        {self.inner.s_addr}.hash(s)
     }
 }