From 5c8b5657d19f36c7a2ee423c5d466afa2fdcbc22 Mon Sep 17 00:00:00 2001 From: Daiva Naudziuniene Date: Tue, 18 May 2021 04:43:30 -0700 Subject: [PATCH] [clang frontend][objc][nullptr] Insert missing load to catch nil insertion into collection issues Summary: Follow similar approach as in the translation of dictionary literal to insert load instruction to catch nil insertion into collection issues. The missing load instruction was causing false negatives in biabduction. This will also help Pulse to catch nil insertion into collection issues for array literals. Facebook Reviewed By: skcho Differential Revision: D28442642 fbshipit-source-id: b530ac21b --- infer/src/clang/cTrans.ml | 5 ++++- .../tests/codetoanalyze/objc/biabduction/issues.exp | 5 +++++ .../objc/biabduction/npe/nil_in_array_literal.m | 12 ++++++------ .../codetoanalyze/objc/frontend/boxing/array.m.dot | 2 +- .../objc/frontend/boxing/array_literal.c.dot | 6 +++--- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index a990d34dc..bcfd7a4c1 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -3537,11 +3537,14 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s stmts in (* 3. Add array initialization (elements assignments) *) + let none_id = Ident.create_none () in let res_trans_array = let instrs = List.mapi res_trans_elems ~f:(fun i {return= e, typ} -> let idx = Exp.Const (Cint (IntLit.of_int i)) in - Sil.Store {e1= Lindex (temp_var, idx); root_typ= typ; typ; e2= e; loc} ) + [ Sil.Load {id= none_id; e; root_typ= typ; typ; loc} + ; Sil.Store {e1= Lindex (temp_var, idx); root_typ= typ; typ; e2= e; loc} ] ) + |> List.concat in mk_trans_result temp_with_typ {empty_control with instrs} in diff --git a/infer/tests/codetoanalyze/objc/biabduction/issues.exp b/infer/tests/codetoanalyze/objc/biabduction/issues.exp index 8a1a6db17..f615f50f1 100644 --- a/infer/tests/codetoanalyze/objc/biabduction/issues.exp +++ b/infer/tests/codetoanalyze/objc/biabduction/issues.exp @@ -55,6 +55,11 @@ codetoanalyze/objc/biabduction/npe/UpdateDict.m, nullable_NSDictionary_objectFor codetoanalyze/objc/biabduction/npe/UpdateDict.m, nullable_NSMapTable_objectForKey, 4, NULL_DEREFERENCE, B5, ERROR, [start of procedure nullable_NSMapTable_objectForKey(),Taking true branch,Taking true branch] codetoanalyze/objc/biabduction/npe/UpdateDict.m, update_array_with_null, 5, NULL_DEREFERENCE, B1, ERROR, [start of procedure update_array_with_null()] codetoanalyze/objc/biabduction/npe/UpdateDict.m, update_dict_with_key_null, 10, NULL_DEREFERENCE, B1, ERROR, [start of procedure update_dict_with_key_null(),Skipping dictionaryWithObjectsAndKeys:: method has no implementation] +codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m, Arr.insertNilBad, 3, NULL_DEREFERENCE, B1, ERROR, [start of procedure insertNilBad,start of procedure initA,Taking true branch,return from a call to A.initA] +codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m, Arr.nilInArrayLiteral0, 4, NULL_DEREFERENCE, B1, ERROR, [start of procedure nilInArrayLiteral0] +codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m, Arr.nilInArrayLiteral1, 4, NULL_DEREFERENCE, B1, ERROR, [start of procedure nilInArrayLiteral1] +codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m, Arr.nilInArrayLiteral2, 4, NULL_DEREFERENCE, B1, ERROR, [start of procedure nilInArrayLiteral2] +codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m, Arr.nilInArrayLiteral3, 4, NULL_DEREFERENCE, B1, ERROR, [start of procedure nilInArrayLiteral3] codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m, Arr.nilInArrayWithObject, 4, NULL_DEREFERENCE, B1, ERROR, [start of procedure nilInArrayWithObject] codetoanalyze/objc/biabduction/npe/nil_in_dictionary_literal.m, ADict.nilInDictionaryLiteralKey0, 4, NULL_DEREFERENCE, B1, ERROR, [start of procedure nilInDictionaryLiteralKey0] codetoanalyze/objc/biabduction/npe/nil_in_dictionary_literal.m, ADict.nilInDictionaryLiteralKey1, 4, NULL_DEREFERENCE, B1, ERROR, [start of procedure nilInDictionaryLiteralKey1] diff --git a/infer/tests/codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m b/infer/tests/codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m index 541df0f3e..2054a5ec6 100644 --- a/infer/tests/codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m +++ b/infer/tests/codetoanalyze/objc/biabduction/npe/nil_in_array_literal.m @@ -38,28 +38,28 @@ bool myrand(void); return; } -- (void)nilInArrayLiteral0_FN { +- (void)nilInArrayLiteral0 { NSString* str = nil; // nil argument in array literal crashes NSArray* foo = @[ str ]; } -- (void)nilInArrayLiteral1_FN { +- (void)nilInArrayLiteral1 { NSString* str = nil; // nil argument in array literal crashes NSArray* foo = @[ str, @"bbb" ]; } -- (void)nilInArrayLiteral2_FN { +- (void)nilInArrayLiteral2 { NSString* str = nil; // nil argument in array literal crashes NSArray* foo = @[ @"aaa", str, @"bbb" ]; } -- (void)nilInArrayLiteral3_FN { +- (void)nilInArrayLiteral3 { NSString* str = nil; // nil argument in array literal crashes @@ -75,7 +75,7 @@ bool myrand(void); return foo; } -- (NSMutableArray*)insertNilBad_FN { +- (NSMutableArray*)insertNilBad { NSMutableArray* ar = [NSMutableArray new]; A* a = [A initA]; [ar addObject:@[ a ]]; @@ -87,7 +87,7 @@ bool myrand(void); int ArrMain() { Arr* a = [Arr alloc]; [a noProblem]; - [a nilInArrayLiteral0_FN]; + [a nilInArrayLiteral0]; [a nilInArrayWithObject]; return 0; } diff --git a/infer/tests/codetoanalyze/objc/frontend/boxing/array.m.dot b/infer/tests/codetoanalyze/objc/frontend/boxing/array.m.dot index 26aca8d4c..90edc34ba 100644 --- a/infer/tests/codetoanalyze/objc/frontend/boxing/array.m.dot +++ b/infer/tests/codetoanalyze/objc/frontend/boxing/array.m.dot @@ -52,7 +52,7 @@ digraph cfg { "main.fad58de7366495db4650cfefac2fcd61_13" -> "main.fad58de7366495db4650cfefac2fcd61_11" ; -"main.fad58de7366495db4650cfefac2fcd61_14" [label="14: DeclStmt \n VARIABLE_DECLARED(germanCars:NSArray*); [line 14, column 3]\n n$13=_fun_NSString.stringWithUTF8String:(\"Mercedes-Benz\":char* const ) [line 15, column 5]\n n$14=_fun_NSString.stringWithUTF8String:(\"BMW\":char* const ) [line 16, column 5]\n n$15=_fun_NSString.stringWithUTF8String:(\"Porsche\":char* const ) [line 17, column 5]\n n$16=_fun_NSString.stringWithUTF8String:(\"Opel\":char* const ) [line 18, column 5]\n n$17=_fun_NSString.stringWithUTF8String:(\"Volkswagen\":char* const ) [line 19, column 5]\n n$18=_fun_NSString.stringWithUTF8String:(\"Audi\":char* const ) [line 20, column 5]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[0]:objc_object*=n$13 [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[1]:objc_object*=n$14 [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[2]:objc_object*=n$15 [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[3]:objc_object*=n$16 [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[4]:objc_object*=n$17 [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[5]:objc_object*=n$18 [line 14, column 25]\n n$19=_fun_NSArray.arrayWithObjects:count:(&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12:objc_object* const [6*8],6:int) [line 14, column 25]\n *&germanCars:NSArray*=n$19 [line 14, column 3]\n " shape="box"] +"main.fad58de7366495db4650cfefac2fcd61_14" [label="14: DeclStmt \n VARIABLE_DECLARED(germanCars:NSArray*); [line 14, column 3]\n n$13=_fun_NSString.stringWithUTF8String:(\"Mercedes-Benz\":char* const ) [line 15, column 5]\n n$14=_fun_NSString.stringWithUTF8String:(\"BMW\":char* const ) [line 16, column 5]\n n$15=_fun_NSString.stringWithUTF8String:(\"Porsche\":char* const ) [line 17, column 5]\n n$16=_fun_NSString.stringWithUTF8String:(\"Opel\":char* const ) [line 18, column 5]\n n$17=_fun_NSString.stringWithUTF8String:(\"Volkswagen\":char* const ) [line 19, column 5]\n n$18=_fun_NSString.stringWithUTF8String:(\"Audi\":char* const ) [line 20, column 5]\n _=*n$13:objc_object* [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[0]:objc_object*=n$13 [line 14, column 25]\n _=*n$14:objc_object* [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[1]:objc_object*=n$14 [line 14, column 25]\n _=*n$15:objc_object* [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[2]:objc_object*=n$15 [line 14, column 25]\n _=*n$16:objc_object* [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[3]:objc_object*=n$16 [line 14, column 25]\n _=*n$17:objc_object* [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[4]:objc_object*=n$17 [line 14, column 25]\n _=*n$18:objc_object* [line 14, column 25]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12[5]:objc_object*=n$18 [line 14, column 25]\n n$20=_fun_NSArray.arrayWithObjects:count:(&0$?%__sil_tmpSIL_arrayWithObjects_count___n$12:objc_object* const [6*8],6:int) [line 14, column 25]\n *&germanCars:NSArray*=n$20 [line 14, column 3]\n " shape="box"] "main.fad58de7366495db4650cfefac2fcd61_14" -> "main.fad58de7366495db4650cfefac2fcd61_13" ; diff --git a/infer/tests/codetoanalyze/objc/frontend/boxing/array_literal.c.dot b/infer/tests/codetoanalyze/objc/frontend/boxing/array_literal.c.dot index 2cdf78015..79608de38 100644 --- a/infer/tests/codetoanalyze/objc/frontend/boxing/array_literal.c.dot +++ b/infer/tests/codetoanalyze/objc/frontend/boxing/array_literal.c.dot @@ -7,15 +7,15 @@ digraph cfg { "get_array.bca6b16c85e5b8ba530f380271b2ec79_2" [label="2: Exit get_array \n " color=yellow style=filled] -"get_array.bca6b16c85e5b8ba530f380271b2ec79_3" [label="3: Return Stmt \n n$1=_fun_NSString.stringWithUTF8String:(\"cat\":char* const ) [line 12, column 13]\n n$2=_fun_NSString.stringWithUTF8String:(\"dog\":char* const ) [line 12, column 21]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$0[0]:objc_object*=n$1 [line 12, column 10]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$0[1]:objc_object*=n$2 [line 12, column 10]\n n$3=_fun_NSArray.arrayWithObjects:count:(&0$?%__sil_tmpSIL_arrayWithObjects_count___n$0:objc_object* const [2*8],2:int) [line 12, column 10]\n " shape="box"] +"get_array.bca6b16c85e5b8ba530f380271b2ec79_3" [label="3: Return Stmt \n n$1=_fun_NSString.stringWithUTF8String:(\"cat\":char* const ) [line 12, column 13]\n n$2=_fun_NSString.stringWithUTF8String:(\"dog\":char* const ) [line 12, column 21]\n _=*n$1:objc_object* [line 12, column 10]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$0[0]:objc_object*=n$1 [line 12, column 10]\n _=*n$2:objc_object* [line 12, column 10]\n *&0$?%__sil_tmpSIL_arrayWithObjects_count___n$0[1]:objc_object*=n$2 [line 12, column 10]\n n$4=_fun_NSArray.arrayWithObjects:count:(&0$?%__sil_tmpSIL_arrayWithObjects_count___n$0:objc_object* const [2*8],2:int) [line 12, column 10]\n " shape="box"] "get_array.bca6b16c85e5b8ba530f380271b2ec79_3" -> "get_array.bca6b16c85e5b8ba530f380271b2ec79_4" ; -"get_array.bca6b16c85e5b8ba530f380271b2ec79_4" [label="4: Return Stmt \n *&return:NSArray*=n$3 [line 12, column 3]\n " shape="box"] +"get_array.bca6b16c85e5b8ba530f380271b2ec79_4" [label="4: Return Stmt \n *&return:NSArray*=n$4 [line 12, column 3]\n " shape="box"] "get_array.bca6b16c85e5b8ba530f380271b2ec79_4" -> "get_array.bca6b16c85e5b8ba530f380271b2ec79_2" ; -"get_array.bca6b16c85e5b8ba530f380271b2ec79_5" [label="5: DeclStmt \n VARIABLE_DECLARED(animals:NSArray*); [line 11, column 3]\n n$5=_fun_NSString.stringWithUTF8String:(\"cat\":char* const ) [line 11, column 48]\n n$4=_fun_NSString.stringWithUTF8String:(\"dog\":char* const ) [line 11, column 56]\n n$6=_fun_NSArray.arrayWithObjects:(n$5:objc_object*,n$4:NSString*,null:void*) [line 11, column 22]\n *&animals:NSArray*=n$6 [line 11, column 3]\n " shape="box"] +"get_array.bca6b16c85e5b8ba530f380271b2ec79_5" [label="5: DeclStmt \n VARIABLE_DECLARED(animals:NSArray*); [line 11, column 3]\n n$6=_fun_NSString.stringWithUTF8String:(\"cat\":char* const ) [line 11, column 48]\n n$5=_fun_NSString.stringWithUTF8String:(\"dog\":char* const ) [line 11, column 56]\n n$7=_fun_NSArray.arrayWithObjects:(n$6:objc_object*,n$5:NSString*,null:void*) [line 11, column 22]\n *&animals:NSArray*=n$7 [line 11, column 3]\n " shape="box"] "get_array.bca6b16c85e5b8ba530f380271b2ec79_5" -> "get_array.bca6b16c85e5b8ba530f380271b2ec79_3" ;