Improving treatment of default constructor

Reviewed By: sblackshear

Differential Revision: D7509019

fbshipit-source-id: 69d99a9
master
Dino Distefano 7 years ago committed by Facebook Github Bot
parent 767606b98e
commit 3b608695af

@ -195,6 +195,15 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
acc acc
(* true if a function initializes at least a param or a field of a struct param *)
let function_initializes_some_formal_params pdesc call =
match Summary.read_summary pdesc call with
| Some {pre= initialized_formal_params; post= _} ->
not (D.is_empty initialized_formal_params)
| _ ->
false
let exec_instr (astate: Domain.astate) {ProcData.pdesc; ProcData.extras; ProcData.tenv} _ let exec_instr (astate: Domain.astate) {ProcData.pdesc; ProcData.extras; ProcData.tenv} _
(instr: HilInstr.t) = (instr: HilInstr.t) =
let update_prepost (((_, lhs_typ), apl) as lhs_ap) rhs = let update_prepost (((_, lhs_typ), apl) as lhs_ap) rhs =
@ -232,8 +241,18 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Call (_, Direct callee_pname, _, _, _) | Call (_, Direct callee_pname, _, _, _)
when Typ.Procname.equal callee_pname BuiltinDecl.objc_cpp_throw -> when Typ.Procname.equal callee_pname BuiltinDecl.objc_cpp_throw ->
{astate with uninit_vars= D.empty} {astate with uninit_vars= D.empty}
| Call (_, HilInstr.Direct call, _, _, _) when is_dummy_constructor_of_a_struct call -> | Call (_, HilInstr.Direct call, [(HilExp.AccessExpression AddressOf Base base)], _, _)
astate when is_dummy_constructor_of_a_struct call ->
(* if it's a default constructor, we use the following heuristic: we assume that it initializes
correctly all fields when there is an implementation of the constructor that initilizes at least one
field. If there is no explicit implementation we cannot assume fields are initialized *)
if function_initializes_some_formal_params pdesc call then
let uninit_vars' =
(* in HIL/SIL the default constructor has only one param: the struct *)
remove_all_fields tenv base astate.uninit_vars
in
{astate with uninit_vars= uninit_vars'}
else astate
| Call (_, HilInstr.Direct call, actuals, _, loc) -> | Call (_, HilInstr.Direct call, actuals, _, loc) ->
(* in case of intraprocedural only analysis we assume that parameters passed by reference (* in case of intraprocedural only analysis we assume that parameters passed by reference
to a function will be initialized inside that function *) to a function will be initialized inside that function *)

@ -0,0 +1,52 @@
/*
* 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.
*/
#include <string>
struct InitializingStruct {
size_t match1;
size_t count1;
InitializingStruct();
};
InitializingStruct::InitializingStruct() : match1(0), count1(0) {}
struct SemiInitializingStruct {
size_t match1;
size_t count1;
SemiInitializingStruct();
};
SemiInitializingStruct::SemiInitializingStruct() : match1(0) {}
struct NonInitializingStruct {
size_t match1;
size_t count1;
};
void foo(size_t, size_t){};
void init_OK() {
InitializingStruct s;
foo(s.count1, s.match1);
}
void FN_init() {
SemiInitializingStruct s;
foo(s.count1, s.match1);
}
void init_bad() {
NonInitializingStruct s;
foo(s.count1, s.match1);
}

@ -1,3 +1,5 @@
codetoanalyze/cpp/uninit/default_constr.cpp, init_bad, 3, UNINITIALIZED_VALUE, ERROR, []
codetoanalyze/cpp/uninit/default_constr.cpp, init_bad, 3, UNINITIALIZED_VALUE, ERROR, []
codetoanalyze/cpp/uninit/members.cpp, access_members_bad, 4, UNINITIALIZED_VALUE, ERROR, [] codetoanalyze/cpp/uninit/members.cpp, access_members_bad, 4, UNINITIALIZED_VALUE, ERROR, []
codetoanalyze/cpp/uninit/members.cpp, access_members_bad2, 4, UNINITIALIZED_VALUE, ERROR, [] codetoanalyze/cpp/uninit/members.cpp, access_members_bad2, 4, UNINITIALIZED_VALUE, ERROR, []
codetoanalyze/cpp/uninit/members.cpp, access_members_bad3, 4, UNINITIALIZED_VALUE, ERROR, [] codetoanalyze/cpp/uninit/members.cpp, access_members_bad3, 4, UNINITIALIZED_VALUE, ERROR, []

Loading…
Cancel
Save