let eval_as_exact_loc ~with_alarms state e =
  try
    let lv = find_lv ~with_alarms state e in
    let loc = lval_to_loc ~with_alarms state lv in
    if not (valid_cardinal_zero_or_one ~for_writing:false loc)
    then raise Not_an_exact_loc;
    let typ = typeOfLval lv in
    let value_for_loc =
      Cvalue.Model.find ~conflate_bottom:true ~with_alarms state loc in
    (* Using (typeOf e) caused imprecisions with the condition
       char c; ... if (c>0) being transformed in if (((int)c)>0) by Cil. *)

    let value_for_loc2 = do_cast ~with_alarms typ value_for_loc in
    let value_for_loc2 =
      cast_lval_when_bitfield lv ~sizebf:loc.size value_for_loc2
    in
    if Cvalue.V.has_sign_problems value_for_loc &&
      not (Cvalue.V.equal value_for_loc value_for_loc2)
    then raise Not_an_exact_loc;
    loc, value_for_loc2, typ
  with Cannot_find_lv ->
    raise Not_an_exact_loc