[pulse] do not destroy `this` even if asked to

Summary:
Some code calls `this->~Obj()` then proceeds to use fields in the current
object, which previously we would report as invalid uses. Assume people know
what they are doing and ignore destructor calls to `this`.

Reviewed By: mbouaziz

Differential Revision: D13401145

fbshipit-source-id: f6b0fb6ec
master
Jules Villard 6 years ago committed by Facebook Github Bot
parent f409450d8b
commit 95fab102bf

@ -42,6 +42,8 @@ let is_global = function ProgramVar pvar -> Pvar.is_global pvar | LogicalVar _ -
let is_return = function ProgramVar pvar -> Pvar.is_return pvar | LogicalVar _ -> false let is_return = function ProgramVar pvar -> Pvar.is_return pvar | LogicalVar _ -> false
let is_this = function ProgramVar pvar -> Pvar.is_this pvar | LogicalVar _ -> false
let is_footprint = function ProgramVar _ -> false | LogicalVar id -> Ident.is_footprint id let is_footprint = function ProgramVar _ -> false | LogicalVar id -> Ident.is_footprint id
let is_none = function LogicalVar id -> Ident.is_none id | _ -> false let is_none = function LogicalVar id -> Ident.is_none id | _ -> false

@ -37,6 +37,9 @@ val is_global : t -> bool
val is_return : t -> bool val is_return : t -> bool
val is_this : t -> bool
(** return whether the var is the special "this" var *)
val is_footprint : t -> bool val is_footprint : t -> bool
val is_none : t -> bool val is_none : t -> bool

@ -61,6 +61,9 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
match call with match call with
| Direct callee_pname when is_destructor callee_pname -> ( | Direct callee_pname when is_destructor callee_pname -> (
match actuals with match actuals with
| [AccessExpression (Base (destroyed_var, _))] when Var.is_this destroyed_var ->
(* do not invalidate [this] when it is destroyed by calls to [this->~Obj()] *)
Ok astate
| [AccessExpression destroyed_access] -> | [AccessExpression destroyed_access] ->
let destroyed_object = HilExp.AccessExpression.dereference destroyed_access in let destroyed_object = HilExp.AccessExpression.dereference destroyed_access in
PulseDomain.invalidate PulseDomain.invalidate

@ -100,3 +100,18 @@ int struct_inside_loop_ok(std::vector<int> numbers) {
} }
return sum; return sum;
} }
struct UseAfterSelfDestruct {
A a_;
int x_;
~UseAfterSelfDestruct() {
if (x_ == 0) {
a_ = getA();
}
}
void reset_ok() {
this->~UseAfterSelfDestruct();
x_ = a_.f(x_);
}
};

Loading…
Cancel
Save