From a6757be0367438afe73e0d989ebb84b3aa5814f5 Mon Sep 17 00:00:00 2001 From: Jia Chen Date: Wed, 21 Jun 2017 10:22:28 -0700 Subject: [PATCH] Force emitting prune node for C++ comparison expressions Summary: This diff tries to achieve the followings: if we have the following C++ codes: ``` bool foo(int x, int y) { return &x == &y; } ``` We want the C++ frontend to emit Sil as if the input is written as ``` bool foo(int x, int y) { if (&x == &y) return 1; else return 0; } ``` This matches the behavior of our Java frontend. The reason why we prefer an explicit branch is that it will force the backend to eagerly produce two different specs for `foo`. Without the explicit branch, for the above example the backend would produce one spec with `return = (&x == &y)` as the post condition, which is not ideal because (1) we don't want local variables to escape to the function summary, and (2) with the knowledge that no two local variables may alias each other, the backend could actually determines that `&x == &y` is always false, emitting a more precise postcondition `return = 0`. This is not possible if we do not eagerly resolve the comparison expression. Reviewed By: akotulski Differential Revision: D5260745 fbshipit-source-id: 6bbbf99 --- infer/src/clang/ast_expressions.ml | 7 +- infer/src/clang/ast_expressions.mli | 5 +- infer/src/clang/cTrans.ml | 46 ++++++++----- .../booleans/condition_as_param.c.dot | 37 +++++++++-- .../cpp/frontend/loops/foreach1.cpp.dot | 33 ++++++++-- .../cpp/shared/types/typeid_expr.cpp.dot | 66 ++++++++++++++++--- .../codetoanalyze/objc/errors/issues.exp | 6 +- 7 files changed, 161 insertions(+), 39 deletions(-) diff --git a/infer/src/clang/ast_expressions.ml b/infer/src/clang/ast_expressions.ml index f64fd8cb5..4cd2af84e 100644 --- a/infer/src/clang/ast_expressions.ml +++ b/infer/src/clang/ast_expressions.ml @@ -568,7 +568,12 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = (Clang_ast_j.string_of_stmt_info stmt_info); CompoundStmt (stmt_info, stmt_list), [] -(* We translate the logical negation of an integer with a conditional*) +(* We translate an expression with a conditional*) +(* x <=> x?1:0 *) +let trans_with_conditional stmt_info expr_info stmt_list = + let stmt_list_cond = stmt_list @ [create_integer_literal "1"] @ [create_integer_literal "0"] in + Clang_ast_t.ConditionalOperator (stmt_info, stmt_list_cond, expr_info) +(* We translate the logical negation of an expression with a conditional*) (* !x <=> x?0:1 *) let trans_negation_with_conditional stmt_info expr_info stmt_list = let stmt_list_cond = stmt_list @ [create_integer_literal "0"] @ [create_integer_literal "1"] in diff --git a/infer/src/clang/ast_expressions.mli b/infer/src/clang/ast_expressions.mli index 03b446cb9..e1a90fba7 100644 --- a/infer/src/clang/ast_expressions.mli +++ b/infer/src/clang/ast_expressions.mli @@ -60,6 +60,9 @@ val translate_dispatch_function : stmt_info -> stmt list -> int -> stmt val translate_block_enumerate : string -> stmt_info -> stmt list -> expr_info -> stmt * (string * Clang_ast_t.pointer * qual_type) list -(* We translate the logical negation of an integer with a conditional*) +(* We translate an expression with a conditional*) +(* x <=> x?1:0 *) +val trans_with_conditional : stmt_info -> expr_info -> stmt list -> stmt +(* We translate the logical negation of an expression with a conditional*) (* !x <=> x?0:1 *) val trans_negation_with_conditional : stmt_info -> expr_info -> stmt list -> stmt diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 67b974309..63420746b 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -1206,13 +1206,27 @@ struct extract_exp_from_list el "@\nWARNING: Missing expression for Conditional operator. Need to be fixed" in (* this function translate cond without doing shortcircuit *) - let no_short_circuit_cond () = + let no_short_circuit_cond ~is_cmp = L.(debug Capture Verbose) " No short-circuit condition@\n"; let res_trans_cond = if is_null_stmt cond then { empty_res_trans with exps = [(Exp.Const (Const.Cint IntLit.one), Typ.mk (Tint Typ.IBool))] } (* Assumption: If it's a null_stmt, it is a loop with no bound, so we set condition to 1 *) + else + if is_cmp then + let open Clang_ast_t in + (* If we have a comparision here, do not dispatch it to `instruction` function, which + * invokes binaryOperator_trans_with_cond -> conditionalOperator_trans -> cond_trans. + * This will throw the translation process into an infinite loop immediately. + * Instead, dispatch to binaryOperator_trans directly. *) + (* If one wants to add a new kind of `BinaryOperator` that will have the same behavior, + * she need to change both the codes here and the `match` in + * binaryOperator_trans_with_cond *) + match cond with + | BinaryOperator (si, ss, ei, boi) -> + binaryOperator_trans trans_state boi si ei ss + | _ -> instruction trans_state cond else instruction trans_state cond in let e', instrs' = @@ -1276,10 +1290,12 @@ struct (match boi.Clang_ast_t.boi_kind with | `LAnd -> short_circuit (Binop.LAnd) s1 s2 | `LOr -> short_circuit (Binop.LOr) s1 s2 - | _ -> no_short_circuit_cond ()) + | `LT | `GT | `LE | `GE | `EQ | `NE -> + no_short_circuit_cond ~is_cmp:true + | _ -> no_short_circuit_cond ~is_cmp:false) | ParenExpr(_,[s], _) -> (* condition can be wrapped in parenthesys *) cond_trans trans_state s - | _ -> no_short_circuit_cond () + | _ -> no_short_circuit_cond ~is_cmp:false and declStmt_in_condition_trans trans_state decl_stmt res_trans_cond = match decl_stmt with @@ -2370,19 +2386,17 @@ struct let trans_state' = { trans_state with obj_bridged_cast_typ = Some typ } in instruction trans_state' stmt - and binaryOperator_trans_shortc trans_state stmt_info stmt_list expr_info binary_operator_info = + and binaryOperator_trans_with_cond trans_state stmt_info stmt_list expr_info binop_info = let open Clang_ast_t in - match binary_operator_info.boi_kind with - | `LAnd | `LOr -> - (* For LAnd/LOr we compiles a binary expression bo into an semantic equivalent - conditional operator 'bo ? 1:0'. + match binop_info.boi_kind with + | `LAnd | `LOr | `LT | `GT | `LE | `GE | `EQ | `NE -> + (* For LAnd/LOr/comparison operators we compiles a binary expression bo into an semantic + equivalent conditional operator 'bo ? 1:0'. The conditional operator takes care of shortcircuit when/where needed *) - let bo = BinaryOperator (stmt_info, stmt_list, expr_info, binary_operator_info) in - let stmt_list' = - [bo; Ast_expressions.create_integer_literal "1"; Ast_expressions.create_integer_literal "0"] in - conditionalOperator_trans trans_state stmt_info stmt_list' expr_info - | _ -> binaryOperator_trans trans_state binary_operator_info stmt_info expr_info stmt_list - + let bo = BinaryOperator (stmt_info, stmt_list, expr_info, binop_info) in + let cond = Ast_expressions.trans_with_conditional stmt_info expr_info [bo] in + instruction trans_state cond + | _ -> binaryOperator_trans trans_state binop_info stmt_info expr_info stmt_list and attributedStmt_trans trans_state stmts attrs = let open Clang_ast_t in match stmts, attrs with @@ -2416,8 +2430,8 @@ struct | ArraySubscriptExpr(_, stmt_list, expr_info) -> arraySubscriptExpr_trans trans_state expr_info stmt_list - | BinaryOperator (stmt_info, stmt_list, expr_info, binary_operator_info) -> - binaryOperator_trans_shortc trans_state stmt_info stmt_list expr_info binary_operator_info + | BinaryOperator (stmt_info, stmt_list, expr_info, binop_info) -> + binaryOperator_trans_with_cond trans_state stmt_info stmt_list expr_info binop_info | CallExpr(stmt_info, stmt_list, ei) -> (match is_dispatch_function stmt_list with diff --git a/infer/tests/codetoanalyze/c/frontend/booleans/condition_as_param.c.dot b/infer/tests/codetoanalyze/c/frontend/booleans/condition_as_param.c.dot index 9423fde77..0a4b09fef 100644 --- a/infer/tests/codetoanalyze/c/frontend/booleans/condition_as_param.c.dot +++ b/infer/tests/codetoanalyze/c/frontend/booleans/condition_as_param.c.dot @@ -1,20 +1,45 @@ /* @generated */ digraph iCFG { -"main.fad58de7366495db4650cfefac2fcd61_1" [label="1: Start main\nFormals: \nLocals: x:int \n DECLARE_LOCALS(&return,&x); [line 12]\n " color=yellow style=filled] +"main.fad58de7366495db4650cfefac2fcd61_1" [label="1: Start main\nFormals: \nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$0:int x:int \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$0,&x); [line 12]\n " color=yellow style=filled] - "main.fad58de7366495db4650cfefac2fcd61_1" -> "main.fad58de7366495db4650cfefac2fcd61_4" ; + "main.fad58de7366495db4650cfefac2fcd61_1" -> "main.fad58de7366495db4650cfefac2fcd61_10" ; "main.fad58de7366495db4650cfefac2fcd61_2" [label="2: Exit main \n " color=yellow style=filled] -"main.fad58de7366495db4650cfefac2fcd61_3" [label="3: Call _fun_check \n n$0=*&x:int [line 14]\n _fun_check((n$0 < 2):int) [line 14]\n " shape="box"] +"main.fad58de7366495db4650cfefac2fcd61_3" [label="3: + \n " ] - "main.fad58de7366495db4650cfefac2fcd61_3" -> "main.fad58de7366495db4650cfefac2fcd61_2" ; -"main.fad58de7366495db4650cfefac2fcd61_4" [label="4: DeclStmt \n *&x:int=3 [line 13]\n " shape="box"] + "main.fad58de7366495db4650cfefac2fcd61_3" -> "main.fad58de7366495db4650cfefac2fcd61_9" ; +"main.fad58de7366495db4650cfefac2fcd61_4" [label="4: BinaryOperatorStmt: LT \n n$1=*&x:int [line 14]\n " shape="box"] - "main.fad58de7366495db4650cfefac2fcd61_4" -> "main.fad58de7366495db4650cfefac2fcd61_3" ; + "main.fad58de7366495db4650cfefac2fcd61_4" -> "main.fad58de7366495db4650cfefac2fcd61_5" ; + "main.fad58de7366495db4650cfefac2fcd61_4" -> "main.fad58de7366495db4650cfefac2fcd61_6" ; +"main.fad58de7366495db4650cfefac2fcd61_5" [label="5: Prune (true branch) \n PRUNE(((n$1 < 2) != 0), true); [line 14]\n " shape="invhouse"] + + + "main.fad58de7366495db4650cfefac2fcd61_5" -> "main.fad58de7366495db4650cfefac2fcd61_7" ; +"main.fad58de7366495db4650cfefac2fcd61_6" [label="6: Prune (false branch) \n PRUNE(((n$1 < 2) == 0), false); [line 14]\n " shape="invhouse"] + + + "main.fad58de7366495db4650cfefac2fcd61_6" -> "main.fad58de7366495db4650cfefac2fcd61_8" ; +"main.fad58de7366495db4650cfefac2fcd61_7" [label="7: ConditinalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$0:int=1 [line 14]\n " shape="box"] + + + "main.fad58de7366495db4650cfefac2fcd61_7" -> "main.fad58de7366495db4650cfefac2fcd61_3" ; +"main.fad58de7366495db4650cfefac2fcd61_8" [label="8: ConditinalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$0:int=0 [line 14]\n " shape="box"] + + + "main.fad58de7366495db4650cfefac2fcd61_8" -> "main.fad58de7366495db4650cfefac2fcd61_3" ; +"main.fad58de7366495db4650cfefac2fcd61_9" [label="9: Call _fun_check \n n$2=*&0$?%__sil_tmpSIL_temp_conditional___n$0:int [line 14]\n _fun_check(n$2:int) [line 14]\n " shape="box"] + + + "main.fad58de7366495db4650cfefac2fcd61_9" -> "main.fad58de7366495db4650cfefac2fcd61_2" ; +"main.fad58de7366495db4650cfefac2fcd61_10" [label="10: DeclStmt \n *&x:int=3 [line 13]\n " shape="box"] + + + "main.fad58de7366495db4650cfefac2fcd61_10" -> "main.fad58de7366495db4650cfefac2fcd61_4" ; "check.0ba4439ee9a46d9d9f14c60f88f45f87_1" [label="1: Start check\nFormals: x:int\nLocals: \n DECLARE_LOCALS(&return); [line 10]\n " color=yellow style=filled] diff --git a/infer/tests/codetoanalyze/cpp/frontend/loops/foreach1.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/loops/foreach1.cpp.dot index eaf6eb711..ac79c6878 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/loops/foreach1.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/loops/foreach1.cpp.dot @@ -52,17 +52,42 @@ digraph iCFG { "test#_Z4testv.1b928d988491fdd2fa78fcb048d46e8c_13" -> "test#_Z4testv.1b928d988491fdd2fa78fcb048d46e8c_12" ; -"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_1" [label="1: Start operator!=\nFormals: i1:iterator& i2:iterator&\nLocals: \n DECLARE_LOCALS(&return); [line 21]\n " color=yellow style=filled] +"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_1" [label="1: Start operator!=\nFormals: i1:iterator& i2:iterator&\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$0); [line 21]\n " color=yellow style=filled] - "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_1" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_3" ; + "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_1" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_4" ; "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_2" [label="2: Exit operator!= \n " color=yellow style=filled] -"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_3" [label="3: Return Stmt \n n$0=*&i1:iterator& [line 21]\n n$1=*n$0.val:int [line 21]\n n$2=*&i2:iterator& [line 21]\n n$3=*n$2.val:int [line 21]\n *&return:_Bool=(n$1 != n$3) [line 21]\n " shape="box"] +"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_3" [label="3: + \n " ] - "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_3" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_2" ; + "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_3" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_9" ; +"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_4" [label="4: BinaryOperatorStmt: NE \n n$1=*&i1:iterator& [line 21]\n n$2=*n$1.val:int [line 21]\n n$3=*&i2:iterator& [line 21]\n n$4=*n$3.val:int [line 21]\n " shape="box"] + + + "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_4" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_5" ; + "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_4" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_6" ; +"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_5" [label="5: Prune (true branch) \n PRUNE(((n$2 != n$4) != 0), true); [line 21]\n " shape="invhouse"] + + + "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_5" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_7" ; +"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_6" [label="6: Prune (false branch) \n PRUNE(((n$2 != n$4) == 0), false); [line 21]\n " shape="invhouse"] + + + "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_6" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_8" ; +"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_7" [label="7: ConditinalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool=1 [line 21]\n " shape="box"] + + + "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_7" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_3" ; +"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_8" [label="8: ConditinalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool=0 [line 21]\n " shape="box"] + + + "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_8" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_3" ; +"operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_9" [label="9: Return Stmt \n n$5=*&0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool [line 21]\n *&return:_Bool=n$5 [line 21]\n " shape="box"] + + + "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_9" -> "operator!=#_Zne8iteratorS_.497d6549b2907c91697671b3c62dc141_2" ; "operator*#iterator#(_ZN8iteratordeEv).d1b3c4615152af7edafb600f858babe9_1" [label="1: Start iterator_operator*\nFormals: this:iterator*\nLocals: \n DECLARE_LOCALS(&return); [line 17]\n " color=yellow style=filled] diff --git a/infer/tests/codetoanalyze/cpp/shared/types/typeid_expr.cpp.dot b/infer/tests/codetoanalyze/cpp/shared/types/typeid_expr.cpp.dot index f809aca2d..5aea38127 100644 --- a/infer/tests/codetoanalyze/cpp/shared/types/typeid_expr.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/shared/types/typeid_expr.cpp.dot @@ -381,17 +381,42 @@ digraph iCFG { "exception_ptr#exception_ptr#std#{_ZNSt13exception_ptrC1Ev}.0c4f2ef0c0bd9280100ecba5b0fba8bd_3" -> "exception_ptr#exception_ptr#std#{_ZNSt13exception_ptrC1Ev}.0c4f2ef0c0bd9280100ecba5b0fba8bd_2" ; -"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_1" [label="1: Start std::exception_ptr_operator_bool\nFormals: this:std::exception_ptr*\nLocals: \n DECLARE_LOCALS(&return); [line 136]\n " color=yellow style=filled] +"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_1" [label="1: Start std::exception_ptr_operator_bool\nFormals: this:std::exception_ptr*\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$0); [line 136]\n " color=yellow style=filled] - "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_1" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_3" ; + "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_1" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_4" ; "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_2" [label="2: Exit std::exception_ptr_operator_bool \n " color=yellow style=filled] -"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_3" [label="3: Return Stmt \n n$0=*&this:std::exception_ptr const * [line 138]\n n$1=*n$0.__ptr_:void* [line 138]\n *&return:_Bool=(n$1 != null) [line 138]\n " shape="box"] +"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_3" [label="3: + \n " ] - "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_3" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_2" ; + "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_3" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_9" ; +"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_4" [label="4: BinaryOperatorStmt: NE \n n$1=*&this:std::exception_ptr const * [line 138]\n n$2=*n$1.__ptr_:void* [line 138]\n " shape="box"] + + + "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_4" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_5" ; + "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_4" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_6" ; +"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_5" [label="5: Prune (true branch) \n PRUNE(((n$2 != null) != 0), true); [line 138]\n " shape="invhouse"] + + + "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_5" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_7" ; +"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_6" [label="6: Prune (false branch) \n PRUNE(((n$2 != null) == 0), false); [line 138]\n " shape="invhouse"] + + + "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_6" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_8" ; +"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_7" [label="7: ConditinalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool=1 [line 138]\n " shape="box"] + + + "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_7" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_3" ; +"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_8" [label="8: ConditinalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool=0 [line 138]\n " shape="box"] + + + "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_8" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_3" ; +"operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_9" [label="9: Return Stmt \n n$3=*&0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool [line 138]\n *&return:_Bool=n$3 [line 138]\n " shape="box"] + + + "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_9" -> "operator_bool#exception_ptr#std#(_ZNKSt13exception_ptrcvbEv).6fac2b4e27029bcd0295f179efc6cf0f_2" ; "exception_ptr#exception_ptr#std#{_ZNSt13exception_ptrC1EDn}.b23bb2147c8a8ba771e2f40d3542abc9_1" [label="1: Start std::exception_ptr_exception_ptr\nFormals: this:std::exception_ptr* __param_0:int\nLocals: \n DECLARE_LOCALS(&return); [line 131]\n " color=yellow style=filled] @@ -431,17 +456,42 @@ digraph iCFG { "hash_code#type_info#std#(_ZNKSt9type_info9hash_codeEv).01675cb218ac7b3cd979914210b13e49_3" -> "hash_code#type_info#std#(_ZNKSt9type_info9hash_codeEv).01675cb218ac7b3cd979914210b13e49_2" ; -"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_1" [label="1: Start std::type_info_before\nFormals: this:std::type_info* __arg:std::type_info const &\nLocals: \n DECLARE_LOCALS(&return); [line 103]\n " color=yellow style=filled] +"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_1" [label="1: Start std::type_info_before\nFormals: this:std::type_info* __arg:std::type_info const &\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$0); [line 103]\n " color=yellow style=filled] - "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_1" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_3" ; + "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_1" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_4" ; "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_2" [label="2: Exit std::type_info_before \n " color=yellow style=filled] -"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_3" [label="3: Return Stmt \n n$0=*&this:std::type_info const * [line 106]\n n$1=*n$0.__type_name:char const * [line 106]\n n$2=*&__arg:std::type_info const & [line 106]\n n$3=*n$2.__type_name:char const * [line 106]\n *&return:_Bool=(n$1 < n$3) [line 106]\n " shape="box"] +"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_3" [label="3: + \n " ] + + + "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_3" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_9" ; +"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_4" [label="4: BinaryOperatorStmt: LT \n n$1=*&this:std::type_info const * [line 106]\n n$2=*n$1.__type_name:char const * [line 106]\n n$3=*&__arg:std::type_info const & [line 106]\n n$4=*n$3.__type_name:char const * [line 106]\n " shape="box"] + + + "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_4" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_5" ; + "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_4" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_6" ; +"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_5" [label="5: Prune (true branch) \n PRUNE(((n$2 < n$4) != 0), true); [line 106]\n " shape="invhouse"] + + + "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_5" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_7" ; +"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_6" [label="6: Prune (false branch) \n PRUNE(((n$2 < n$4) == 0), false); [line 106]\n " shape="invhouse"] + + + "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_6" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_8" ; +"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_7" [label="7: ConditinalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool=1 [line 106]\n " shape="box"] + + + "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_7" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_3" ; +"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_8" [label="8: ConditinalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool=0 [line 106]\n " shape="box"] + + + "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_8" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_3" ; +"before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_9" [label="9: Return Stmt \n n$5=*&0$?%__sil_tmpSIL_temp_conditional___n$0:_Bool [line 106]\n *&return:_Bool=n$5 [line 106]\n " shape="box"] - "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_3" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_2" ; + "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_9" -> "before#type_info#std#(_ZNKSt9type_info6beforeERKS_).d0ee91d1b591c9ae21397c3dface7eb7_2" ; "operator==#type_info#std#(_ZNKSt9type_infoeqERKS_).bba3803f824984bb290007319588edac_1" [label="1: Start std::type_info_operator==\nFormals: this:std::type_info* __arg:std::type_info const &\nLocals: \n " color=yellow style=filled] diff --git a/infer/tests/codetoanalyze/objc/errors/issues.exp b/infer/tests/codetoanalyze/objc/errors/issues.exp index 83888c7aa..8be89bf3b 100644 --- a/infer/tests/codetoanalyze/objc/errors/issues.exp +++ b/infer/tests/codetoanalyze/objc/errors/issues.exp @@ -55,9 +55,9 @@ codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle2.m, strongcycle2, codetoanalyze/objc/errors/npe/UpdateDict.m, add_nil_in_dict, 10, NULL_DEREFERENCE, [start of procedure add_nil_in_dict(),Skipped call: function or method not found] codetoanalyze/objc/errors/npe/UpdateDict.m, add_nil_to_array, 4, NULL_DEREFERENCE, [start of procedure add_nil_to_array()] codetoanalyze/objc/errors/npe/UpdateDict.m, insert_nil_in_array, 4, NULL_DEREFERENCE, [start of procedure insert_nil_in_array()] -codetoanalyze/objc/errors/npe/UpdateDict.m, nullable_NSDictionary_objectForKey, 4, NULL_DEREFERENCE, [start of procedure nullable_NSDictionary_objectForKey(),Condition is true,Condition is true] -codetoanalyze/objc/errors/npe/UpdateDict.m, nullable_NSDictionary_objectForKeyedSubscript, 5, NULL_DEREFERENCE, [start of procedure nullable_NSDictionary_objectForKeyedSubscript(),Condition is true,Condition is true] -codetoanalyze/objc/errors/npe/UpdateDict.m, nullable_NSMapTable_objectForKey, 4, NULL_DEREFERENCE, [start of procedure nullable_NSMapTable_objectForKey(),Condition is true,Condition is true] +codetoanalyze/objc/errors/npe/UpdateDict.m, nullable_NSDictionary_objectForKey, 4, NULL_DEREFERENCE, [start of procedure nullable_NSDictionary_objectForKey(),Condition is true,Condition is true,Condition is true] +codetoanalyze/objc/errors/npe/UpdateDict.m, nullable_NSDictionary_objectForKeyedSubscript, 5, NULL_DEREFERENCE, [start of procedure nullable_NSDictionary_objectForKeyedSubscript(),Condition is true,Condition is true,Condition is true] +codetoanalyze/objc/errors/npe/UpdateDict.m, nullable_NSMapTable_objectForKey, 4, NULL_DEREFERENCE, [start of procedure nullable_NSMapTable_objectForKey(),Condition is true,Condition is true,Condition is true] codetoanalyze/objc/errors/npe/UpdateDict.m, update_array_with_null, 5, NULL_DEREFERENCE, [start of procedure update_array_with_null()] codetoanalyze/objc/errors/npe/UpdateDict.m, update_dict_with_key_null, 10, NULL_DEREFERENCE, [start of procedure update_dict_with_key_null(),Skipped call: function or method not found] codetoanalyze/objc/errors/npe/WeakCapturedVarsNPE.m, __objc_anonymous_block_WeakCapturedA_strongSelfNoCheck______2, 2, NULL_DEREFERENCE, [start of procedure block]