Skip to content

miri function argument passing should use FnAbi #56166

Description

@RalfJung

In the miri engine, when evaluating a function call, it can happen that caller and callee do not agree on the type of an argument. In this case, the argument effectively gets transmuted from the caller type to the callee type. However, this is not legal for all types, and whether it is legal depends on horrible details of the ABI. This logic is implemented for codegen, where it is called FnType. miri should probably use that same infrastructure.

The relevant code in miri that would need changing is here. Currently, we only allow argument type punning for the Rust ABI, and we only allow the valid range of a Scalar/ScalarPair to change -- effectively, we allow one side to have &T while the other side has *const T.

For the FnType side, I do not know much, but @eddyb offered to mentor someone trying to do this cleanup. :) He also left the following hints:

move some code from rustc_codegen_ssa and then compare ArgType pairwise.

The main issue to moving that stuff around is pointee_info_at (it would have to be moved to rustc::ty::layout, as an additional method in TyLayoutMethods):

if let Some(pointee) = layout.pointee_info_at(cx, offset) {

Everything else is mostly relying on rustc_target doing the heavy lifting, already.

Cc @oli-obk

Activity

  1. added
    E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
    E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.
    on Nov 22, 2018
  2. added
    C-cleanupCategory: PRs that clean code up or issues documenting cleanup.
    on Nov 22, 2018
  3. wildarch commented on Dec 20, 2018

    @wildarch
    Contributor

    It seems this issue has been open for a while, is it still relevant? If so, I would like to take a shot at it 😄.

  4. RalfJung commented on Dec 20, 2018

    @RalfJung
    MemberAuthor

    Awesome! Nobody has been working on this so far, so you are free to grab it. :)

    @eddyb your mentoring is needed :D

  5. wildarch commented on Dec 24, 2018

    @wildarch
    Contributor

    I have started with the refactoring by moving the pointee_info_at function to TyLayoutMethods. For now I still need to figure out how to translate some of the calls that were previously using the CodegenCx reference to work with the different context type available in TyLayoutMethods.
    I'm quite confident I can get that to work, the only thing I'm struggling with at the moment are the MaybeResult<TyLayout>s I get when calling layout_of on the context. It's the first time I encounter this trait, and I am not quite sure how to work with it, given that I eventually want to end up with an Option<PointeeInfo> instead of a MaybeResult<PointeeInfo>.

    @eddyb do you have some pointers on this? I might also ask around on IRC. Perhaps I should change the signature to be MaybeResult<PointeeInfo>?

  6. wildarch commented on Dec 24, 2018

    @wildarch
    Contributor

    Figured out the situation with the MaybeResult, will post another update when pointee_info_at has been moved

  7. wildarch commented on Dec 24, 2018

    @wildarch
    Contributor

    I have created a duplicate implementation of pointee_info_at in TyLayoutMethods as suggested by @eddyb (I will remove the original in a later commit). I think the method by itself is okay now, except that I want to move the type_is_freeze method in src/librustc_codegen_ssa/common.rs to somewhere in the rustc crate, right now I have simply copied to implementation into pointee_info_at, which is far from ideal. Any ideas on where to put that function @eddyb or @RalfJung?

    Current changes are in my fork, should I already turn it into a WIP pull request?

  8. oli-obk commented on Dec 27, 2018

    @oli-obk
    Contributor

    should I already turn it into a WIP pull request?

    That's a good idea, because it makes commenting on the impl much easier

  9. RalfJung commented on Dec 27, 2018

    @RalfJung
    MemberAuthor

    I want to move the type_is_freeze method in src/librustc_codegen_ssa/common.rs

    I wonder why it even has such a method, can't it use is_freeze?

    But anyway, @eddyb is much more qualified to answer these questions. ;)

  10. wildarch commented on Dec 27, 2018

    @wildarch
    Contributor

    @RalfJung type_is_freeze actually calls out to is_freeze, providing the param_env and span arguments. The following two are equivalent:

    cx.type_is_freeze(ty)
    ty.is_freeze(cx, ParamEnv::reveal_all(), DUMMY_SPAN)

    Instead of moving type_is_freeze I could also change the occurrences to use is_freeze, how do you feel about that?

  11. wildarch commented on Dec 27, 2018

    @wildarch
    Contributor

    should I already turn it into a WIP pull request?

    That's a good idea, because it makes commenting on the impl much easier

    Done!

  12. RalfJung commented on Dec 27, 2018

    @RalfJung
    MemberAuthor

    Instead of moving type_is_freeze I could also change the occurrences to use is_freeze, how do you feel about that?

    Depends on how often it gets called. But really I have very little experience in rustc outside miri, so I'll leave this to @eddyb.

  13. added a commit that references this issue on May 5, 2019
  14. saleemjaffer commented on May 6, 2019

    @saleemjaffer
    Contributor

    @eddyb Regarding moving FnType stuff from librustc_codegen_llvm/abi.rs to librustc_target/abi/call/mod.rs:

    This is defined in librustc_codegen_llvm/abi.rs

    pub trait FnTypeExt<'tcx> {
        fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self;
        fn new(cx: &CodegenCx<'ll, 'tcx>,
               sig: ty::FnSig<'tcx>,
               extra_args: &[Ty<'tcx>]) -> Self;
        fn new_vtable(cx: &CodegenCx<'ll, 'tcx>,
                      sig: ty::FnSig<'tcx>,
                      extra_args: &[Ty<'tcx>]) -> Self;
        fn new_internal(
            cx: &CodegenCx<'ll, 'tcx>,
            sig: ty::FnSig<'tcx>,
            extra_args: &[Ty<'tcx>],
            mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgType<'tcx, Ty<'tcx>>,
        ) -> Self;
        fn adjust_for_abi(&mut self,
                          cx: &CodegenCx<'ll, 'tcx>,
                          abi: Abi);
        fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
        fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
        fn llvm_cconv(&self) -> llvm::CallConv;
        fn apply_attrs_llfn(&self, llfn: &'ll Value);
        fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
    }

    Looks like we need to move everything except

    fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
    fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
    fn llvm_cconv(&self) -> llvm::CallConv;
    fn apply_attrs_llfn(&self, llfn: &'ll Value);

    These methods seem to so some conversion from FnType into what LLVM needs.

  15. added a commit that references this issue on May 15, 2019
  16. added a commit that references this issue on May 16, 2019
  17. RalfJung commented on Dec 31, 2019

    @RalfJung
    MemberAuthor

    Also see what @eddyb wrote at rust-lang/miri#1038 (comment)

  18. removed
    E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.
    E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
    on Jul 16, 2021
  19. changed the title [-]miri function argument passing should use FnType[/-] [+]miri function argument passing should use FnAbi[/+] on Jul 16, 2021
  20. RalfJung commented on Jul 16, 2021

    @RalfJung
    MemberAuthor

    So... what would it take to use this in Miri? @eddyb @oli-obk and maybe @bjorn3
    I assume I have to somehow get hold of an FnAbi around here

    let (fn_val, abi, caller_can_unwind) = match *func.layout.ty.kind() {

    and adjust the eval_fn_call function to take such a FnAbi and use it -- though I am not entirely clear on how to use it either. Would this replace one of the existing arguments, or would this be a new argument? But if it's a new argument then nothing forces eval_fn_call to even use it.^^

    Is there code in our codegen backends that uses FnAbi that Miri should basically follow?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-cleanupCategory: PRs that clean code up or issues documenting cleanup.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions