Fixing init list expr when there is no variable or compound literal expression

Reviewed By: ddino

Differential Revision: D3048294

fb-gh-sync-id: b4b8cd2
shipit-source-id: b4b8cd2
master
Dulma Rodriguez 9 years ago committed by Facebook Github Bot 8
parent 7ffb635719
commit a62ccc7a05

@ -253,6 +253,14 @@ struct
let typ = CTypes_decl.type_ptr_to_sil_type tenv type_ptr in let typ = CTypes_decl.type_ptr_to_sil_type tenv type_ptr in
(mk_temp_sil_var procdesc var_name_prefix, typ) (mk_temp_sil_var procdesc var_name_prefix, typ)
let create_var_exp_tmp_var trans_state expr_info var_name =
let context = trans_state.context in
let procdesc = context.CContext.procdesc in
let (pvar, typ) = mk_temp_sil_var_for_expr context.CContext.tenv procdesc
var_name expr_info in
Cfg.Procdesc.append_locals procdesc [(Sil.pvar_get_name pvar, typ)];
Sil.Lvar pvar, typ
let create_call_instr trans_state return_type function_sil params_sil sil_loc let create_call_instr trans_state return_type function_sil params_sil sil_loc
call_flags ~is_objc_method = call_flags ~is_objc_method =
let ret_id = if (Sil.typ_equal return_type Sil.Tvoid) then [] let ret_id = if (Sil.typ_equal return_type Sil.Tvoid) then []
@ -374,7 +382,7 @@ struct
| _ -> empty_res_trans | _ -> empty_res_trans
let implicitValueInitExpr_trans trans_state expr_info = let implicitValueInitExpr_trans trans_state expr_info =
let (var_exp, _) = extract_var_exp_of_fail trans_state in let (var_exp, _) = extract_var_exp_or_fail trans_state in
let tenv = trans_state.context.CContext.tenv in let tenv = trans_state.context.CContext.tenv in
let typ = CTypes_decl.get_type_from_expr_info expr_info trans_state.context.CContext.tenv in let typ = CTypes_decl.get_type_from_expr_info expr_info trans_state.context.CContext.tenv in
let exps = var_or_zero_in_init_list tenv var_exp typ ~return_zero:true in let exps = var_or_zero_in_init_list tenv var_exp typ ~return_zero:true in
@ -1513,9 +1521,13 @@ struct
and initListExpr_trans trans_state stmt_info expr_info stmts = and initListExpr_trans trans_state stmt_info expr_info stmts =
let context = trans_state.context in let context = trans_state.context in
let tenv = context.tenv in let tenv = context.tenv in
let (var_exp, typ) =
match trans_state.var_exp_typ with
| Some var_exp_typ -> var_exp_typ
| None -> create_var_exp_tmp_var trans_state expr_info "SIL_init_list__" in
let trans_state = { trans_state with var_exp_typ = Some (var_exp, typ) } in
let trans_state_pri = PriorityNode.try_claim_priority_node trans_state stmt_info in let trans_state_pri = PriorityNode.try_claim_priority_node trans_state stmt_info in
let sil_loc = CLocation.get_sil_location stmt_info context in let sil_loc = CLocation.get_sil_location stmt_info context in
let var_exp, _ = extract_var_exp_of_fail trans_state in
let var_type = let var_type =
CTypes_decl.type_ptr_to_sil_type context.CContext.tenv expr_info.Clang_ast_t.ei_type_ptr in CTypes_decl.type_ptr_to_sil_type context.CContext.tenv expr_info.Clang_ast_t.ei_type_ptr in
let lh = var_or_zero_in_init_list tenv var_exp var_type ~return_zero:false in let lh = var_or_zero_in_init_list tenv var_exp var_type ~return_zero:false in
@ -1955,12 +1967,7 @@ struct
let var_exp_typ = let var_exp_typ =
if Option.is_some trans_state.var_exp_typ then trans_state.var_exp_typ if Option.is_some trans_state.var_exp_typ then trans_state.var_exp_typ
else else
let context = trans_state.context in Some (create_var_exp_tmp_var trans_state expr_info "SIL_compound_literal__") in
let procdesc = context.CContext.procdesc in
let (pvar, typ) = mk_temp_sil_var_for_expr context.CContext.tenv procdesc
"SIL_compound_literal__" expr_info in
Cfg.Procdesc.append_locals procdesc [(Sil.pvar_get_name pvar, typ)];
Some (Sil.Lvar pvar, typ) in
let trans_state' = { trans_state with var_exp_typ = var_exp_typ } in let trans_state' = { trans_state with var_exp_typ = var_exp_typ } in
instruction trans_state' stmt instruction trans_state' stmt

