let rec destruct_pointer e = match (stripInfo e).enode with
| Lval(Var v,NoOffset) | StartOf(Var v,NoOffset) | AddrOf(Var v,NoOffset) ->
Some(v,None)
| StartOf(Var v,Index(i,NoOffset)) | AddrOf(Var v,Index(i,NoOffset)) ->
Some(v,Some i)
| BinOp((PlusPI | IndexPI | MinusPI as op),e1,e2,_) ->
begin match destruct_pointer e1 with
| None -> None
| Some(v,None) ->
begin match op with
| PlusPI | IndexPI -> Some(v,Some e2)
| MinusPI -> Some(v,Some(new_exp(UnOp(Neg,e2,typeOf e2))))
| _ -> assert false
end
| Some(v,Some off) ->
begin match op with
| PlusPI | IndexPI ->
Some(v,Some(new_exp(BinOp(PlusA,off,e2,typeOf e2))))
| MinusPI ->
Some(v,Some(new_exp(BinOp(MinusA,off,e2,typeOf e2))))
| _ -> assert false
end
end
| CastE(ty,e) ->
let ety = typeOf e in
if isPointerType ty && isPointerType ety
&& (typeSig (typeRemoveAttributes ["const";"volatile"]
(unrollType (pointed_type ty)))
=
typeSig (typeRemoveAttributes ["const";"volatile"]
(unrollType (pointed_type ety)))) then
destruct_pointer e
else None
| _ -> None