use rustc_hir::LangItem;
use rustc_index::IndexVec;
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext};
use rustc_middle::mir::*;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_session::Session;

use crate::check_pointers::{BorrowedFieldProjectionMode, PointerCheck, check_pointers};

pub(super) struct CheckNull;

impl<'tcx> crate::MirPass<'tcx> for CheckNull {
    fn is_enabled(&self, sess: &Session) -> bool {
        sess.ub_checks()
    }

    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
        check_pointers(
            tcx,
            body,
            &[],
            insert_null_check,
            BorrowedFieldProjectionMode::NoFollowProjections,
        );
    }

    fn is_required(&self) -> bool {
        true
    }
}

fn insert_null_check<'tcx>(
    tcx: TyCtxt<'tcx>,
    pointer: Place<'tcx>,
    pointee_ty: Ty<'tcx>,
    context: PlaceContext,
    local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>,
    stmts: &mut Vec<Statement<'tcx>>,
    source_info: SourceInfo,
) -> PointerCheck<'tcx> {
    // Cast the pointer to a *const ().
    let const_raw_ptr = Ty::new_imm_ptr(tcx, tcx.types.unit);
    let rvalue = Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(pointer), const_raw_ptr);
    let thin_ptr = local_decls.push(LocalDecl::with_source_info(const_raw_ptr, source_info)).into();
    stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((thin_ptr, rvalue)))));

    // Transmute the pointer to a usize (equivalent to `ptr.addr()`).
    let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Copy(thin_ptr), tcx.types.usize);
    let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
    stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((addr, rvalue)))));

    let zero = Operand::Constant(Box::new(ConstOperand {
        span: source_info.span,
        user_ty: None,
        const_: Const::Val(ConstValue::from_target_usize(0, &tcx), tcx.types.usize),
    }));

    let pointee_should_be_checked = match context {
        // Borrows pointing to "null" are UB even if the pointee is a ZST.
        PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
        | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
            // Pointer should be checked unconditionally.
            Operand::Constant(Box::new(ConstOperand {
                span: source_info.span,
                user_ty: None,
                const_: Const::from_bool(tcx, true),
            }))
        }
        // Other usages of null pointers only are UB if the pointee is not a ZST.
        _ => {
            let size_of = tcx.require_lang_item(LangItem::SizeOf, source_info.span);
            let size_of =
                Operand::unevaluated_constant(tcx, size_of, &[pointee_ty.into()], source_info.span);

            let pointee_should_be_checked =
                local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
            let rvalue = Rvalue::BinaryOp(BinOp::Ne, Box::new((size_of, zero.clone())));
            stmts.push(Statement::new(
                source_info,
                StatementKind::Assign(Box::new((pointee_should_be_checked, rvalue))),
            ));
            Operand::Copy(pointee_should_be_checked.into())
        }
    };

    // Check whether the pointer is null.
    let is_null = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
    stmts.push(Statement::new(
        source_info,
        StatementKind::Assign(Box::new((
            is_null,
            Rvalue::BinaryOp(BinOp::Eq, Box::new((Operand::Copy(addr), zero))),
        ))),
    ));

    // We want to throw an exception if the pointer is null and the pointee is not unconditionally
    // allowed (which for all non-borrow place uses, is when the pointee is ZST).
    let should_throw_exception =
        local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
    stmts.push(Statement::new(
        source_info,
        StatementKind::Assign(Box::new((
            should_throw_exception,
            Rvalue::BinaryOp(
                BinOp::BitAnd,
                Box::new((Operand::Copy(is_null), pointee_should_be_checked)),
            ),
        ))),
    ));

    // The final condition whether this pointer usage is ok or not.
    let is_ok = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
    stmts.push(Statement::new(
        source_info,
        StatementKind::Assign(Box::new((
            is_ok,
            Rvalue::UnaryOp(UnOp::Not, Operand::Copy(should_throw_exception)),
        ))),
    ));

    // Emit a PointerCheck that asserts on the condition and otherwise triggers
    // a AssertKind::NullPointerDereference.
    PointerCheck {
        cond: Operand::Copy(is_ok),
        assert_kind: Box::new(AssertKind::NullPointerDereference),
    }
}
