fix ICE in const_c_variadic when passing ZSTs#153398
fix ICE in const_c_variadic when passing ZSTs#153398folkertdev wants to merge 1 commit intorust-lang:mainfrom
const_c_variadic when passing ZSTs#153398Conversation
|
|
| J: Iterator<Item = (usize, &'a ArgAbi<'tcx, Ty<'tcx>>)>, | ||
| { | ||
| // Arguments that are ignored (ZSTs) are not passed by the caller. | ||
| let mut callee_abis = callee_abis.filter(|(_, abi)| !abi.is_ignore()); |
There was a problem hiding this comment.
I think it'd be better to do this in call.rs where this function is called; that's closer to the other logic for skipping ignored arguments.
|
|
||
| unsafe fn read_too_many() { | ||
| const { read_n::<0>(read_as::<u32>, 1i32) } | ||
| //~^ ERROR can't pass a function item to a variadic function |
There was a problem hiding this comment.
Wait, we are executing this const even though it has a type error? That seems very wrong.
| J: Iterator<Item = (usize, &'a ArgAbi<'tcx, Ty<'tcx>>)>, | ||
| { | ||
| // Arguments that are ignored (ZSTs) are not passed by the caller. | ||
| let mut callee_abis = callee_abis.filter(|(_, abi)| !abi.is_ignore()); |
There was a problem hiding this comment.
Can you add a test in src/tools/miri/tests/pass/c-variadic.rs where the caller passes i32, (), i32 and then I guess the callee only sees the two integers? That does seem strange though, arguably the callee needs to fetch the () argument or else it's UB, no?
fd19350 to
f8da51c
Compare
|
The Miri subtree was changed cc @rust-lang/miri |
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
f8da51c to
e24fd0a
Compare
e24fd0a to
7b35105
Compare
|
After playing around with this some more, it turned out that ignored arguments are platform-specific, because some ABIs explicitly pass ZSTs. So, I think that it's actually best to truly pass the argument, and then have any use fail because there is no valid way to e.g. read a |
| loop { | ||
| // Peel off ignored arguments. These are not passed by the caller, but are present in | ||
| // the callee's ABI. | ||
| while let Some((_idx, callee_abi)) = callee_abis.peek() | ||
| && callee_abi.is_ignore() | ||
| { | ||
| let mplace = self.allocate(callee_abi.layout, MemoryKind::Stack)?; | ||
| varargs.push(mplace); | ||
| let _ = callee_abis.next(); | ||
| } | ||
|
|
||
| let Some((fn_arg, caller_abi)) = caller_args.next() else { | ||
| break; | ||
| }; |
There was a problem hiding this comment.
a bit weird, but this needs a do-while loop
fixes #153351
r? RalfJung
There was a mismatch between the caller and callee ABI where the caller does not pass ZST arguments, but the callee does expect them. Because ZSTs don't implement
VaArgSafethe program must already be invalid if this comes up.