let get_bitwise_shift_right_operand_assertion
    ~simplify_constants:simplify_constants
    ~warning:warning
    exp roperand =
  let t = Cil.typeOf exp in
  let size = bitsSizeOf t
  in let size64 = Int64.of_int size
  in let right_operand_assertion () =
      let term = translate_C_expr_to_term roperand
      in
        Logic_const.pand
          (Logic_const.prel (Rge, term, Cil.lzero ()),
           Logic_const.prel (Rlt, term, Cil.lconstant size64))
  in let problem_with_operand_assertion () =
      if simplify_constants then (
        match get_expr_val roperand with
          | None -> (false,false)
          | Some c64 ->
              (* right operand is constant:
                 check it is nonnegative and stricly less than size *)

              if (Int64.compare c64 size64 < 0) && (Int64.compare c64 Int64.zero >= 0)
              then (true,true)  (* constant operator and assertion holds *)
              else (true,false(* constant operator and assertion does not hold *)
      ) else (false,false)
  in match problem_with_operand_assertion () with
    | (true,false->
        let assertion = right_operand_assertion () in
          if warning then (
            rte_warn
              "shift assert broken (bad right operand): %a" d_predicate_named assertion
          )
          ;
          ([ (assertion, Some (make_check_false ())) ], false)
    | (true,true-> ([ ], true)
    | (false,_)  ->  ([ (right_operand_assertion (), None) ], true)