diff --git a/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.dot b/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.dot index 12037e4d9..53a9737d6 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.dot @@ -1,38 +1,67 @@ digraph iCFG { -12 [label="12: DeclStmt \n *&error:class NSError *=0 [line 22]\n NULLIFY(&error,false); [line 22]\n " shape="box"] +19 [label="19: DeclStmt \n *&error:class NSError *=0 [line 20]\n NULLIFY(&error,false); [line 20]\n " shape="box"] - 12 -> 11 ; -11 [label="11: DeclStmt \n n$5=_fun_BlockVar_test() [line 23]\n *&res:int =n$5 [line 23]\n REMOVE_TEMPS(n$5); [line 23]\n " shape="box"] + 19 -> 18 ; +18 [label="18: DeclStmt \n n$9=_fun_BlockVar_test() [line 21]\n *&res:int =n$9 [line 21]\n REMOVE_TEMPS(n$9); [line 21]\n " shape="box"] - 11 -> 10 ; -10 [label="10: Return Stmt \n n$2=*&a:int [line 24]\n n$3=*&b:int [line 24]\n n$4=*&res:int [line 24]\n *&return:int =((n$2 + n$3) + n$4) [line 24]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 24]\n NULLIFY(&a,false); [line 24]\n NULLIFY(&b,false); [line 24]\n NULLIFY(&res,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"] + 18 -> 17 ; +17 [label="17: Return Stmt \n n$6=*&a:int [line 22]\n n$7=*&b:int [line 22]\n n$8=*&res:int [line 22]\n *&return:int =((n$6 + n$7) + n$8) [line 22]\n REMOVE_TEMPS(n$6,n$7,n$8); [line 22]\n NULLIFY(&a,false); [line 22]\n NULLIFY(&b,false); [line 22]\n NULLIFY(&res,false); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 10 -> 9 ; -9 [label="9: Exit __objc_anonymous_block_BlockVar_navigateToURLInBackground:resolver:______1 \n " color=yellow style=filled] + 17 -> 16 ; +16 [label="16: Exit __objc_anonymous_block_BlockVar_navigateToURLInBackground______1 \n " color=yellow style=filled] -8 [label="8: Start __objc_anonymous_block_BlockVar_navigateToURLInBackground:resolver:______1\nFormals: a:int b:int \nLocals: res:int error:class NSError * \n DECLARE_LOCALS(&return,&res,&error); [line 21]\n NULLIFY(&error,false); [line 21]\n NULLIFY(&res,false); [line 21]\n " color=yellow style=filled] +15 [label="15: Start __objc_anonymous_block_BlockVar_navigateToURLInBackground______1\nFormals: a:int b:int \nLocals: res:int error:class NSError * \n DECLARE_LOCALS(&return,&res,&error); [line 19]\n NULLIFY(&error,false); [line 19]\n NULLIFY(&res,false); [line 19]\n " color=yellow style=filled] - 8 -> 12 ; -7 [label="7: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_navigateToURLInBackground:resolver:______1); [line 21]\n n$6=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_navigateToURLInBackground:resolver:______1 ):unsigned long ) [line 21]\n *&__objc_anonymous_block_BlockVar_navigateToURLInBackground:resolver:______1:class __objc_anonymous_block_BlockVar_navigateToURLInBackground:resolver:______1 =n$6 [line 21]\n *&addBlock:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_navigateToURLInBackground:resolver:______1) [line 21]\n REMOVE_TEMPS(n$6); [line 21]\n " shape="box"] + 15 -> 19 ; +14 [label="14: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1); [line 19]\n n$10=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_navigateToURLInBackground______1 ):unsigned long ) [line 19]\n *&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1:class __objc_anonymous_block_BlockVar_navigateToURLInBackground______1 =n$10 [line 19]\n *&addBlock:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_navigateToURLInBackground______1) [line 19]\n REMOVE_TEMPS(n$10); [line 19]\n " shape="box"] - 7 -> 6 ; -6 [label="6: Return Stmt \n n$0=*&addBlock:_fn_ (*) [line 26]\n n$1=n$0(1:int ,2:int ) [line 26]\n *&return:int =n$1 [line 26]\n REMOVE_TEMPS(n$0,n$1); [line 26]\n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground:resolver:______1,true); [line 26]\n NULLIFY(&addBlock,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] + 14 -> 13 ; +13 [label="13: DeclStmt \n n$4=*&addBlock:_fn_ (*) [line 24]\n n$5=n$4(1:int ,2:int ) [line 24]\n *&x:int =n$5 [line 24]\n REMOVE_TEMPS(n$4,n$5); [line 24]\n NULLIFY(&addBlock,false); [line 24]\n " shape="box"] + + + 13 -> 12 ; +12 [label="12: DeclStmt \n *&p:int *=0 [line 25]\n " shape="box"] + + + 12 -> 7 ; +11 [label="11: Return Stmt \n NULLIFY(&p,false); [line 27]\n n$3=*&x:int [line 27]\n *&return:int =n$3 [line 27]\n REMOVE_TEMPS(n$3); [line 27]\n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1,true); [line 27]\n NULLIFY(&x,false); [line 27]\n APPLY_ABSTRACTION; [line 27]\n " shape="box"] + + + 11 -> 5 ; +10 [label="10: Return Stmt \n NULLIFY(&x,false); [line 26]\n n$1=*&p:int * [line 26]\n n$2=*n$1:int [line 26]\n *&return:int =n$2 [line 26]\n REMOVE_TEMPS(n$1,n$2); [line 26]\n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1,true); [line 26]\n NULLIFY(&p,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] + + + 10 -> 5 ; +9 [label="9: Prune (false branch) \n PRUNE(((n$0 == 8) == 0), false); [line 26]\n REMOVE_TEMPS(n$0); [line 26]\n " shape="invhouse"] + + + 9 -> 11 ; +8 [label="8: Prune (true branch) \n PRUNE(((n$0 == 8) != 0), true); [line 26]\n REMOVE_TEMPS(n$0); [line 26]\n " shape="invhouse"] + + + 8 -> 10 ; +7 [label="7: BinaryOperatorStmt: EQ \n n$0=*&x:int [line 26]\n " shape="box"] + + + 7 -> 8 ; + 7 -> 9 ; +6 [label="6: + \n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1,true); [line 26]\n NULLIFY(&addBlock,false); [line 26]\n NULLIFY(&p,false); [line 26]\n NULLIFY(&x,false); [line 26]\n " ] 6 -> 5 ; -5 [label="5: Exit BlockVar_navigateToURLInBackground:resolver: \n " color=yellow style=filled] +5 [label="5: Exit BlockVar_navigateToURLInBackground \n " color=yellow style=filled] -4 [label="4: Start BlockVar_navigateToURLInBackground:resolver:\nFormals: destination:class NSURL * resolver:struct objc_object *\nLocals: addBlock:_fn_ (*) \n DECLARE_LOCALS(&return,&addBlock); [line 18]\n NULLIFY(&addBlock,false); [line 18]\n NULLIFY(&destination,false); [line 18]\n NULLIFY(&resolver,false); [line 18]\n " color=yellow style=filled] +4 [label="4: Start BlockVar_navigateToURLInBackground\nFormals: \nLocals: p:int * x:int addBlock:_fn_ (*) \n DECLARE_LOCALS(&return,&p,&x,&addBlock); [line 18]\n NULLIFY(&addBlock,false); [line 18]\n NULLIFY(&p,false); [line 18]\n NULLIFY(&x,false); [line 18]\n " color=yellow style=filled] - 4 -> 7 ; + 4 -> 14 ; 3 [label="3: Return Stmt \n *&return:int =5 [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.h b/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.h index 108d9429b..ad779b274 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.h +++ b/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.h @@ -13,7 +13,6 @@ + (int)test; -+ (int)navigateToURLInBackground:(NSURL *)destination - resolver:(id)resolver; ++ (int)navigateToURLInBackground; @end diff --git a/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.m b/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.m index fb60d41d1..2d8004986 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.m +++ b/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.m @@ -15,15 +15,16 @@ return 5; } -+ (int)navigateToURLInBackground:(NSURL *)destination - resolver:(id)resolver { - ++ (int)navigateToURLInBackground { int (^addBlock)(int a, int b) = ^(int a, int b){ NSError *error = nil; int res = [self test]; return a + b + res; }; - return addBlock(1, 2); + int x = addBlock(1, 2); + int *p = 0; + if (x == 8) return *p; + else return x; } - @end + diff --git a/infer/tests/codetoanalyze/objc/frontend/block/main.m b/infer/tests/codetoanalyze/objc/frontend/block/main.m deleted file mode 100644 index bc8b199a6..000000000 --- a/infer/tests/codetoanalyze/objc/frontend/block/main.m +++ /dev/null @@ -1,20 +0,0 @@ -/* -* Copyright (c) 2014 - 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. -*/ - -#import "BlockVar.m" - -int main(int argc, const char * argv[]) -{ - int res = [BlockVar navigateToURLInBackground:nil resolver:nil]; - NSLog(@"Hello, World! The result is %d" , res); - if (res == 8) { - return 1/0; - } - return 0; -} diff --git a/infer/tests/endtoend/objc/BlockTest.java b/infer/tests/endtoend/objc/BlockVarTest.java similarity index 62% rename from infer/tests/endtoend/objc/BlockTest.java rename to infer/tests/endtoend/objc/BlockVarTest.java index b88d6385d..90cd70955 100644 --- a/infer/tests/endtoend/objc/BlockTest.java +++ b/infer/tests/endtoend/objc/BlockVarTest.java @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013 - present Facebook, Inc. +* Copyright (c) 2015 - present Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD style license found in the @@ -11,6 +11,7 @@ package endtoend.objc; import static org.hamcrest.MatcherAssert.assertThat; import static utils.matchers.ResultContainsErrorInMethod.contains; +import static utils.matchers.ResultContainsExactly.containsExactly; import com.google.common.collect.ImmutableList; @@ -25,15 +26,13 @@ import utils.InferException; import utils.InferResults; import utils.InferRunner; -public class BlockTest { +public class BlockVarTest { - public static final String MAIN_FILE = - "infer/tests/" + - "codetoanalyze/objc/frontend/block/main.m"; + public static final String FILE = "infer/tests/codetoanalyze/objc/frontend/block/BlockVar.m"; private static ImmutableList inferCmd; - public static final String DIVIDE_BY_ZERO = "DIVIDE_BY_ZERO"; + public static final String NULL_DEREFERENCE = "NULL_DEREFERENCE"; @ClassRule public static DebuggableTemporaryFolder folder = @@ -41,21 +40,23 @@ public class BlockTest { @BeforeClass public static void runInfer() throws InterruptedException, IOException { - inferCmd = InferRunner.createObjCInferCommand(folder, MAIN_FILE); + inferCmd = InferRunner.createObjCInferCommand(folder, FILE); } @Test - public void whenInferRunsOnEOCPersonThenMemoryLeakIsFound() + public void whenInferRunsOnNavigateToURLInBackgroundThenNPEIsFound() throws InterruptedException, IOException, InferException { InferResults inferResults = InferRunner.runInferObjC(inferCmd); + String[] procedures = { + "navigateToURLInBackground", + }; assertThat( - "Results should contain divide by zero error. " + - "This shows that the translation is correct and res = 8.", + "Results should contain the expected null pointer exception", inferResults, - contains( - DIVIDE_BY_ZERO, - MAIN_FILE, - "main" + containsExactly( + NULL_DEREFERENCE, + FILE, + procedures ) ); }