Ignore type change in UncheckedDerivedToBase cast

Summary: public
Infer gets confused with this cast. It happens when objects try
to access superclass field/method, but we shouldn't change type in
this case (for the sake of backend)

Reviewed By: dulmarod

Differential Revision: D2663905

fb-gh-sync-id: bbf1cb2
master
Andrzej Kotulski 9 years ago committed by facebook-github-bot-7
parent b598c747b5
commit 1eecdacea6

@ -1751,7 +1751,7 @@ struct
leaf_nodes = res_trans_stmt.leaf_nodes; leaf_nodes = res_trans_stmt.leaf_nodes;
ids = res_trans_stmt.ids @ cast_ids; ids = res_trans_stmt.ids @ cast_ids;
instrs = res_trans_stmt.instrs @ cast_inst; instrs = res_trans_stmt.instrs @ cast_inst;
exps = [(cast_exp, typ)] } exps = [cast_exp] }
(* function used in the computation for both Member_Expr and ObjCIVarRefExpr *) (* function used in the computation for both Member_Expr and ObjCIVarRefExpr *)
and do_memb_ivar_ref_exp trans_state expr_info stmt_info stmt_list decl_ref = and do_memb_ivar_ref_exp trans_state expr_info stmt_info stmt_list decl_ref =

@ -385,27 +385,33 @@ let dereference_value_from_result sil_loc trans_result ~strip_pointer =
let cast_operation context cast_kind exps cast_typ sil_loc is_objc_bridged = let cast_operation context cast_kind exps cast_typ sil_loc is_objc_bridged =
let (exp, typ) = extract_exp_from_list exps "" in let (exp, typ) = extract_exp_from_list exps "" in
let exp_typ = match cast_kind with
| `UncheckedDerivedToBase -> typ (* This cast ignores change of type *)
| _ -> cast_typ (* by default use the return type of cast expr *) in
if is_objc_bridged then if is_objc_bridged then
let id, instr, exp = create_cast_instrs context exp typ cast_typ sil_loc in let id, instr, exp = create_cast_instrs context exp typ cast_typ sil_loc in
[id], [instr], exp [id], [instr], (exp, exp_typ)
else else
match cast_kind with match cast_kind with
| `NoOp | `NoOp
| `BitCast | `BitCast
| `IntegralCast | `IntegralCast
| `DerivedToBase
| `UncheckedDerivedToBase
| `IntegralToBoolean -> (* This is treated as a nop by returning the same expressions exps*) | `IntegralToBoolean -> (* This is treated as a nop by returning the same expressions exps*)
([],[], exp) ([], [], (exp, exp_typ))
| `LValueToRValue -> | `LValueToRValue ->
(* Takes an LValue and allow it to use it as RValue. *) (* Takes an LValue and allow it to use it as RValue. *)
(* So we assign the LValue to a temp and we pass it to the parent.*) (* So we assign the LValue to a temp and we pass it to the parent.*)
dereference_var_sil (exp, typ) sil_loc let ids, instrs, deref_exp = dereference_var_sil (exp, typ) sil_loc in
ids, instrs, (deref_exp, exp_typ)
| `CPointerToObjCPointerCast -> | `CPointerToObjCPointerCast ->
([], [], Sil.Cast(typ, exp)) [], [], (Sil.Cast(typ, exp), exp_typ)
| _ -> | _ ->
Printing.log_err Printing.log_err
"\nWARNING: Missing translation for Cast Kind %s. The construct has been ignored...\n" "\nWARNING: Missing translation for Cast Kind %s. The construct has been ignored...\n"
(Clang_ast_j.string_of_cast_kind cast_kind); (Clang_ast_j.string_of_cast_kind cast_kind);
([],[], exp) ([],[], (exp, exp_typ))
let trans_assertion_failure sil_loc context = let trans_assertion_failure sil_loc context =
let assert_fail_builtin = Sil.Const (Sil.Cfun SymExec.ModelBuiltins.__infer_fail) in let assert_fail_builtin = Sil.Const (Sil.Cfun SymExec.ModelBuiltins.__infer_fail) in

@ -81,7 +81,7 @@ val dereference_value_from_result : Location.t -> trans_result -> strip_pointer:
val cast_operation : val cast_operation :
CContext.t -> Clang_ast_t.cast_kind -> (Sil.exp * Sil.typ) list -> Sil.typ -> Location.t -> CContext.t -> Clang_ast_t.cast_kind -> (Sil.exp * Sil.typ) list -> Sil.typ -> Location.t ->
bool -> Ident.t list * Sil.instr list * Sil.exp bool -> Ident.t list * Sil.instr list * (Sil.exp * Sil.typ)
val trans_assertion_failure : Location.t -> CContext.t -> trans_result val trans_assertion_failure : Location.t -> CContext.t -> trans_result

@ -19,7 +19,7 @@ digraph iCFG {
20 -> 19 ; 20 -> 19 ;
19 [label="19: Call _fun_Base_fun \n n$6=*&s2:class Sub * [line 28]\n n$7=_fun_Base_fun(n$6:class Base *) [line 28]\n REMOVE_TEMPS(n$6,n$7); [line 28]\n " shape="box"] 19 [label="19: Call _fun_Base_fun \n n$6=*&s2:class Sub * [line 28]\n n$7=_fun_Base_fun(n$6:class Sub *) [line 28]\n REMOVE_TEMPS(n$6,n$7); [line 28]\n " shape="box"]
19 -> 18 ; 19 -> 18 ;

@ -46,6 +46,17 @@ int div0_cast_ref(Sub s) {
return 1 / b.b1; return 1 / b.b1;
} }
int div0_b1_s(Sub *s) {
s->b1 = 1;
s->s = 1;
return 1 / (s->b1 - s->s);
}
int div0_s_b1(Sub *s) {
s->b1 = 1;
s->s = 1;
return 1 / (s->b1 - s->s);
}
int div1_b1(Sub s) { int div1_b1(Sub s) {
s.b1 = 1; s.b1 = 1;
@ -57,4 +68,3 @@ int div1_cast(Sub *s) {
Base1 *b = s; Base1 *b = s;
return 1 / b->b1; return 1 / b->b1;
} }

@ -1,38 +1,76 @@
digraph iCFG { digraph iCFG {
31 [label="31: BinaryOperatorStmt: Assign \n n$3=*&s:class Sub * [line 56]\n *n$3.b1:int =1 [line 56]\n REMOVE_TEMPS(n$3); [line 56]\n " shape="box"] 41 [label="41: BinaryOperatorStmt: Assign \n n$3=*&s:class Sub * [line 67]\n *n$3.b1:int =1 [line 67]\n REMOVE_TEMPS(n$3); [line 67]\n " shape="box"]
41 -> 40 ;
40 [label="40: DeclStmt \n n$2=*&s:class Sub * [line 68]\n *&b:struct Base1 *=n$2 [line 68]\n REMOVE_TEMPS(n$2); [line 68]\n NULLIFY(&s,false); [line 68]\n " shape="box"]
40 -> 39 ;
39 [label="39: Return Stmt \n n$0=*&b:struct Base1 * [line 69]\n n$1=*n$0.b1:int [line 69]\n *&return:int =(1 / n$1) [line 69]\n REMOVE_TEMPS(n$0,n$1); [line 69]\n NULLIFY(&b,false); [line 69]\n APPLY_ABSTRACTION; [line 69]\n " shape="box"]
39 -> 38 ;
38 [label="38: Exit div1_cast \n " color=yellow style=filled]
37 [label="37: Start div1_cast\nFormals: s:class Sub *\nLocals: b:struct Base1 * \n DECLARE_LOCALS(&return,&b); [line 66]\n NULLIFY(&b,false); [line 66]\n " color=yellow style=filled]
37 -> 41 ;
36 [label="36: BinaryOperatorStmt: Assign \n *&s.b1:int =1 [line 62]\n " shape="box"]
36 -> 35 ;
35 [label="35: Return Stmt \n n$0=*&s.b1:int [line 63]\n *&return:int =(1 / n$0) [line 63]\n REMOVE_TEMPS(n$0); [line 63]\n NULLIFY(&s,false); [line 63]\n APPLY_ABSTRACTION; [line 63]\n " shape="box"]
35 -> 34 ;
34 [label="34: Exit div1_b1 \n " color=yellow style=filled]
33 [label="33: Start div1_b1\nFormals: s:class Sub \nLocals: \n DECLARE_LOCALS(&return); [line 61]\n " color=yellow style=filled]
33 -> 36 ;
32 [label="32: BinaryOperatorStmt: Assign \n n$5=*&s:class Sub * [line 56]\n *n$5.b1:int =1 [line 56]\n REMOVE_TEMPS(n$5); [line 56]\n " shape="box"]
32 -> 31 ;
31 [label="31: BinaryOperatorStmt: Assign \n n$4=*&s:class Sub * [line 57]\n *n$4.s:int =1 [line 57]\n REMOVE_TEMPS(n$4); [line 57]\n " shape="box"]
31 -> 30 ; 31 -> 30 ;
30 [label="30: DeclStmt \n n$2=*&s:class Sub * [line 57]\n *&b:struct Base1 *=n$2 [line 57]\n REMOVE_TEMPS(n$2); [line 57]\n NULLIFY(&s,false); [line 57]\n " shape="box"] 30 [label="30: Return Stmt \n n$0=*&s:class Sub * [line 58]\n n$1=*n$0.b1:int [line 58]\n n$2=*&s:class Sub * [line 58]\n n$3=*n$2.s:int [line 58]\n *&return:int =(1 / (n$1 - n$3)) [line 58]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 58]\n NULLIFY(&s,false); [line 58]\n APPLY_ABSTRACTION; [line 58]\n " shape="box"]
30 -> 29 ; 30 -> 29 ;
29 [label="29: Return Stmt \n n$0=*&b:struct Base1 * [line 58]\n n$1=*n$0.b1:int [line 58]\n *&return:int =(1 / n$1) [line 58]\n REMOVE_TEMPS(n$0,n$1); [line 58]\n NULLIFY(&b,false); [line 58]\n APPLY_ABSTRACTION; [line 58]\n " shape="box"] 29 [label="29: Exit div0_s_b1 \n " color=yellow style=filled]
29 -> 28 ; 28 [label="28: Start div0_s_b1\nFormals: s:class Sub *\nLocals: \n DECLARE_LOCALS(&return); [line 55]\n " color=yellow style=filled]
28 [label="28: Exit div1_cast \n " color=yellow style=filled]
27 [label="27: Start div1_cast\nFormals: s:class Sub *\nLocals: b:struct Base1 * \n DECLARE_LOCALS(&return,&b); [line 55]\n NULLIFY(&b,false); [line 55]\n " color=yellow style=filled] 28 -> 32 ;
27 [label="27: BinaryOperatorStmt: Assign \n n$5=*&s:class Sub * [line 50]\n *n$5.b1:int =1 [line 50]\n REMOVE_TEMPS(n$5); [line 50]\n " shape="box"]
27 -> 31 ; 27 -> 26 ;
26 [label="26: BinaryOperatorStmt: Assign \n *&s.b1:int =1 [line 51]\n " shape="box"] 26 [label="26: BinaryOperatorStmt: Assign \n n$4=*&s:class Sub * [line 51]\n *n$4.s:int =1 [line 51]\n REMOVE_TEMPS(n$4); [line 51]\n " shape="box"]
26 -> 25 ; 26 -> 25 ;
25 [label="25: Return Stmt \n n$0=*&s.b1:int [line 52]\n *&return:int =(1 / n$0) [line 52]\n REMOVE_TEMPS(n$0); [line 52]\n NULLIFY(&s,false); [line 52]\n APPLY_ABSTRACTION; [line 52]\n " shape="box"] 25 [label="25: Return Stmt \n n$0=*&s:class Sub * [line 52]\n n$1=*n$0.b1:int [line 52]\n n$2=*&s:class Sub * [line 52]\n n$3=*n$2.s:int [line 52]\n *&return:int =(1 / (n$1 - n$3)) [line 52]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 52]\n NULLIFY(&s,false); [line 52]\n APPLY_ABSTRACTION; [line 52]\n " shape="box"]
25 -> 24 ; 25 -> 24 ;
24 [label="24: Exit div1_b1 \n " color=yellow style=filled] 24 [label="24: Exit div0_b1_s \n " color=yellow style=filled]
23 [label="23: Start div1_b1\nFormals: s:class Sub \nLocals: \n DECLARE_LOCALS(&return); [line 50]\n " color=yellow style=filled] 23 [label="23: Start div0_b1_s\nFormals: s:class Sub *\nLocals: \n DECLARE_LOCALS(&return); [line 49]\n " color=yellow style=filled]
23 -> 26 ; 23 -> 27 ;
22 [label="22: BinaryOperatorStmt: Assign \n *&s.b1:int =0 [line 44]\n " shape="box"] 22 [label="22: BinaryOperatorStmt: Assign \n *&s.b1:int =0 [line 44]\n " shape="box"]

@ -10,7 +10,7 @@ digraph iCFG {
25 -> 27 ; 25 -> 27 ;
24 [label="24: Return Stmt \n n$0=*&y:class Y & [line 48]\n n$1=_fun_X_operator[](n$0:class X &,0:int ) [line 48]\n *&return:int =(1 / n$1) [line 48]\n REMOVE_TEMPS(n$0,n$1); [line 48]\n NULLIFY(&y,false); [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"] 24 [label="24: Return Stmt \n n$0=*&y:class Y & [line 48]\n n$1=_fun_X_operator[](n$0:class Y &,0:int ) [line 48]\n *&return:int =(1 / n$1) [line 48]\n REMOVE_TEMPS(n$0,n$1); [line 48]\n NULLIFY(&y,false); [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"]
24 -> 23 ; 24 -> 23 ;

@ -53,6 +53,8 @@ public class InheritanceFieldTest {
"div0_s", "div0_s",
"div0_cast", "div0_cast",
"div0_cast_ref", "div0_cast_ref",
"div0_b1_s",
"div0_s_b1",
}; };
assertThat( assertThat(
"Results should contain the expected divide by zero", "Results should contain the expected divide by zero",

Loading…
Cancel
Save