translate CompoundLiteralExpr

Reviewed By: dulmarod

Differential Revision: D2839164

fb-gh-sync-id: e9a3f69
master
Jules Villard 9 years ago committed by facebook-github-bot-7
parent f04c979563
commit 7b9b6841d2

@ -224,6 +224,15 @@ struct
f trans_state e f trans_state e
else f { trans_state with priority = Free } e else f { trans_state with priority = Free } e
let mk_temp_sil_var_for_expr tenv procdesc var_name_prefix expr_info =
let procname = Cfg.Procdesc.get_proc_name procdesc in
let id = Ident.create_fresh Ident.knormal in
let pvar_mangled = Mangled.from_string (var_name_prefix ^ Ident.to_string id) in
let pvar = Sil.mk_pvar pvar_mangled procname in
let type_ptr = expr_info.Clang_ast_t.ei_type_ptr in
let typ = CTypes_decl.type_ptr_to_sil_type tenv type_ptr in
(pvar, typ)
let breakStmt_trans trans_state = let breakStmt_trans trans_state =
match trans_state.continuation with match trans_state.continuation with
| Some bn -> { empty_res_trans with root_nodes = bn.break } | Some bn -> { empty_res_trans with root_nodes = bn.break }
@ -1447,6 +1456,7 @@ struct
| _ -> Printing.log_stats "\n!!!!WARNING: found statement <\"ImplicitValueInitExpr\"> with non-empty stmt_list.\n"); | _ -> Printing.log_stats "\n!!!!WARNING: found statement <\"ImplicitValueInitExpr\"> with non-empty stmt_list.\n");
{ empty_res_trans with root_nodes = trans_state.succ_nodes } { empty_res_trans with root_nodes = trans_state.succ_nodes }
| Some (InitListExpr (stmt_info , stmts , expr_info)) | Some (InitListExpr (stmt_info , stmts , expr_info))
| Some (ImplicitCastExpr (_, [CompoundLiteralExpr (_, [InitListExpr (stmt_info , stmts , expr_info)], _)], _, _))
| Some (ExprWithCleanups (_, [InitListExpr (stmt_info , stmts , expr_info)], _, _)) -> | Some (ExprWithCleanups (_, [InitListExpr (stmt_info , stmts , expr_info)], _, _)) ->
initListExpr_trans trans_state var_res_trans stmt_info expr_info stmts initListExpr_trans trans_state var_res_trans stmt_info expr_info stmts
| Some (CXXConstructExpr _ as expr) -> | Some (CXXConstructExpr _ as expr) ->
@ -1809,20 +1819,24 @@ struct
and materializeTemporaryExpr_trans trans_state stmt_info stmt_list expr_info = and materializeTemporaryExpr_trans trans_state stmt_info stmt_list expr_info =
let context = trans_state.context in let context = trans_state.context in
let procdesc = context.CContext.procdesc in let procdesc = context.CContext.procdesc in
let procname = Cfg.Procdesc.get_proc_name procdesc in let (pvar, typ) = mk_temp_sil_var_for_expr context.CContext.tenv procdesc
let temp_exp = match stmt_list with [p] -> p | _ -> assert false in "SIL_materialize_temp__" expr_info in
(* use id to create unique variable name within a function *)
let id = Ident.create_fresh Ident.knormal in
let pvar_mangled = Mangled.from_string ("SIL_materialize_temp__" ^ (Ident.to_string id)) in
let pvar = Sil.mk_pvar pvar_mangled procname in
let type_ptr = expr_info.Clang_ast_t.ei_type_ptr in
let typ = CTypes_decl.type_ptr_to_sil_type context.CContext.tenv type_ptr in
let typ_ptr = Sil.Tptr (typ, Sil.Pk_pointer) in let typ_ptr = Sil.Tptr (typ, Sil.Pk_pointer) in
let var_res_trans = { empty_res_trans with exps = [(Sil.Lvar pvar, typ_ptr)] } in let var_res_trans = { empty_res_trans with exps = [(Sil.Lvar pvar, typ_ptr)] } in
let temp_exp = match stmt_list with [p] -> p | _ -> assert false in
Cfg.Procdesc.append_locals procdesc [(Sil.pvar_get_name pvar, typ)]; Cfg.Procdesc.append_locals procdesc [(Sil.pvar_get_name pvar, typ)];
let res_trans = init_expr_trans trans_state var_res_trans stmt_info (Some temp_exp) in let res_trans = init_expr_trans trans_state var_res_trans stmt_info (Some temp_exp) in
{ res_trans with exps = [(Sil.Lvar pvar, typ)] } { res_trans with exps = [(Sil.Lvar pvar, typ)] }
and compoundLiteralExpr_trans trans_state stmt_info stmt_list expr_info =
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
"SIL_compound_literal__" expr_info in
let typ_ptr = Sil.Tptr (typ, Sil.Pk_pointer) in
let var_res_trans = { empty_res_trans with exps = [(Sil.Lvar pvar, typ_ptr)] } in
initListExpr_trans trans_state var_res_trans stmt_info expr_info stmt_list
(* Translates a clang instruction into SIL instructions. It takes a *) (* Translates a clang instruction into SIL instructions. It takes a *)
(* a trans_state containing current info on the translation and it returns *) (* a trans_state containing current info on the translation and it returns *)
(* a result_state.*) (* a result_state.*)
@ -2038,6 +2052,8 @@ struct
cxxDeleteExpr_trans trans_state stmt_info stmt_list expr_info delete_expr_info cxxDeleteExpr_trans trans_state stmt_info stmt_list expr_info delete_expr_info
| MaterializeTemporaryExpr (stmt_info, stmt_list, expr_info, _) -> | MaterializeTemporaryExpr (stmt_info, stmt_list, expr_info, _) ->
materializeTemporaryExpr_trans trans_state stmt_info stmt_list expr_info materializeTemporaryExpr_trans trans_state stmt_info stmt_list expr_info
| CompoundLiteralExpr (_, [InitListExpr (stmt_info , stmt_list , expr_info)], _) ->
compoundLiteralExpr_trans trans_state stmt_info stmt_list expr_info
| s -> (Printing.log_stats | s -> (Printing.log_stats
"\n!!!!WARNING: found statement %s. \nACTION REQUIRED: Translation need to be defined. Statement ignored.... \n" "\n!!!!WARNING: found statement %s. \nACTION REQUIRED: Translation need to be defined. Statement ignored.... \n"
(Ast_utils.string_of_stmt s); (Ast_utils.string_of_stmt s);

@ -0,0 +1,22 @@
/*
* 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.
*/
struct point {
int x;
int y;
};
int compound_literal_expr() {
return ((struct point) { .y = 32, .x = 52 }).x;
}
int init_with_compound_literal() {
struct point p = (struct point) { 32, 52 };
return p.x;
}

@ -0,0 +1,28 @@
digraph iCFG {
7 [label="7: InitListExp \n *&p.x:int =32 [line 20]\n *&p.y:int =52 [line 20]\n " shape="box"]
7 -> 6 ;
6 [label="6: Return Stmt \n n$0=*&p.x:int [line 21]\n *&return:int =n$0 [line 21]\n REMOVE_TEMPS(n$0); [line 21]\n NULLIFY(&p,false); [line 21]\n APPLY_ABSTRACTION; [line 21]\n " shape="box"]
6 -> 5 ;
5 [label="5: Exit init_with_compound_literal \n " color=yellow style=filled]
4 [label="4: Start init_with_compound_literal\nFormals: \nLocals: p:struct point \n DECLARE_LOCALS(&return,&p); [line 19]\n " color=yellow style=filled]
4 -> 7 ;
3 [label="3: Return Stmt \n *&SIL_compound_literal__n$0.x:int =52 [line 16]\n *&SIL_compound_literal__n$0.y:int =32 [line 16]\n n$1=*&SIL_compound_literal__n$0.x:int [line 16]\n *&return:int =n$1 [line 16]\n REMOVE_TEMPS(n$1); [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"]
3 -> 2 ;
2 [label="2: Exit compound_literal_expr \n " color=yellow style=filled]
1 [label="1: Start compound_literal_expr\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 15]\n " color=yellow style=filled]
1 -> 3 ;
}

@ -40,4 +40,11 @@ public class InitListExprTest {
throws InterruptedException, IOException, InferException { throws InterruptedException, IOException, InferException {
frontendTest("struct_initlistexpr.c"); frontendTest("struct_initlistexpr.c");
} }
@Test
public void whenCaptureRunOnCompoundLiteralExprThenDotFilesAreTheSame()
throws InterruptedException, IOException, InferException {
frontendTest("compound_literal.c");
}
} }

Loading…
Cancel
Save