[ownership] directly assigning any field of an aggregate struct counts as initialization

Summary:
Aggregate initialization (e.g., `S s{1, 2}`) doesn't invoke a contructor.
Our frontend translates aggregation initialization as assigning to each field in the struct.
To avoid the appearance of the struct being uninitialized, count any assignment to a field of an aggregate struct as initializing the struct.

Reviewed By: jeremydubreil

Differential Revision: D7189671

fbshipit-source-id: ace02fc
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 0bc4df4b42
commit 3a40afcd22

@ -217,11 +217,24 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
false false
let is_aggregate (_, typ) =
match typ.Typ.desc with
| Tstruct _ ->
(* TODO: we could compute this precisely by recursively checking all of the fields of the
type, but that's going to be expensive. will add it to the frontend instead *)
true
| _ ->
false
let exec_instr (astate: Domain.astate) (proc_data: extras ProcData.t) _ (instr: HilInstr.t) = let exec_instr (astate: Domain.astate) (proc_data: extras ProcData.t) _ (instr: HilInstr.t) =
let summary = proc_data.extras in let summary = proc_data.extras in
match instr with match instr with
| Assign (Base lhs_base, rhs_exp, loc) -> | Assign (Base lhs_base, rhs_exp, loc) ->
Domain.handle_var_assign lhs_base rhs_exp loc summary astate Domain.handle_var_assign lhs_base rhs_exp loc summary astate
| Assign (FieldOffset (Base lhs_base, _), rhs_exp, loc) when is_aggregate lhs_base ->
(* assume assigning to any field of an aggregate struct re-initalizes the struct *)
Domain.handle_var_assign lhs_base rhs_exp loc summary astate
| Assign (lhs_access_exp, rhs_exp, loc) -> | Assign (lhs_access_exp, rhs_exp, loc) ->
(* assign to field, array, indirectly with &/*, or a combination *) (* assign to field, array, indirectly with &/*, or a combination *)
Domain.exp_add_reads rhs_exp loc summary astate Domain.exp_add_reads rhs_exp loc summary astate

@ -0,0 +1,25 @@
/*
* Copyright (c) 2018 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
struct Aggregate {
int i;
~Aggregate() {}
};
void aggregate_reassign_ok() {
const int len = 5;
Aggregate arr[len];
for (int i = 0; i < len; i++) {
Aggregate s = {1};
// assign with curly bracket syntax doesn't call constructor; need to
// recognize that this is a reassignment anyway
arr[0] = s; // shouldn't be flagged as a use-after-lifetime
}
}
Loading…
Cancel
Save