@ -184,7 +184,7 @@ let collect_res_trans l =
is_cpp_call_virtual = false; } in is_cpp_call_virtual = false; } in
collect l empty_res_trans collect l empty_res_trans
let extract_var_exp_of_fail transt_state = let extract_var_exp_or_fail transt_state =
match transt_state.var_exp_typ with match transt_state.var_exp_typ with
| Some var_exp_typ -> var_exp_typ | Some var_exp_typ -> var_exp_typ
| None -> assert false | None -> assert false

@ -41,7 +41,7 @@ val empty_res_trans: trans_result
val collect_res_trans : trans_result list -> trans_result val collect_res_trans : trans_result list -> trans_result
val extract_var_exp_of_fail : trans_state -> Sil.exp * Sil.typ val extract_var_exp_or_fail : trans_state -> Sil.exp * Sil.typ
val is_return_temp: continuation option -> bool val is_return_temp: continuation option -> bool

@ -0,0 +1,17 @@
/*
* Copyright (c) 2016 - 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.
*/
typedef struct { int top, left, bottom, right; } Insets;
struct Person {
int age;
Person(const Insets l) : age(l.top) {}
};
void test() { Person p({}); }

@ -0,0 +1,24 @@
digraph iCFG {
6 [label="6: DeclStmt \n *&SIL_init_list__n$0.top:int =0 [line 17]\n *&SIL_init_list__n$0.left:int =0 [line 17]\n *&SIL_init_list__n$0.bottom:int =0 [line 17]\n *&SIL_init_list__n$0.right:int =0 [line 17]\n _fun_Person_Person(&p:class Person *,&SIL_init_list__n$0:class Insets ) [line 17]\n NULLIFY(&SIL_init_list__n$0,false); [line 17]\n NULLIFY(&p,false); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"]
6 -> 5 ;
5 [label="5: Exit test \n " color=yellow style=filled]
4 [label="4: Start test\nFormals: \nLocals: p:class Person SIL_init_list__n$0:class Insets \n DECLARE_LOCALS(&return,&p,&SIL_init_list__n$0); [line 17]\n " color=yellow style=filled]
4 -> 6 ;
3 [label="3: Constructor Init \n n$0=*&this:class Person * [line 14]\n n$1=*&l.top:int [line 14]\n *n$0.age:int =n$1 [line 14]\n REMOVE_TEMPS(n$0,n$1); [line 14]\n NULLIFY(&l,false); [line 14]\n NULLIFY(&this,false); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"]
3 -> 2 ;
2 [label="2: Exit Person_Person \n " color=yellow style=filled]
1 [label="1: Start Person_Person\nFormals: this:class Person * l:class Insets \nLocals: \n DECLARE_LOCALS(&return); [line 14]\n " color=yellow style=filled]
1 -> 3 ;
}

@ -64,4 +64,10 @@ public class ConstructorsTest {
throws InterruptedException, IOException, InferException { throws InterruptedException, IOException, InferException {
frontendTest("default_field_init.cpp"); frontendTest("default_field_init.cpp");
} }
@Test
public void testConstructorInitListDotFilesMatch()
throws InterruptedException, IOException, InferException {
frontendTest("constructor_struct_init_list.cpp");
}
} }

Loading…
Cancel
Save