diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2020-12-29 20:00:57 +0100 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2021-01-23 10:30:39 +0100 |
| commit | a93dace55c588badca5475de570e45063deaf0be (patch) | |
| tree | b727c704f7aaa73a29970a8723a83d1e8191473f /compiler/rustc_target | |
| parent | ba484de538640305b0ba5f574d809c1a71feda26 (diff) | |
| download | rust-a93dace55c588badca5475de570e45063deaf0be.tar.gz rust-a93dace55c588badca5475de570e45063deaf0be.zip | |
Never create an temporary PassMode::Direct when it is not a valid pass mode for a type
Diffstat (limited to 'compiler/rustc_target')
| -rw-r--r-- | compiler/rustc_target/src/abi/call/mod.rs | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 24fd11b6772..e889c3c415c 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -434,31 +434,49 @@ pub struct ArgAbi<'a, Ty> { } impl<'a, Ty> ArgAbi<'a, Ty> { - pub fn new(layout: TyAndLayout<'a, Ty>) -> Self { - ArgAbi { layout, pad: None, mode: PassMode::Direct(ArgAttributes::new()) } + pub fn new( + cx: &impl HasDataLayout, + layout: TyAndLayout<'a, Ty>, + scalar_attrs: impl Fn(&TyAndLayout<'a, Ty>, &abi::Scalar, Size) -> ArgAttributes, + ) -> Self { + let mode = match &layout.abi { + Abi::Uninhabited => PassMode::Ignore, + Abi::Scalar(scalar) => PassMode::Direct(scalar_attrs(&layout, scalar, Size::ZERO)), + Abi::ScalarPair(a, b) => PassMode::Pair( + scalar_attrs(&layout, a, Size::ZERO), + scalar_attrs(&layout, b, a.value.size(cx).align_to(b.value.align(cx).abi)), + ), + Abi::Vector { .. } => PassMode::Direct(ArgAttributes::new()), + Abi::Aggregate { .. } => Self::indirect_pass_mode(&layout), + }; + ArgAbi { layout, pad: None, mode } } - pub fn make_indirect(&mut self) { - match self.mode { - PassMode::Direct(_) | PassMode::Pair(_, _) => {} - _ => panic!("Tried to make {:?} indirect", self.mode), - } - - // Start with fresh attributes for the pointer. + fn indirect_pass_mode(layout: &TyAndLayout<'a, Ty>) -> PassMode { let mut attrs = ArgAttributes::new(); // For non-immediate arguments the callee gets its own copy of // the value on the stack, so there are no aliases. It's also // program-invisible so can't possibly capture attrs.set(ArgAttribute::NoAlias).set(ArgAttribute::NoCapture).set(ArgAttribute::NonNull); - attrs.pointee_size = self.layout.size; + attrs.pointee_size = layout.size; // FIXME(eddyb) We should be doing this, but at least on // i686-pc-windows-msvc, it results in wrong stack offsets. - // attrs.pointee_align = Some(self.layout.align.abi); + // attrs.pointee_align = Some(layout.align.abi); - let extra_attrs = self.layout.is_unsized().then_some(ArgAttributes::new()); + let extra_attrs = layout.is_unsized().then_some(ArgAttributes::new()); - self.mode = PassMode::Indirect { attrs, extra_attrs, on_stack: false }; + PassMode::Indirect { attrs, extra_attrs, on_stack: false } + } + + pub fn make_indirect(&mut self) { + match self.mode { + PassMode::Direct(_) | PassMode::Pair(_, _) => {} + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: false } => return, + _ => panic!("Tried to make {:?} indirect", self.mode), + } + + self.mode = Self::indirect_pass_mode(&self.layout); } pub fn make_indirect_byval(&mut self) { @@ -489,10 +507,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> { } pub fn cast_to<T: Into<CastTarget>>(&mut self, target: T) { - match self.mode { - PassMode::Direct(_) | PassMode::Pair(_, _) => {} - _ => panic!("Tried to cast {:?} to {:?}", self.mode, target.into()), - } self.mode = PassMode::Cast(target.into()); } |
