let locate ?alarm ?pos e =
  (* Recursively label conjuncts so that splitting conjuncts in Why still
   * allows to locate the resulting VC.
   *)

  let rec dopos ~toplevel e =
    (* Generate (and store) a label associated to this source location *)
    let pos = match pos with
      | None -> e#pos
      | Some pos ->
          if is_unknown_location e#pos then pos else e#pos
    in
    let lab = match alarm with
      | None ->
          reg_pos pos
      | Some Alarms.Division_alarm ->
          reg_pos ~kind:Output.DivByZero pos
      | Some Alarms.Memory_alarm | Some Alarms.Index_alarm ->
          reg_pos ~kind:Output.PointerDeref pos
      | Some (Alarms.Shift_alarm|Alarms.Signed_overflow_alarm->
          reg_pos ~kind:Output.ArithOverflow pos
      | Some Alarms.Pointer_compare_alarm
      | Some Alarms.Using_nan_or_infinite_alarm
      | Some Alarms.Result_is_nan_or_infinite_alarm ->
          reg_pos pos
      | Some Alarms.Separation_alarm -> reg_pos pos
      | Some Alarms.Other_alarm -> reg_pos pos
    in
    let e = match e#node with
      | JCPEbinary(e1,`Bland,e2) ->
          begin match e1#node,e2#node with
            | JCPElabel _,JCPElabel _ -> e (* already labelled *)
            | JCPElabel _,_ -> (* [e1] already labelled *)
                let e2 = dopos ~toplevel:false e2 in
                mkexpr (JCPEbinary(e1,`Bland,e2)) pos
            | _,JCPElabel _ -> (* [e2] already labelled *)
                let e1 = dopos ~toplevel:false e1 in
                mkexpr (JCPEbinary(e1,`Bland,e2)) pos
            | _,_ -> (* none already labelled *)
                let e1 = dopos ~toplevel:false e1 in
                let e2 = dopos ~toplevel:false e2 in
                mkexpr (JCPEbinary(e1,`Bland,e2)) pos
          end
      | _ -> e
    in
    (* Do not generate a label for every intermediate conjunct *)
    match e#node with
      | JCPEbinary(_e1,`Bland,_e2) when not toplevel -> e
      | _ ->
          (* Label the expression accordingly *)
          mkexpr (JCPElabel(lab,e)) pos
  in
  dopos ~toplevel:true e