let merge_range loc base r1 r2 =
match r1,r2 with
| Fixed c1, Fixed c2 when Datatype.Int.compare c1 c2 = 0 -> r1
| Fixed c1, Fixed c2 ->
let min, max =
if Datatype.Int.compare c1 c2 <= 0 then c1,c2 else c2,c1 in
Interval (min,max)
| Fixed c1, Interval(min,max) ->
let min = if Datatype.Int.compare c1 min <= 0 then c1 else min in
let max = if Datatype.Int.compare max c1 <= 0 then c1 else max in
Interval (min,max)
| Fixed c1, Bounded(min,_) ->
let min = if Datatype.Int.compare c1 min <= 0 then c1 else min in
Unbounded min
| Fixed c1, Unbounded min ->
let min = if Datatype.Int.compare c1 min <= 0 then c1 else min in
Unbounded min
| Interval(min,max), Fixed c ->
if Datatype.Int.compare c min < 0 || Datatype.Int.compare c max > 0 then
begin
let min = if Datatype.Int.compare c min < 0 then c else min in
if Cil.isLogicZero base then
absolute_range loc min
else Unbounded min
end else r1
| Interval(min1,max1), Interval(min2,max2) ->
if Datatype.Int.compare min2 min1 < 0
|| Datatype.Int.compare max2 max1 > 0 then
begin
let min =
if Datatype.Int.compare min2 min1 < 0 then min2 else min1
in
if Cil.isLogicZero base then
absolute_range loc min
else Unbounded min
end else r1
| Interval(min1,_), (Bounded(min2,_) | Unbounded min2)->
let min = if Datatype.Int.compare min1 min2 <= 0 then min1 else min2 in
Unbounded min
| Bounded(min1,max1), Bounded(min2,max2)
when Cil_datatype.Term.equal max1 max2 ->
let min =
if Datatype.Int.compare min2 min1 < 0 then min2 else min1
in
Bounded(min,max1)
| Bounded(min1,_),
(Fixed min2 | Interval(min2,_) | Bounded (min2,_) | Unbounded min2) ->
let min =
if Datatype.Int.compare min2 min1 < 0 then min2 else min1
in Unbounded min
| Unbounded min1,
(Fixed min2 | Interval(min2,_) | Bounded (min2,_) | Unbounded min2) ->
let min =
if Datatype.Int.compare min2 min1 < 0 then min2 else min1
in Unbounded min