540 likes | 649 Views
Footprint Analysis: A Shape Analysis that Discovers Preconditions. Hongseok Yang (Queen Mary, University of London) (Joint work with Cristiano Calcagno, Dino Distefano, and Peter O’Hearn). void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp ).
E N D
Footprint Analysis: A Shape Analysis that Discovers Preconditions Hongseok Yang (Queen Mary, University of London) (Joint work with Cristiano Calcagno, Dino Distefano, and Peter O’Hearn)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) KeAcquireSpinLock(&de->ResetSpinLock, &Irql); void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { ……… PRESET_IRP ResetIrp,temp,tempnext; PDEVICE_EXTENSION de; ……… KeAcquireSpinLock(&de->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)ResetIrp->Flink2; } KeReleaseSpinLock(&de->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT); } KeReleaseSpinLock(&de->ResetSpinLock, Irql); IoCompleteRequest(Irp, IO_NO_INCREMENT);
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { ……… PRESET_IRP ResetIrp,temp,tempnext; PDEVICE_EXTENSION de; ……… KeAcquireSpinLock(&de->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)ResetIrp->Flink2; } KeReleaseSpinLock(&de->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT); } Footprint Analysis • Discovers safe preconditions of a piece of code. • Only the memory footprint of the code.
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { ……… PRESET_IRP ResetIrp,temp,tempnext; PDEVICE_EXTENSION de; ……… KeAcquireSpinLock(&de->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)ResetIrp->Flink2; } KeReleaseSpinLock(&de->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT); }
(de aD Flink2:0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aRIrp:Irp) void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)ResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT); } typedef struct { RESET_IRP* Flink2; IRP* Irp; … } RESET_IRP, *PRESET_IRP; typedef struct { RESET_IRP* Flink2; … } DEVICE_EXTENSION;
(de aD Flink2:0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aRIrp:Irp) void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT); } de aD Flink2: de typedef struct { RESET_IRP* Flink2; IRP* Irp; … } RESET_IRP, *PRESET_IRP; typedef struct { RESET_IRP* Flink2; … } DEVICE_EXTENSION;
(de aD Flink2:0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aRIrp:Irp) void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT); } de aD Flink2: de Æde = ResetIrp typedef struct { RESET_IRP* Flink2; IRP* Irp; … } RESET_IRP, *PRESET_IRP; typedef struct { RESET_IRP* Flink2; … } DEVICE_EXTENSION;
(de aD Flink2:0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aRIrp:Irp) void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT); } de aD Flink2: de Æ de = ResetIrp typedef struct { RESET_IRP* Flink2; IRP* Irp; … } RESET_IRP, *PRESET_IRP; typedef struct { RESET_IRP* Flink2; … } DEVICE_EXTENSION;
(de aD Flink2:0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de) (de aD Flink2: de) (de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aRIrp:Irp) void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT); } de aD Flink2: de Æ de = ResetIrp ERROR: No IRP Field in DEVICE_EXTENSION typedef struct { RESET_IRP* Flink2; IRP* Irp; … } RESET_IRP, *PRESET_IRP; typedef struct { RESET_IRP* Flink2; … } DEVICE_EXTENSION;
Footprint Analysis x=aÆemp list t*; while (x!=0) { t = x; x = x->next; free(t); } Seeding Footprint Computation
Footprint Analysis x=aÆemp list t*; while (x!=0) { t = x; x = x->next; free(t); } Seeding Footprint Computation
Footprint Analysis x=aÆemp list t*; while (x!=0) { t = x; x = x->next; free(t); } P1 P2 P3 Seeding Footprint Computation
Footprint Analysis {P1} x=aÆemp list t*; while (x!=0) { t = x; x = x->next; free(t); } P1 P2 P3 Seeding {I1,I2,I3} Footprint Computation SpaceInvader {Q1,Q2} {P1}C{Q1ÇQ2}
Footprint Analysis {P2} x=aÆemp list t*; while (x!=0) { t = x; x = x->next; free(t); } P1 P2 P3 Seeding {I10,I11,I12} Footprint Computation SpaceInvader {Q10,Q11 ,Q12} {P1}C{Q1ÇQ2} {P2}C{Q10ÇQ11ÇQ12}
Footprint Analysis {P3} x=aÆemp list t*; while (x!=0) { t = x; x = x->next; free(t); } P1 P2 P3 Seeding > Footprint Computation SpaceInvader > {P1}C{Q1ÇQ2} {P2}C{Q10ÇQ11ÇQ12}
Footprint Analysis x=aÆemp list t*; while (x!=0) { t = x; x = x->next; free(t); } P1 P2 P3 Seeding Footprint Computation SpaceInvader {P1}C{Q1ÇQ2} {P2}C{Q10ÇQ11ÇQ12}
Footprint Analysis Seeding Safe precondition Footprint only Footprint Computation SpaceInvader
Separation Logic xay, ls (y,z) xay * ls (y,z), emp 9y’. z!=0 Æ v=a Æxay’ * ls (y’,z) x y z y y z x
Variable Convention • Program variables: x,y,z,t,v,w • Ghost (or auxiliary) variables: a,b,c,d,…. • Primed variables: x’,y’,z’,t’,v’,w’ 9 w’,w’1. x!=0 Æ z=a Æ w’!=w’1Æ xaw’ * ls (w’,w’1) * yaw’1
Symbolic Heaps Separation logic formulas of the form: (x!=0 Æ z=a Æ w’!=w’1) Æ (xaw’ * ls (w’,w’1) * yaw’1) SH = Set of all symbolic heaps GhoSH = Set of sym. heaps with ghost vars only
Footprint Computation list t*; while (x!=0) { t = x; x = x->next; free(t); } { (x=aÆemp, x=aÆemp) } 2 Pfin(GhoSH, SH) Fixpoint Computation { (x=aÆls (a,0), x=0Æemp), (x=0Æemp, x=0Æemp), … } 2 Pfin (GhoSH, SH)
Footprint Computation rearr(x)(F,P) = { (F,P1), …, (F,Pn) } if SpInvRearr(x)(P) = {P1, …, Pn} = { (F*aab, P*aab) } else if P ` x=a = { (false,false) } otherwise «x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH) rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH) exec(x=x->next) : GhoSH x SH ! GhoSH x SH abs : GhoSH x SH ! CanGhoSH x CanSH { (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) } { (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b), (x=aÆls a b*bac, x=bÆls a b*bac) }
Footprint Computation «x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH) rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH) exec(x=x->next) : GhoSH x SH ! GhoSH x SH abs : GhoSH x SH ! CanGhoSH x CanSH { (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) } { (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b), (x=aÆls a b*bac, x=bÆls a b*bac) } { ………………………………., (x=aÆls a b*bac, x=cÆls a b*bac) }
Footprint Computation «x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH) rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH) exec(x=x->next) : GhoSH x SH ! GhoSH x SH abs : GhoSH x SH ! CanGhoSH x CanSH { (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) } { (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b), (x=aÆls a b*bac, x=bÆls a b*bac) } { ………………………………., (x=aÆls a b*bac, x=cÆls a b*bac) } { ………………………………., (x=aÆls a b*bac, x=cÆls a c) } { ………………………………., (x=aÆls a c*bac, x=cÆls a c) }
Footprint Computation «x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH) rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH) exec(x=x->next) : GhoSH x SH ! GhoSH x SH abs : GhoSH x SH ! CanGhoSH x CanSH { (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) } { (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b), (x=aÆls a b*bac, x=bÆls a b*bac) } { ………………………………., (x=aÆls a b*bac, x=cÆls a b*bac) } { ………………………………., (x=aÆls a b*bac, x=cÆls a c) } { ………………………………., (x=aÆls a c*bac, x=cÆls a c) }
List Disposal list t*; while (x!=0) { t = x; x = x->next; free(t); } x 0
List Disposal list t*; while (x!=0) { t = x; x = x->next; free(t); } x 0
List Disposal list t*; while (x!=0) { t = x; x = x->next; free(t); } t x 0
List Disposal list t*; while (x!=0) { t = x; x = x->next; free(t); } t x 0
List Disposal list t*; while (x!=0) { t = x; x = x->next; free(t); } t x 0
Footprint Computation list t*; while (x!=0) { t = x; x = x->next; free(t); }
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=a Æ emp list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ emp list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ emp list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=a Æ a!=0 Æ t=aÆ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ emp * aab list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=aÆ a!=0 Æ t=aÆ emp x=bÆ a!=0 Æ t=a Æ emp * aab
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ emp * aab list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=a Æ a!=0 Æ t=aÆ emp x=b Æ a!=0 Æ t=a Æ emp * aab x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ emp * aab list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=a Æ a!=0 Æ t=aÆ emp x=b Æ a!=0 Æ t=a Æ emp * aab x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * aab list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=bÆ a!=0 Æ t=a Æ b!=0Æ emp x=a Æ a!=0 Æ t=aÆ emp x=b Æ a!=0 Æ t=a Æ emp * aab x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * aab list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=bÆ a!=0 Æ t=aÆ b!=0 Æ emp x=a Æ a!=0 Æ t=aÆ emp x=b Æ a!=0 Æt=bÆ b!=0 Æ emp x=b Æt=bÆ b!=0 Æ emp x=b Æ a!=0 Æ t=a Æ emp * aab x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * aab* bac Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * ls a c a Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * ls a c a list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=bÆ a!=0 Æ t=a Æ b!=0 Æ emp x=a Æ a!=0 Æ t=aÆ emp x=bÆ t=b Æ b!=0 Æ emp x=b Æ a!=0 Æ t=a Æ emp * aab x=c Æ t=b Æ b!=0 Æ emp * bac x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * aab* bac Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * ls a c a list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=bÆ a!=0 Æ t=a Æ b!=0 Æ emp x=a Æ a!=0 Æ t=aÆ emp x=b Æ t=b Æ b!=0 Æ emp x=b Æ a!=0 Æ t=a Æ emp * aab x=c Æ t=b Æ b!=0 Æ emp * bac x=b Æ a!=0 Æ t=a Æ emp x=c Æ t=b Æ b!=0 Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * aab* bac Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * ls a c list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=bÆ a!=0 Æ t=a Æ b!=0 Æ emp x=a Æ a!=0 Æ t=aÆ emp x=b Æ t=b Æ b!=0 Æ emp x=b Æ a!=0 Æ t=a Æ emp * aab x=c Æ t=b Æ b!=0 Æ emp * bac x=b Æ a!=0 Æ t=a Æ emp x=c Æ t=b Æ b!=0 Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * aab* bac Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * ls a c a list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=bÆ a!=0 Æ t=a Æ b!=0 Æ emp x=a Æ a!=0 Æ t=aÆ emp x=b Æ t=b Æ b!=0 Æ emp x=b Æ a!=0 Æ t=a Æ emp * aab x=c Æ t=b Æ b!=0 Æ emp * bac x=b Æ a!=0 Æ t=a Æ emp x=c Æ t=b Æ b!=0 Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp) Footprint Computation Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * aab* bac Discovered Precondition: x=aÆ a!=0 Æ b!=0 Æ emp * ls a c a list t*; while (x!=0) { t = x; x = x->next; free(t); } x=a Æ emp x=a Æ a!=0 Æ emp x=bÆ a!=0 Æ t=a Æ b!=0 Æ emp x=a Æ a!=0 Æ t=aÆ emp x=b Æ t=b Æ b!=0 Æ emp x=b Æ a!=0 Æ t=a Æ emp * aab x=c Æ t=b Æ b!=0 Æ emp * bac x=b Æ a!=0 Æ t=a Æ emp x=c Æ t=b Æ b!=0 Æ emp Result: (x=aÆa=0Æemp, x=aÆa=0Æemp) (x=aÆa!=0Æb=0Æaab, x=bÆa!=0Æt=aÆb=0Æemp) (x=aÆa!=0Æc=0Æls a c, x=cÆt=bÆb!=0Æc=0Æemp)
Shape Analysis with SpaceInvader (x=aÆa=0Æemp, x=aÆa=0Æemp) (x=aÆa!=0Æb=0Æaab, x=bÆa!=0Æt=aÆb=0Æemp) (x=aÆa!=0Æc=0Æls a c, x=cÆt=bÆb!=0Æc=0Æemp) (x=aÆa=0Æemp, x=aÆa=0Æemp) (x=aÆa!=0Æb=0Æaab, x=bÆa!=0Æt=aÆb=0Æemp) (x=aÆa!=0Æc=0Æls a c, x=cÆt=bÆb!=0Æc=0Æemp) list t*; while (x!=0) { t = x; x = x->next; free(t); } {x=a’Æa’=0Æemp} {x=a’Æa’!=0Æa’a0} {x=a’Æa’!=0Æls a’ 0} { x=0 Æ emp } { x=0 Æ emp } { x=0 Æ emp }
Footprint Computation, Ideally «C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH) Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }. Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}. Q G F0 F P D C
Footprint Computation, Ideally «C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH) Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }. Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}. {t=aÆx=bÆaab} free(t);t=x {t=bÆx=bÆemp} «x=x->next¬{ (t=aÆx=bÆaab, t=bÆx=bÆemp) } = { (t=aÆx=bÆaab*bac, t=bÆx=cÆbac) } «x=x->next¬{ (t=aÆx=bÆaab, t=bÆx=bÆemp) } = { (t=aÆx=bÆls a c, t=bÆx=cÆbac) } {t=aÆx=bÆaab*bac} …….;x=x->next{t=bÆx=cÆbac} {t=aÆx=bÆls a c } …….;x=x->next{t=bÆx=cÆbac}
Footprint Computation, Actually «C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH) Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }. Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}. Actually: for all D, if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi}, PiµQi. Gi Pi Abstraction abs Fi F P D C Qi Rearrangement rearr(E)
Footprint Computation, Actually «C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH) Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }. Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}. Actually: for all D, if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi}, PiµQi. But, only abs and rearr(E)! Gi Pi Abstraction abs Fi F P D C Qi Rearrangement rearr(E)
Footprint Computation, Actually «C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH) Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }. Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}. Actually: for all D, if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi}, PiµQi. But, only abs and rearr(E)! Pi Fi F P D free(t) proof rule for free(t) in sep. logic