[ownership] support placement new

Reviewed By: jeremydubreil

Differential Revision: D7269381

fbshipit-source-id: 7867958
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 245e49e2da
commit ec73adc66d

@ -267,6 +267,18 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
(* assign to field, array, indirectly with &/*, or a combination *)
Domain.exp_add_reads rhs_exp loc summary astate
|> Domain.access_path_add_read (AccessExpression.to_access_path lhs_access_exp) loc summary
| Call (Some (lhs_var, _), Direct callee_pname, actuals, _, _)
when Typ.Procname.equal callee_pname BuiltinDecl.__placement_new -> (
match
(* placement new creates an alias between lhs_var and placement_var. model as lhs_var
borrowing from placement_var *)
Option.bind ~f:extract_base_var (List.last actuals)
with
| Some (placement_var, _) ->
Domain.add placement_var CapabilityDomain.Owned astate
|> Domain.borrow_vars lhs_var (VarSet.singleton placement_var)
| None ->
astate )
| Call (_, Direct callee_pname, [(AccessExpression Base ((lhs_var, _) as lhs_base))], _, loc)
when transfers_ownership callee_pname ->
Domain.base_add_read lhs_base loc summary astate

@ -113,3 +113,33 @@ class Subclass : virtual POD {
*/
~Subclass() { delete f; }
};
void basic_placement_new_ok() {
S* ptr = new S(1);
S* tptr = new (ptr) S(1);
tptr->~S();
delete[] ptr;
}
S* destruct_pointer_contents_then_placement_new1_ok(S* s) {
s->~S();
new (s) S(1);
return s;
}
// need better heap abstraction to catch this example and the next
S* FN_placement_new_aliasing1_bad() {
S* s = new S(1);
s->~S();
auto alias = new (s) S(2);
delete alias; // this deletes s too
return s; // bad, returning freed memory
}
S* FN_placement_new_aliasing2_bad() {
S* s = new S(1);
s->~S();
auto alias = new (s) S(2);
delete s; // this deletes alias too
return alias; // bad, returning freed memory
}

Loading…
Cancel
Save