let compose_range loc b r1 r2 =
  match r1, r2 with
    | Fixed c1, Fixed c2 -> Fixed (c1 + c2)
    | Fixed c, Interval(min,max) | Interval(min,max), Fixed c ->
       Interval (c+min,c+max)
    | Fixed c, Bounded(min,max) | Bounded(min,max), Fixed c ->
      let max = 
        Logic_const.term
          (TBinOp(PlusA,max, Logic_const.tinteger ~ikind:IInt c))
          Linteger
      in
      Bounded(c+min,max)
    | Fixed c1, Unbounded min | Unbounded min, Fixed c1 -> Unbounded (min+c1)
    | Interval(min1,max1), Interval(min2,max2) ->
      Interval(min1+min2,max1+max2)
    (* NB: in the bounded case, we could check if upper bound of interval
       is less then lower bound of bounded to keep bounded.
     *)

    | Interval(min1,_), Bounded(min2,_) | Bounded(min2,_), Interval(min1,_)
    | Interval(min1,_), Unbounded min2 | Unbounded min2, Interval (min1,_)
    | Bounded(min1, _), Bounded (min2, _) | Unbounded min1, Unbounded min2
    | Bounded(min1,_), Unbounded min2 | Unbounded min1, Bounded(min2,_)
      ->
      if Cil.isLogicZero b then Data_for_aorai.absolute_range loc (min1 + min2)
      else Unbounded (min1 + min2)