method vexpr e = match e.enode with
    | BinOp((Shiftlt | Shiftrt as op),e1,e2,_ty) ->
        let cur_stmt = the self#current_stmt in
        let is_left_shift = match op with Shiftlt -> true | _ -> false in
        let ty1 = typeOf e1 in
        (* Ideally, should strip only casts introduced by the compiler, not
         * user casts. Since this information is not available, be
         * conservative here.
         *)

        let e1' = stripCastsButLastInfo e1 in
        let e2' = stripCastsButLastInfo e2 in
        (* Check that signed shift has a positive right operand *)
        if isSignedInteger ty1 then
          begin match possible_value_of_integral_expr e2' with
            | Some i when i >= 0L -> ()
            | _ ->
                let check = new_exp (BinOp(Ge,e2',constant_expr 0L,intType)) in
                let check =
                  !Db.Properties.Interp.force_exp_to_predicate locUnknown check
                in
                Annotations.add_alarm
                  cur_stmt ~before:true Alarms.Shift_alarm check
          end
        else ();
        (* Check that shift has not too big a right operand. *)
        let max_right = Int64.of_int (integral_type_size_in_bits ty1) in
        begin match possible_value_of_integral_expr e2' with
          | Some i when i < max_right -> ()
          | _ ->
              let max_right = constant_expr max_right in
              let check = new_exp (BinOp(Lt,e2',max_right,intType)) in
              let check =
                !Db.Properties.Interp.force_exp_to_predicate locUnknown check
              in
              Annotations.add_alarm
                cur_stmt ~before:true Alarms.Shift_alarm check
        end;
        (* Check that signed left shift has a positive left operand *)
        if is_left_shift && isSignedInteger ty1 then
          begin match possible_value_of_integral_expr e1' with
            | Some i when i >= 0L -> ()
            | _ ->
                let check = new_exp (BinOp(Ge,e1',constant_expr 0L,intType)) in
                let check =
                  !Db.Properties.Interp.force_exp_to_predicate locUnknown check
                in
                Annotations.add_alarm
                  cur_stmt ~before:true Alarms.Shift_alarm check
          end
        else ();
        (* Check that signed left shift has not a left operand that is bigger
         * than the maximal value for the type right shifted by its right
         * operand.
         *)

        if is_left_shift && isSignedInteger ty1 then
          let max_int = Int64.of_string
            (Big_int.string_of_big_int (max_value_of_integral_type ty1))
          in
          begin match possible_value_of_integral_expr e2' with
            | Some i when i >= 0L && i < 64L ->
                (* Only use optimization where [Int64.shift_right] is
                 * defined in OCaml
                 *)

                let i = Int64.to_int i in
                let max_left = constant_expr (Int64.shift_right max_int i) in
                let check = new_exp (BinOp(Le,e1',max_left,intType)) in
                let check =
                  !Db.Properties.Interp.force_exp_to_predicate locUnknown check
                in
                Annotations.add_alarm
                  cur_stmt ~before:true Alarms.Shift_alarm check
            | _ ->
                let max_int = constant_expr max_int in
                let max_left = new_exp (BinOp(Shiftrt,max_int,e2',intType)) in
                let check = new_exp (BinOp(Le,e1',max_left,intType)) in
                let check =
                  !Db.Properties.Interp.force_exp_to_predicate locUnknown check
                in
                Annotations.add_alarm
                  cur_stmt ~before:true Alarms.Shift_alarm check
          end
        else ();
        DoChildren
    | _ -> DoChildren