diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index badfaddd6..be67dc0c5 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -2802,7 +2802,10 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s let res_trans_placement_control, res_trans_placement_exps = instructions trans_state_placement placement_args in - let res_trans_new = cpp_new_trans sil_loc typ size_exp_opt res_trans_placement_exps in + let res_trans_new = + cpp_new_trans context.translation_unit_context.integer_type_widths sil_loc typ size_exp_opt + res_trans_placement_exps + in let stmt_opt = CAst_utils.get_stmt_opt cxx_new_expr_info.Clang_ast_t.xnei_initializer_expr source_range in diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index 4625125b4..281a1c4e8 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -326,7 +326,8 @@ module Scope = struct end (** This function handles ObjC new/alloc and C++ new calls *) -let create_alloc_instrs ~alloc_builtin ?size_exp ?placement_args_exps sil_loc function_type = +let create_alloc_instrs integer_type_widths ~alloc_builtin ?size_exp ?placement_args_exps sil_loc + function_type = let function_type, function_type_np = match function_type.Typ.desc with | Tptr (styp, Typ.Pk_pointer) @@ -339,8 +340,15 @@ let create_alloc_instrs ~alloc_builtin ?size_exp ?placement_args_exps sil_loc fu in let ret_id = Ident.create_fresh Ident.knormal in let args = + let nbytes = + match function_type_np.Typ.desc with + | Tint ikind -> + Some (Typ.width_of_ikind integer_type_widths ikind / 8) + | _ -> + None + in let sizeof_exp_ = - Exp.Sizeof {typ= function_type_np; nbytes= None; dynamic_length= None; subtype= Subtype.exact} + Exp.Sizeof {typ= function_type_np; nbytes; dynamic_length= None; subtype= Subtype.exact} in let sizeof_exp = match size_exp with @@ -360,7 +368,10 @@ let create_alloc_instrs ~alloc_builtin ?size_exp ?placement_args_exps sil_loc fu let alloc_trans trans_state ~alloc_builtin loc stmt_info function_type = - let function_type, instrs, exp = create_alloc_instrs ~alloc_builtin loc function_type in + let integer_type_widths = trans_state.context.translation_unit_context.integer_type_widths in + let function_type, instrs, exp = + create_alloc_instrs integer_type_widths ~alloc_builtin loc function_type + in let control_tmp = {empty_control with instrs} in PriorityNode.compute_control_to_parent trans_state loc ~node_name:(Call "alloc") stmt_info control_tmp @@ -368,8 +379,9 @@ let alloc_trans trans_state ~alloc_builtin loc stmt_info function_type = let objc_new_trans trans_state ~alloc_builtin loc stmt_info cls_name function_type = + let integer_type_widths = trans_state.context.translation_unit_context.integer_type_widths in let alloc_ret_type, alloc_stmt_call, alloc_ret_exp = - create_alloc_instrs ~alloc_builtin loc function_type + create_alloc_instrs integer_type_widths ~alloc_builtin loc function_type in let init_ret_id = Ident.create_fresh Ident.knormal in let is_instance = true in @@ -412,7 +424,7 @@ let new_or_alloc_trans trans_state loc stmt_info qual_type class_name_opt select else Logging.die InternalError "Expected selector new or alloc but got, %s" selector -let cpp_new_trans sil_loc function_type size_exp placement_args_exps = +let cpp_new_trans integer_type_widths sil_loc function_type size_exp placement_args_exps = let alloc_builtin = match placement_args_exps with | [] -> ( @@ -422,7 +434,8 @@ let cpp_new_trans sil_loc function_type size_exp placement_args_exps = BuiltinDecl.__placement_new in let function_type, stmt_call, exp = - create_alloc_instrs ~alloc_builtin ?size_exp ~placement_args_exps sil_loc function_type + create_alloc_instrs integer_type_widths ~alloc_builtin ?size_exp ~placement_args_exps sil_loc + function_type in mk_trans_result (exp, function_type) {empty_control with instrs= stmt_call} diff --git a/infer/src/clang/cTrans_utils.mli b/infer/src/clang/cTrans_utils.mli index f010b2cad..3c10a6d12 100644 --- a/infer/src/clang/cTrans_utils.mli +++ b/infer/src/clang/cTrans_utils.mli @@ -120,7 +120,13 @@ val new_or_alloc_trans : -> string -> trans_result -val cpp_new_trans : Location.t -> Typ.t -> Exp.t option -> (Exp.t * Typ.typ) list -> trans_result +val cpp_new_trans : + Typ.IntegerWidths.t + -> Location.t + -> Typ.t + -> Exp.t option + -> (Exp.t * Typ.typ) list + -> trans_result (** Module for creating cfg nodes and other utility functions related to them. *) module Nodes : sig diff --git a/infer/tests/codetoanalyze/cpp/bufferoverrun/issues.exp b/infer/tests/codetoanalyze/cpp/bufferoverrun/issues.exp index e17deec0f..5065fad18 100644 --- a/infer/tests/codetoanalyze/cpp/bufferoverrun/issues.exp +++ b/infer/tests/codetoanalyze/cpp/bufferoverrun/issues.exp @@ -50,6 +50,9 @@ codetoanalyze/cpp/bufferoverrun/repro1.cpp, LM_uI_FP, 0, INTEGER_OVERFLOW_L codetoanalyze/cpp/bufferoverrun/repro1.cpp, am_Good, 5, BUFFER_OVERRUN_L5, no_bucket, ERROR, [Call,Call,Call,Assignment,Call,Call,Call,Parameter: bi,Call,Call,ArrayDeclaration,Assignment,Parameter: index,ArrayAccess: Offset: [0, +oo] Size: [0, +oo]] codetoanalyze/cpp/bufferoverrun/repro1.cpp, am_Good, 5, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [Call,Call,Call,Assignment,Call,Call,Call,Parameter: bi,Binop: ([-oo, +oo] - 1):signed32 by call to `ral_FP` ] codetoanalyze/cpp/bufferoverrun/simple_vector.cpp, my_vector_oob_Bad, 2, BUFFER_OVERRUN_L2, no_bucket, ERROR, [Call,Call,ArrayDeclaration,Assignment,Parameter: i,ArrayAccess: Offset: v[*]._size Size: v[*]._size by call to `int_vector_access_at` ] +codetoanalyze/cpp/bufferoverrun/std_array.cpp, new_int1_Bad, 3, INFERBO_ALLOC_IS_BIG, no_bucket, ERROR, [Assignment,Alloc: Length: 4611686018427387903] +codetoanalyze/cpp/bufferoverrun/std_array.cpp, new_int2_Bad, 3, INFERBO_ALLOC_IS_BIG, no_bucket, ERROR, [Assignment,Alloc: Length: 9223372036854775807] +codetoanalyze/cpp/bufferoverrun/std_array.cpp, new_int2_Bad, 3, INTEGER_OVERFLOW_L1, no_bucket, ERROR, [Assignment,Binop: (4 * 9223372036854775807):unsigned64] codetoanalyze/cpp/bufferoverrun/std_array.cpp, normal_array_bo, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [ArrayDeclaration,ArrayAccess: Offset: 42 Size: 42] codetoanalyze/cpp/bufferoverrun/std_array.cpp, std_array_bo_Bad, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [ArrayDeclaration,ArrayAccess: Offset: 42 Size: 42] codetoanalyze/cpp/bufferoverrun/symb_arr.cpp, symb_arr_alloc_symb_arr_access_bad, 0, BUFFER_OVERRUN_L1, no_bucket, ERROR, [ArrayAccess: Offset: 10 Size: 10] diff --git a/infer/tests/codetoanalyze/cpp/bufferoverrun/std_array.cpp b/infer/tests/codetoanalyze/cpp/bufferoverrun/std_array.cpp index 249336755..e0ea85b23 100644 --- a/infer/tests/codetoanalyze/cpp/bufferoverrun/std_array.cpp +++ b/infer/tests/codetoanalyze/cpp/bufferoverrun/std_array.cpp @@ -15,3 +15,27 @@ int normal_array_bo() { int b[42]; return b[42]; } + +void new_char_Good() { + uint64_t len = 13; + char* dst; + dst = new char[len]; +} + +void new_int1_Bad() { + uint64_t len = 4611686018427387903; // (1 << 62) - 1 + int32_t* dst; + dst = new int32_t[len]; +} + +void new_int2_Bad() { + uint64_t len = 9223372036854775807; // (1 << 63) - 1 + int32_t* dst; + dst = new int32_t[len]; +} + +void new_int3_Bad_FN() { + uint64_t len = 18446744073709551615; // (1 << 64) - 1 + int32_t* dst; + dst = new int32_t[len]; +} diff --git a/infer/tests/codetoanalyze/cpp/frontend/builtin/new.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/builtin/new.cpp.dot index ef8df1254..8e84d8572 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/builtin/new.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/builtin/new.cpp.dot @@ -22,11 +22,11 @@ digraph cfg { "test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_3" -> "test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_2" ; -"test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_4" [label="4: CXXNewExpr \n n$3=_fun___new(sizeof(t=int):unsigned long) [line 11, column 3]\n " shape="box"] +"test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_4" [label="4: CXXNewExpr \n n$3=_fun___new(sizeof(t=int;nbytes=4):unsigned long) [line 11, column 3]\n " shape="box"] "test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_4" -> "test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_3" ; -"test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_5" [label="5: DeclStmt \n n$4=_fun___new(sizeof(t=int):unsigned long) [line 10, column 12]\n *&i:int*=n$4 [line 10, column 3]\n " shape="box"] +"test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_5" [label="5: DeclStmt \n n$4=_fun___new(sizeof(t=int;nbytes=4):unsigned long) [line 10, column 12]\n *&i:int*=n$4 [line 10, column 3]\n " shape="box"] "test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_5" -> "test#18241244337164948030.afc14f193ad97442f67ac7183be789bc_4" ; diff --git a/infer/tests/codetoanalyze/cpp/shared/constructors/constructor_new.cpp.dot b/infer/tests/codetoanalyze/cpp/shared/constructors/constructor_new.cpp.dot index bc817ba6b..c7c6dda5b 100644 --- a/infer/tests/codetoanalyze/cpp/shared/constructors/constructor_new.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/shared/constructors/constructor_new.cpp.dot @@ -191,7 +191,7 @@ digraph cfg { "int_array#constructor_new#17288301834361373856.f0e67f3600c928968ac2559eafa09ba2_11" -> "int_array#constructor_new#17288301834361373856.f0e67f3600c928968ac2559eafa09ba2_6" ; -"int_array#constructor_new#17288301834361373856.f0e67f3600c928968ac2559eafa09ba2_12" [label="12: DeclStmt \n n$10=*&0$?%__sil_tmpSIL_temp_conditional___n$7:int [line 76, column 21]\n n$11=_fun___new_array((sizeof(t=int) * n$10):unsigned long) [line 76, column 13]\n *&x2:int*=n$11 [line 76, column 3]\n " shape="box"] +"int_array#constructor_new#17288301834361373856.f0e67f3600c928968ac2559eafa09ba2_12" [label="12: DeclStmt \n n$10=*&0$?%__sil_tmpSIL_temp_conditional___n$7:int [line 76, column 21]\n n$11=_fun___new_array((sizeof(t=int;nbytes=4) * n$10):unsigned long) [line 76, column 13]\n *&x2:int*=n$11 [line 76, column 3]\n " shape="box"] "int_array#constructor_new#17288301834361373856.f0e67f3600c928968ac2559eafa09ba2_12" -> "int_array#constructor_new#17288301834361373856.f0e67f3600c928968ac2559eafa09ba2_5" ; @@ -206,7 +206,7 @@ digraph cfg { "int_array_init#constructor_new#14099932616230884357.69a63438c3aee293029f068d373c29c3_3" -> "int_array_init#constructor_new#14099932616230884357.69a63438c3aee293029f068d373c29c3_2" ; -"int_array_init#constructor_new#14099932616230884357.69a63438c3aee293029f068d373c29c3_4" [label="4: DeclStmt \n n$11=_fun___new_array((sizeof(t=int) * 100):unsigned long) [line 83, column 14]\n *n$11[0]:int=1 [line 83, column 26]\n *n$11[1]:int=2 [line 83, column 26]\n *n$11[2]:int=3 [line 83, column 26]\n *n$11[3]:int=4 [line 83, column 26]\n *n$11[4]:int=5 [line 83, column 26]\n *n$11[5]:int=6 [line 83, column 26]\n *n$11[6]:int=7 [line 83, column 26]\n *n$11[7]:int=8 [line 83, column 26]\n *n$11[8]:int=9 [line 83, column 26]\n *n$11[9]:int=10 [line 83, column 26]\n *&arr:int*=n$11 [line 83, column 3]\n " shape="box"] +"int_array_init#constructor_new#14099932616230884357.69a63438c3aee293029f068d373c29c3_4" [label="4: DeclStmt \n n$11=_fun___new_array((sizeof(t=int;nbytes=4) * 100):unsigned long) [line 83, column 14]\n *n$11[0]:int=1 [line 83, column 26]\n *n$11[1]:int=2 [line 83, column 26]\n *n$11[2]:int=3 [line 83, column 26]\n *n$11[3]:int=4 [line 83, column 26]\n *n$11[4]:int=5 [line 83, column 26]\n *n$11[5]:int=6 [line 83, column 26]\n *n$11[6]:int=7 [line 83, column 26]\n *n$11[7]:int=8 [line 83, column 26]\n *n$11[8]:int=9 [line 83, column 26]\n *n$11[9]:int=10 [line 83, column 26]\n *&arr:int*=n$11 [line 83, column 3]\n " shape="box"] "int_array_init#constructor_new#14099932616230884357.69a63438c3aee293029f068d373c29c3_4" -> "int_array_init#constructor_new#14099932616230884357.69a63438c3aee293029f068d373c29c3_3" ; @@ -221,7 +221,7 @@ digraph cfg { "int_init_empty#constructor_new#15413029864213743197.d5b807871fe4ea10e898a381f0edef4d_3" -> "int_init_empty#constructor_new#15413029864213743197.d5b807871fe4ea10e898a381f0edef4d_2" ; -"int_init_empty#constructor_new#15413029864213743197.d5b807871fe4ea10e898a381f0edef4d_4" [label="4: DeclStmt \n n$3=_fun___new(sizeof(t=int):unsigned long) [line 48, column 13]\n *n$3:int=0 [line 48, column 21]\n *&x1:int*=n$3 [line 48, column 3]\n " shape="box"] +"int_init_empty#constructor_new#15413029864213743197.d5b807871fe4ea10e898a381f0edef4d_4" [label="4: DeclStmt \n n$3=_fun___new(sizeof(t=int;nbytes=4):unsigned long) [line 48, column 13]\n *n$3:int=0 [line 48, column 21]\n *&x1:int*=n$3 [line 48, column 3]\n " shape="box"] "int_init_empty#constructor_new#15413029864213743197.d5b807871fe4ea10e898a381f0edef4d_4" -> "int_init_empty#constructor_new#15413029864213743197.d5b807871fe4ea10e898a381f0edef4d_3" ; @@ -251,7 +251,7 @@ digraph cfg { "int_init_empty_list_new#constructor_new#18093274870234850959.e77c2840901e6e789e52d55ac81db88f_3" -> "int_init_empty_list_new#constructor_new#18093274870234850959.e77c2840901e6e789e52d55ac81db88f_2" ; -"int_init_empty_list_new#constructor_new#18093274870234850959.e77c2840901e6e789e52d55ac81db88f_4" [label="4: DeclStmt \n n$3=_fun___new(sizeof(t=int):unsigned long) [line 58, column 13]\n *n$3:int=0 [line 58, column 13]\n *&x1:int*=n$3 [line 58, column 3]\n " shape="box"] +"int_init_empty_list_new#constructor_new#18093274870234850959.e77c2840901e6e789e52d55ac81db88f_4" [label="4: DeclStmt \n n$3=_fun___new(sizeof(t=int;nbytes=4):unsigned long) [line 58, column 13]\n *n$3:int=0 [line 58, column 13]\n *&x1:int*=n$3 [line 58, column 3]\n " shape="box"] "int_init_empty_list_new#constructor_new#18093274870234850959.e77c2840901e6e789e52d55ac81db88f_4" -> "int_init_empty_list_new#constructor_new#18093274870234850959.e77c2840901e6e789e52d55ac81db88f_3" ; @@ -291,11 +291,11 @@ digraph cfg { "int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_9" -> "int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_4" ; -"int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_10" [label="10: DeclStmt \n n$3=_fun___new(sizeof(t=int):unsigned long) [line 65, column 12]\n n$9=*&0$?%__sil_tmpSIL_temp_conditional___n$4:int [line 65, column 20]\n *n$3:int=n$9 [line 65, column 12]\n *&x:int*=n$3 [line 65, column 3]\n " shape="box"] +"int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_10" [label="10: DeclStmt \n n$3=_fun___new(sizeof(t=int;nbytes=4):unsigned long) [line 65, column 12]\n n$9=*&0$?%__sil_tmpSIL_temp_conditional___n$4:int [line 65, column 20]\n *n$3:int=n$9 [line 65, column 12]\n *&x:int*=n$3 [line 65, column 3]\n " shape="box"] "int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_10" -> "int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_3" ; -"int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_11" [label="11: DeclStmt \n n$10=_fun___new(sizeof(t=int):unsigned long) [line 64, column 12]\n n$11=_fun_constructor_new::getValue(4:int) [line 64, column 20]\n *n$10:int=n$11 [line 64, column 12]\n *&y:int*=n$10 [line 64, column 3]\n " shape="box"] +"int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_11" [label="11: DeclStmt \n n$10=_fun___new(sizeof(t=int;nbytes=4):unsigned long) [line 64, column 12]\n n$11=_fun_constructor_new::getValue(4:int) [line 64, column 20]\n *n$10:int=n$11 [line 64, column 12]\n *&y:int*=n$10 [line 64, column 3]\n " shape="box"] "int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_11" -> "int_init_nodes#constructor_new#3816193909145311065.e18f1e2417086b4c8d20246eeee5dd01_5" ; @@ -314,7 +314,7 @@ digraph cfg { "int_init_number#constructor_new#16564762083428359974.2a1c04c2e924068dd02b097712efe518_3" -> "int_init_number#constructor_new#16564762083428359974.2a1c04c2e924068dd02b097712efe518_2" ; -"int_init_number#constructor_new#16564762083428359974.2a1c04c2e924068dd02b097712efe518_4" [label="4: DeclStmt \n n$3=_fun___new(sizeof(t=int):unsigned long) [line 38, column 13]\n *n$3:int=5 [line 38, column 13]\n *&x1:int*=n$3 [line 38, column 3]\n " shape="box"] +"int_init_number#constructor_new#16564762083428359974.2a1c04c2e924068dd02b097712efe518_4" [label="4: DeclStmt \n n$3=_fun___new(sizeof(t=int;nbytes=4):unsigned long) [line 38, column 13]\n *n$3:int=5 [line 38, column 13]\n *&x1:int*=n$3 [line 38, column 3]\n " shape="box"] "int_init_number#constructor_new#16564762083428359974.2a1c04c2e924068dd02b097712efe518_4" -> "int_init_number#constructor_new#16564762083428359974.2a1c04c2e924068dd02b097712efe518_3" ;