From afebcdad600a0467584b0d51eeed56597b2b980e Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 15 Sep 2016 23:16:31 -0700 Subject: [PATCH] [tests] Prepare objective-c tests for conversion to the new direct testing format Summary: Rename symbols in test files so they are not duplicated and files can be analyzed together without affecting analysis results. Fix some compilation errors, where files could be analyzed but would fail direct compilation. Add Makefile mimicking the same analysis parameters used for the existing tests. Reviewed By: dulmarod Differential Revision: D3869993 fbshipit-source-id: 6db1baf --- infer/src/backend/InferPrint.re | 8 +- infer/tests/codetoanalyze/Makefile.clang | 4 +- .../tests/codetoanalyze/objc/errors/Makefile | 108 +++++++++++ .../objc/errors/category_procdesc/main.c | 3 +- .../objc/errors/category_procdesc/main.dot | 12 +- .../field_superclass/SubtypingExample.m | 2 +- .../errors/field_superclass/SuperExample.dot | 20 +-- .../errors/field_superclass/SuperExample.m | 12 +- .../objc/errors/field_superclass/field.c | 2 +- .../objc/errors/frontend/BlockVar.h | 1 + .../objc/errors/frontend/BlockVar.m | 1 + .../objc/errors/frontend/GetterExample.h | 1 + .../objc/errors/frontend/GetterExample.m | 1 + .../objc/errors/frontend/NSAssert_example.m | 1 + .../objc/errors/frontend/PropertyAttributes.m | 1 + .../objc/errors/frontend/block-it.m | 1 + .../objc/errors/frontend/block.m | 1 + .../objc/errors/frontend/block_no_args.m | 1 + .../objc/errors/frontend/block_release.m | 1 + .../objc/errors/frontend/compound_literal.c | 1 + .../objc/errors/frontend/dispatch.m | 1 + .../objc/errors/frontend/dispatch_examples.m | 1 + .../objc/errors/frontend/dispatch_in_macro.m | 1 + .../errors/frontend/struct_initlistexpr.c | 1 + .../codetoanalyze/objc/errors/issues.exp | 110 ++++++++++++ .../memory_leaks_benchmark/ArcExample.dot | 8 +- .../memory_leaks_benchmark/ArcExample.m | 6 +- .../AutoreleaseExample.dot | 52 +++--- .../AutoreleaseExample.m | 30 ++-- .../CADisplayLinkRetainCycle.m | 10 +- .../memory_leaks_benchmark/MemoryLeakRaii.m | 8 +- .../NSStringInitWithBytesNoCopyExample.m | 4 +- .../RetainCycleStaticVar.m | 24 +-- .../RetainReleaseExample.dot | 27 ++- .../RetainReleaseExample.m | 12 +- .../RetainReleaseExample2.dot | 117 ++++++------ .../RetainReleaseExample2.m | 30 ++-- .../RetainReleaseExampleBucketing.m | 10 +- .../RetainReleaseExampleBucketingArc.m | 25 +++ .../memory_leaks_benchmark/arc_methods.dot | 28 +-- .../memory_leaks_benchmark/arc_methods.m | 26 +-- .../memory_leaks_benchmark/retain_cycle2.m | 30 +++- .../objc/errors/npe/BoxedNumberExample.m | 4 +- .../errors/npe/Nonnull_attribute_example.dot | 24 +-- .../errors/npe/Nonnull_attribute_example.m | 22 +-- .../objc/errors/npe/Npe_with_equal_names.m | 24 +-- .../errors/npe/ObjCMethodCallInCondition.m | 12 +- .../objc/errors/npe/WeakCapturedVarsNPE.m | 4 +- .../codetoanalyze/objc/errors/npe/block.m | 4 +- .../codetoanalyze/objc/errors/npe/blockenum.m | 14 +- .../objc/errors/npe/nil_in_array_literal.m | 8 +- .../errors/npe/nil_in_dictionary_literal.m | 8 +- .../codetoanalyze/objc/errors/npe/nil_param.m | 10 +- .../objc/errors/npe/npe_conditional.m | 8 +- .../objc/errors/npe/npe_malloc.dot | 4 +- .../objc/errors/npe/npe_malloc.m | 4 +- .../codetoanalyze/objc/errors/npe/npe_self.m | 12 +- .../objc/errors/npe/null_returned_by_method.m | 6 +- .../codetoanalyze/objc/errors/npe/nullable.m | 32 ++-- .../errors/npe/skip_method_with_nil_object.m | 18 +- .../objc/errors/procdescs/main.c | 2 +- .../objc/errors/property/ExplicitIvarName.m | 14 +- .../codetoanalyze/objc/errors/property/main.c | 2 +- .../objc/errors/protocol_procdesc/main.c | 2 +- .../objc/errors/protocol_procdesc/main.dot | 4 +- .../errors/subtyping/KindOfClassExample.m | 8 + .../objc/errors/taint/viewController.m | 34 +++- .../premature_nil_termination.m | 8 +- .../warnings/ParameterNotNullableExample.m | 0 .../frontend/assertions/NSAssert_example.dot | 30 ++-- .../frontend/assertions/NSAssert_example.m | 12 +- .../objc/frontend/block/block.dot | 4 +- .../codetoanalyze/objc/frontend/block/block.m | 2 +- .../objc/frontend/block/dispatch.dot | 165 +++++++++-------- .../objc/frontend/block/dispatch.m | 14 +- .../objc/frontend/block/dispatch_examples.dot | 167 ++++++++++-------- .../objc/frontend/block/dispatch_examples.m | 32 ++-- .../objc/frontend/block/dispatch_in_macro.m | 4 +- .../objc/frontend/property/GetterExample.h | 2 +- .../objc/frontend/property/GetterExample.m | 2 +- .../frontend/property/PropertyAttributes.dot | 75 ++++---- .../frontend/property/PropertyAttributes.m | 24 +-- .../endtoend/objc/infer/AutoreleaseTest.java | 8 +- .../objc/infer/BlockDispatchTest.java | 2 +- .../objc/infer/CategoryProcdescTest.java | 2 +- .../infer/ExplicitIvarNameInGetterTest.java | 2 +- .../infer/MemoryLeakBucketingArcTest.java | 5 +- .../objc/infer/MemoryLeakBucketingTest.java | 2 +- .../objc/infer/NPEEqualNamesTest.java | 2 +- .../objc/infer/ParameterNotNullableTest.java | 2 +- .../endtoend/objc/infer/ProcdescTest.java | 2 +- .../endtoend/objc/infer/PropertyTest.java | 2 +- .../objc/infer/ProtocolProcdescTest.java | 2 +- .../endtoend/objc/infer/RetainCycle2Test.java | 2 +- .../objc/infer/RetainCycleStaticVarTest.java | 2 +- .../endtoend/objc/infer/SubtypingTest.java | 2 +- .../infer/WeakVariableInBlockNPETest.java | 2 +- 97 files changed, 1013 insertions(+), 594 deletions(-) create mode 100644 infer/tests/codetoanalyze/objc/errors/Makefile create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/BlockVar.h create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/BlockVar.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/GetterExample.h create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/GetterExample.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/NSAssert_example.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/PropertyAttributes.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/block-it.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/block.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/block_no_args.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/block_release.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/compound_literal.c create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/dispatch.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/dispatch_examples.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/dispatch_in_macro.m create mode 120000 infer/tests/codetoanalyze/objc/errors/frontend/struct_initlistexpr.c create mode 100644 infer/tests/codetoanalyze/objc/errors/issues.exp create mode 100644 infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExampleBucketingArc.m rename infer/tests/codetoanalyze/objc/{ => errors}/warnings/ParameterNotNullableExample.m (100%) diff --git a/infer/src/backend/InferPrint.re b/infer/src/backend/InferPrint.re index 210369b5a..edd577767 100644 --- a/infer/src/backend/InferPrint.re +++ b/infer/src/backend/InferPrint.re @@ -486,7 +486,13 @@ let module IssuesTests = { }; let should_report = ekind == Exceptions.Kerror || - IList.exists (Localise.equal error_name) [Localise.return_value_ignored]; + IList.exists + (Localise.equal error_name) + [ + Localise.return_value_ignored, + Localise.parameter_not_null_checked, + Localise.field_not_null_checked + ]; if (in_footprint && should_report && error_filter source_file error_desc error_name) { F.fprintf fmt diff --git a/infer/tests/codetoanalyze/Makefile.clang b/infer/tests/codetoanalyze/Makefile.clang index bf6803c16..28b9cb7bf 100644 --- a/infer/tests/codetoanalyze/Makefile.clang +++ b/infer/tests/codetoanalyze/Makefile.clang @@ -10,6 +10,8 @@ include $(ROOT_DIR)/Makefile.config ANALYZER = infer +CLEAN_EXTRA = + default: compile print: analyze @@ -22,4 +24,4 @@ test: analyze print rm issues.exp.test clean: - rm -rf *.o infer-out duplicates.txt + rm -rf *.o infer-out $(CLEAN_EXTRA) duplicates.txt diff --git a/infer/tests/codetoanalyze/objc/errors/Makefile b/infer/tests/codetoanalyze/objc/errors/Makefile new file mode 100644 index 000000000..7330151d5 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/Makefile @@ -0,0 +1,108 @@ +# Copyright (c) 2016 - 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. + +include ../../Makefile.clang + +IPHONESIMULATOR_ISYSROOT_SUFFIX = /Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk + +XCODEROOT = $(shell xcode-select -p) + +OPTIONS = -x objective-c -isysroot $(XCODEROOT)$(IPHONESIMULATOR_ISYSROOT_SUFFIX) \ + -mios-simulator-version-min=8.2 --target=x86_64-apple-darwin14 -c + + +FILES = \ + category_procdesc/EOCPerson.m \ + field_superclass/B.m \ + frontend/dispatch.m \ + frontend/GetterExample.m \ + frontend/block-it.m \ + frontend/PropertyAttributes.m \ + memory_leaks_benchmark/ArcExample.m \ + memory_leaks_benchmark/AutoreleaseExample.m \ + memory_leaks_benchmark/FBViewExample.m \ + memory_leaks_benchmark/MemoryLeakExample.m \ + memory_leaks_benchmark/MemoryLeakRaii.m \ + memory_leaks_benchmark/NSMakeCollectableExample.m \ + memory_leaks_benchmark/NSStringInitWithBytesNoCopyExample.m \ + memory_leaks_benchmark/RetainReleaseExample.m \ + memory_leaks_benchmark/RetainReleaseExampleBucketing.m \ + memory_leaks_benchmark/arc_methods.m \ + npe/Fraction.m \ + npe/NPD_core_foundation.m \ + npe/Nonnull_attribute_example.m \ + npe/Npe_with_equal_names.m \ + npe/block.m \ + npe/skip_method_with_nil_object.m \ + procdescs/MethodCall.m \ + property/main.c \ + protocol_procdesc/Bicycle.m \ + protocol_procdesc/main.c \ + resource_leaks/ResourceLeakExample.m \ + taint/sources.m \ + taint/viewController.m \ + +FILES_BUCKET_ALL = \ + frontend/BlockVar.m \ + frontend/NSAssert_example.m \ + frontend/block.m \ + frontend/block_no_args.m \ + frontend/block_release.m \ + frontend/compound_literal.c \ + frontend/dispatch_in_macro.m \ + category_procdesc/main.c \ + field_superclass/SuperExample.m \ + field_superclass/field.c \ + global_const/global_const.m \ + memory_leaks_benchmark/CADisplayLinkRetainCycle.m \ + memory_leaks_benchmark/RetainCycleStaticVar.m \ + memory_leaks_benchmark/RetainReleaseExample2.m \ + npe/blockenum.m \ + npe/nil_param.m \ + npe/npe_malloc.m \ + npe/null_returned_by_method.m \ + procdescs/main.c \ + property/main.c \ + returnstmt/return_npe_test.m \ + warnings/ParameterNotNullableExample.m \ + +FILES_ARC = \ + field_superclass/SubtypingExample.m \ + frontend/dispatch_examples.m \ + frontend/struct_initlistexpr.c \ + memory_leaks_benchmark/RetainReleaseExampleBucketingArc.m \ + memory_leaks_benchmark/TollBridgeExample.m \ + memory_leaks_benchmark/retain_cycle.m \ + memory_leaks_benchmark/retain_cycle2.m \ + npe/BoxedNumberExample.m \ + npe/ObjCMethodCallInCondition.m \ + npe/UpdateDict.m \ + npe/WeakCapturedVarsNPE.m \ + npe/nil_in_array_literal.m \ + npe/nil_in_dictionary_literal.m \ + npe/npe_conditional.m \ + npe/npe_self.m \ + npe/nullable.m \ + property/ExplicitIvarName.m \ + subtyping/KindOfClassExample.m \ + variadic_methods/premature_nil_termination.m \ + +compile: + clang $(OPTIONS) $(FILES) $(FILES_BUCKET_ALL) + clang $(OPTIONS) -fobjc-arc $(FILES_ARC) + +CLEAN_EXTRA = infer-out-arc infer-out-all + +analyze: + $(INFER_BIN) -a $(ANALYZER) --cxx --ml-buckets all --check-duplicate-symbols -o infer-out-all -- clang $(OPTIONS) $(FILES_BUCKET_ALL) >/dev/null 2>duplicates.txt + grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + $(INFER_BIN) -a $(ANALYZER) --cxx --ml-buckets cf --check-duplicate-symbols -o infer-out -- clang $(OPTIONS) $(FILES) >/dev/null 2>duplicates.txt + grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + $(INFER_BIN) -a $(ANALYZER) --cxx --ml-buckets cf --check-duplicate-symbols -o infer-out-arc -- clang $(OPTIONS) -fobjc-arc $(FILES_ARC) >/dev/null 2>duplicates.txt + grep "DUPLICATE_SYMBOLS" duplicates.txt; test $$? -ne 0 + cp infer-out-all/specs/* infer-out/specs + cp infer-out-arc/specs/* infer-out/specs diff --git a/infer/tests/codetoanalyze/objc/errors/category_procdesc/main.c b/infer/tests/codetoanalyze/objc/errors/category_procdesc/main.c index d625bbe57..4fc8d56e4 100644 --- a/infer/tests/codetoanalyze/objc/errors/category_procdesc/main.c +++ b/infer/tests/codetoanalyze/objc/errors/category_procdesc/main.c @@ -7,9 +7,10 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +#include #import "EOCPerson.h" -int main() { +int CategoryProcdescMain() { EOCPerson* person = [[EOCPerson alloc] init]; [person performDaysWork]; int* x = malloc(sizeof(int)); diff --git a/infer/tests/codetoanalyze/objc/errors/category_procdesc/main.dot b/infer/tests/codetoanalyze/objc/errors/category_procdesc/main.dot index e9ab3af55..516eaac8a 100644 --- a/infer/tests/codetoanalyze/objc/errors/category_procdesc/main.dot +++ b/infer/tests/codetoanalyze/objc/errors/category_procdesc/main.dot @@ -1,25 +1,25 @@ /* @generated */ digraph iCFG { -6 [label="6: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class EOCPerson ):unsigned long ) [line 13]\n n$3=_fun_NSObject_init(n$2:class EOCPerson *) virtual [line 13]\n *&person:class EOCPerson *=n$3 [line 13]\n " shape="box"] +6 [label="6: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class EOCPerson ):unsigned long ) [line 14]\n n$3=_fun_NSObject_init(n$2:class EOCPerson *) virtual [line 14]\n *&person:class EOCPerson *=n$3 [line 14]\n " shape="box"] 6 -> 5 ; -5 [label="5: Message Call: performDaysWork \n n$1=*&person:class EOCPerson * [line 14]\n _fun_EOCPerson_performDaysWork(n$1:class EOCPerson *) virtual [line 14]\n " shape="box"] +5 [label="5: Message Call: performDaysWork \n n$1=*&person:class EOCPerson * [line 15]\n _fun_EOCPerson_performDaysWork(n$1:class EOCPerson *) virtual [line 15]\n " shape="box"] 5 -> 4 ; -4 [label="4: DeclStmt \n n$0=_fun_malloc_no_fail(sizeof(int ):int ) [line 15]\n *&x:int *=n$0 [line 15]\n " shape="box"] +4 [label="4: DeclStmt \n n$0=_fun_malloc_no_fail(sizeof(int ):int ) [line 16]\n *&x:int *=n$0 [line 16]\n " shape="box"] 4 -> 3 ; -3 [label="3: Return Stmt \n *&return:int =0 [line 16]\n " shape="box"] +3 [label="3: Return Stmt \n *&return:int =0 [line 17]\n " shape="box"] 3 -> 2 ; -2 [label="2: Exit main \n " color=yellow style=filled] +2 [label="2: Exit CategoryProcdescMain \n " color=yellow style=filled] -1 [label="1: Start main\nFormals: \nLocals: x:int * person:class EOCPerson * \n DECLARE_LOCALS(&return,&x,&person); [line 12]\n " color=yellow style=filled] +1 [label="1: Start CategoryProcdescMain\nFormals: \nLocals: x:int * person:class EOCPerson * \n DECLARE_LOCALS(&return,&x,&person); [line 13]\n " color=yellow style=filled] 1 -> 6 ; diff --git a/infer/tests/codetoanalyze/objc/errors/field_superclass/SubtypingExample.m b/infer/tests/codetoanalyze/objc/errors/field_superclass/SubtypingExample.m index 87c19eb59..4b50bbb35 100644 --- a/infer/tests/codetoanalyze/objc/errors/field_superclass/SubtypingExample.m +++ b/infer/tests/codetoanalyze/objc/errors/field_superclass/SubtypingExample.m @@ -82,4 +82,4 @@ int testFields() { return [employee getAge]; } -int test() { return 1 / (testFields() - 29); } +int subtyping_test() { return 1 / (testFields() - 29); } diff --git a/infer/tests/codetoanalyze/objc/errors/field_superclass/SuperExample.dot b/infer/tests/codetoanalyze/objc/errors/field_superclass/SuperExample.dot index a2514f594..ddb7b7c68 100644 --- a/infer/tests/codetoanalyze/objc/errors/field_superclass/SuperExample.dot +++ b/infer/tests/codetoanalyze/objc/errors/field_superclass/SuperExample.dot @@ -1,6 +1,6 @@ /* @generated */ digraph iCFG { -12 [label="12: DeclStmt \n n$1=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 42]\n n$2=_fun_NSObject_init(n$1:class A *) virtual [line 42]\n *&a:struct objc_object *=n$2 [line 42]\n " shape="box"] +12 [label="12: DeclStmt \n n$1=_fun___objc_alloc_no_fail(sizeof(class ASuper ):unsigned long ) [line 42]\n n$2=_fun_NSObject_init(n$1:class ASuper *) virtual [line 42]\n *&a:struct objc_object *=n$2 [line 42]\n " shape="box"] 12 -> 11 ; @@ -8,29 +8,29 @@ digraph iCFG { 11 -> 10 ; -10 [label="10: Exit main \n " color=yellow style=filled] +10 [label="10: Exit super_example_main \n " color=yellow style=filled] -9 [label="9: Start main\nFormals: argc:int argv:char **\nLocals: a:struct objc_object * \n DECLARE_LOCALS(&return,&a); [line 40]\n " color=yellow style=filled] +9 [label="9: Start super_example_main\nFormals: argc:int argv:char **\nLocals: a:struct objc_object * \n DECLARE_LOCALS(&return,&a); [line 40]\n " color=yellow style=filled] 9 -> 12 ; -8 [label="8: BinaryOperatorStmt: Assign \n n$2=*&self:class A * [line 33]\n n$3=_fun_B_init(n$2:class A *) [line 33]\n *&self:class A *=n$3 [line 33]\n " shape="box"] +8 [label="8: BinaryOperatorStmt: Assign \n n$2=*&self:class ASuper * [line 33]\n n$3=_fun_BSuper_init(n$2:class ASuper *) [line 33]\n *&self:class ASuper *=n$3 [line 33]\n " shape="box"] 8 -> 7 ; -7 [label="7: BinaryOperatorStmt: Assign \n n$1=*&self:class A * [line 34]\n *n$1.a:int =4 [line 34]\n " shape="box"] +7 [label="7: BinaryOperatorStmt: Assign \n n$1=*&self:class ASuper * [line 34]\n *n$1.a:int =4 [line 34]\n " shape="box"] 7 -> 6 ; -6 [label="6: Return Stmt \n n$0=*&self:class A * [line 35]\n *&return:struct objc_object *=n$0 [line 35]\n " shape="box"] +6 [label="6: Return Stmt \n n$0=*&self:class ASuper * [line 35]\n *&return:struct objc_object *=n$0 [line 35]\n " shape="box"] 6 -> 5 ; -5 [label="5: Exit A_init \n " color=yellow style=filled] +5 [label="5: Exit ASuper_init \n " color=yellow style=filled] -4 [label="4: Start A_init\nFormals: self:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 32]\n " color=yellow style=filled] +4 [label="4: Start ASuper_init\nFormals: self:class ASuper *\nLocals: \n DECLARE_LOCALS(&return); [line 32]\n " color=yellow style=filled] 4 -> 8 ; @@ -38,10 +38,10 @@ digraph iCFG { 3 -> 2 ; -2 [label="2: Exit B_init \n " color=yellow style=filled] +2 [label="2: Exit BSuper_init \n " color=yellow style=filled] -1 [label="1: Start B_init\nFormals: self:class B *\nLocals: \n DECLARE_LOCALS(&return); [line 18]\n " color=yellow style=filled] +1 [label="1: Start BSuper_init\nFormals: self:class BSuper *\nLocals: \n DECLARE_LOCALS(&return); [line 18]\n " color=yellow style=filled] 1 -> 3 ; diff --git a/infer/tests/codetoanalyze/objc/errors/field_superclass/SuperExample.m b/infer/tests/codetoanalyze/objc/errors/field_superclass/SuperExample.m index dd74cc5db..7efb96e8d 100644 --- a/infer/tests/codetoanalyze/objc/errors/field_superclass/SuperExample.m +++ b/infer/tests/codetoanalyze/objc/errors/field_superclass/SuperExample.m @@ -9,11 +9,11 @@ #import -@interface B : NSObject +@interface BSuper : NSObject @end -@implementation B +@implementation BSuper - (instancetype)init { return nil; @@ -21,11 +21,11 @@ @end -@interface A : B +@interface ASuper : BSuper @end -@implementation A { +@implementation ASuper { int a; } @@ -37,8 +37,8 @@ @end -int main(int argc, char* argv[]) { +int super_example_main(int argc, char* argv[]) { @autoreleasepool { - __unused id a = [A new]; + __unused id a = [ASuper new]; } } diff --git a/infer/tests/codetoanalyze/objc/errors/field_superclass/field.c b/infer/tests/codetoanalyze/objc/errors/field_superclass/field.c index 8cc84a92f..cb02b5300 100644 --- a/infer/tests/codetoanalyze/objc/errors/field_superclass/field.c +++ b/infer/tests/codetoanalyze/objc/errors/field_superclass/field.c @@ -9,7 +9,7 @@ #include "B.h" -int main() { +int field_superclass_main() { B* b = [B alloc]; b->x = 5; b->a = b; // create cycle --> leak diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/BlockVar.h b/infer/tests/codetoanalyze/objc/errors/frontend/BlockVar.h new file mode 120000 index 000000000..e33a18244 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/BlockVar.h @@ -0,0 +1 @@ +../../frontend/block/BlockVar.h \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/BlockVar.m b/infer/tests/codetoanalyze/objc/errors/frontend/BlockVar.m new file mode 120000 index 000000000..c20f38ed7 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/BlockVar.m @@ -0,0 +1 @@ +../../frontend/block/BlockVar.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/GetterExample.h b/infer/tests/codetoanalyze/objc/errors/frontend/GetterExample.h new file mode 120000 index 000000000..d7f73e359 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/GetterExample.h @@ -0,0 +1 @@ +../../frontend/property/GetterExample.h \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/GetterExample.m b/infer/tests/codetoanalyze/objc/errors/frontend/GetterExample.m new file mode 120000 index 000000000..125cf66c8 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/GetterExample.m @@ -0,0 +1 @@ +../../frontend/property/GetterExample.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/NSAssert_example.m b/infer/tests/codetoanalyze/objc/errors/frontend/NSAssert_example.m new file mode 120000 index 000000000..f2c1086f7 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/NSAssert_example.m @@ -0,0 +1 @@ +../../frontend/assertions/NSAssert_example.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/PropertyAttributes.m b/infer/tests/codetoanalyze/objc/errors/frontend/PropertyAttributes.m new file mode 120000 index 000000000..f151d798d --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/PropertyAttributes.m @@ -0,0 +1 @@ +../../frontend/property/PropertyAttributes.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/block-it.m b/infer/tests/codetoanalyze/objc/errors/frontend/block-it.m new file mode 120000 index 000000000..843d3fa99 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/block-it.m @@ -0,0 +1 @@ +../../frontend/block/block-it.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/block.m b/infer/tests/codetoanalyze/objc/errors/frontend/block.m new file mode 120000 index 000000000..1de41f2a0 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/block.m @@ -0,0 +1 @@ +../../frontend/block/block.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/block_no_args.m b/infer/tests/codetoanalyze/objc/errors/frontend/block_no_args.m new file mode 120000 index 000000000..8b1ac559c --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/block_no_args.m @@ -0,0 +1 @@ +../../frontend/block/block_no_args.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/block_release.m b/infer/tests/codetoanalyze/objc/errors/frontend/block_release.m new file mode 120000 index 000000000..c86702fd7 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/block_release.m @@ -0,0 +1 @@ +../../frontend/block/block_release.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/compound_literal.c b/infer/tests/codetoanalyze/objc/errors/frontend/compound_literal.c new file mode 120000 index 000000000..1f8dbb3ee --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/compound_literal.c @@ -0,0 +1 @@ +../../../c/frontend/initialization/compound_literal.c \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/dispatch.m b/infer/tests/codetoanalyze/objc/errors/frontend/dispatch.m new file mode 120000 index 000000000..ad2c96bb7 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/dispatch.m @@ -0,0 +1 @@ +../../frontend/block/dispatch.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/dispatch_examples.m b/infer/tests/codetoanalyze/objc/errors/frontend/dispatch_examples.m new file mode 120000 index 000000000..d78a6db00 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/dispatch_examples.m @@ -0,0 +1 @@ +../../frontend/block/dispatch_examples.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/dispatch_in_macro.m b/infer/tests/codetoanalyze/objc/errors/frontend/dispatch_in_macro.m new file mode 120000 index 000000000..2556f0251 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/dispatch_in_macro.m @@ -0,0 +1 @@ +../../frontend/block/dispatch_in_macro.m \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/frontend/struct_initlistexpr.c b/infer/tests/codetoanalyze/objc/errors/frontend/struct_initlistexpr.c new file mode 120000 index 000000000..eb7e6d633 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/frontend/struct_initlistexpr.c @@ -0,0 +1 @@ +../../../c/frontend/initialization/struct_initlistexpr.c \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/errors/issues.exp b/infer/tests/codetoanalyze/objc/errors/issues.exp new file mode 100644 index 000000000..2c1582206 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/issues.exp @@ -0,0 +1,110 @@ +category_procdesc/main.c, CategoryProcdescMain, 2, MEMORY_LEAK +category_procdesc/main.c, CategoryProcdescMain, 3, MEMORY_LEAK +field_superclass/SubtypingExample.m, Employee_initWithName:andAge:andEducation:, 6, DIVIDE_BY_ZERO +field_superclass/SubtypingExample.m, subtyping_test, 0, DIVIDE_BY_ZERO +field_superclass/SuperExample.m, ASuper_init, 2, NULL_DEREFERENCE +field_superclass/SuperExample.m, super_example_main, 2, MEMORY_LEAK +field_superclass/field.c, field_superclass_main, 3, RETAIN_CYCLE +frontend/BlockVar.m, BlockVar_blockPostBad, 5, NULL_DEREFERENCE +frontend/BlockVar.m, BlockVar_capturedNullDeref, 5, NULL_DEREFERENCE +frontend/BlockVar.m, BlockVar_navigateToURLInBackground, 8, NULL_DEREFERENCE +frontend/NSAssert_example.m, NSAssert_addTarget:, 1, MEMORY_LEAK +frontend/NSAssert_example.m, NSAssert_initWithRequest:, 1, MEMORY_LEAK +frontend/NSAssert_example.m, test1, 1, MEMORY_LEAK +frontend/NSAssert_example.m, test1, 1, MEMORY_LEAK +frontend/NSAssert_example.m, test2, 1, MEMORY_LEAK +frontend/NSAssert_example.m, test2, 1, MEMORY_LEAK +frontend/block.m, main1, 31, DIVIDE_BY_ZERO +frontend/block_no_args.m, My_manager_m, 10, NULL_DEREFERENCE +frontend/block_release.m, My_manager_blockReleaseTODO, 5, MEMORY_LEAK +frontend/compound_literal.c, init_with_compound_literal, 2, DIVIDE_BY_ZERO +frontend/dispatch.m, DispatchA_dispatch_a_block_variable_from_macro_delivers_initialised_object, 3, DIVIDE_BY_ZERO +frontend/struct_initlistexpr.c, field_set_correctly, 2, DIVIDE_BY_ZERO +frontend/struct_initlistexpr.c, implicit_expr_set_correctly, 3, DIVIDE_BY_ZERO +frontend/struct_initlistexpr.c, point_coords_set_correctly, 2, DIVIDE_BY_ZERO +global_const/global_const.m, SimpleRoot_doSomethingBadWithDict:andString:, 3, NULL_DEREFERENCE +memory_leaks_benchmark/CADisplayLinkRetainCycle.m, testCycle, 3, RETAIN_CYCLE +memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_blockCapturedVarLeak, 3, MEMORY_LEAK +memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_blockFreeNoLeakTODO, 3, MEMORY_LEAK +memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_createCloseCrossGlyph:, 2, MEMORY_LEAK +memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_measureFrameSizeForText, 1, MEMORY_LEAK +memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_regularLeak, 3, MEMORY_LEAK +memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_test, 3, MEMORY_LEAK +memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_test1:, 1, MEMORY_LEAK +memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_test2:, 1, MEMORY_LEAK +memory_leaks_benchmark/NSStringInitWithBytesNoCopyExample.m, StringInitA_macForIV:, 2, MEMORY_LEAK +memory_leaks_benchmark/RetainCycleStaticVar.m, RetainCSVycleStaticVar, 2, RETAIN_CYCLE +memory_leaks_benchmark/RetainReleaseExample2.m, test3, 0, MEMORY_LEAK +memory_leaks_benchmark/RetainReleaseExample2.m, test3, 0, RETURN_VALUE_IGNORED +memory_leaks_benchmark/RetainReleaseExample2.m, test4, 3, MEMORY_LEAK +memory_leaks_benchmark/RetainReleaseExample2.m, test5, 2, MEMORY_LEAK +memory_leaks_benchmark/RetainReleaseExample2.m, test6, 3, MEMORY_LEAK +memory_leaks_benchmark/RetainReleaseExampleBucketing.m, RetainReleaseTest, 0, RETURN_VALUE_IGNORED +memory_leaks_benchmark/RetainReleaseExampleBucketingArc.m, RetainReleaseArcTest, 0, RETURN_VALUE_IGNORED +memory_leaks_benchmark/TollBridgeExample.m, TollBridgeExample_brideRetained, 2, MEMORY_LEAK +memory_leaks_benchmark/TollBridgeExample.m, TollBridgeExample_bridge, 2, MEMORY_LEAK +memory_leaks_benchmark/retain_cycle.m, strongcycle, 6, RETAIN_CYCLE +memory_leaks_benchmark/retain_cycle2.m, strongcycle2, 4, RETAIN_CYCLE +npe/Fraction.m, test_virtual_call, 7, NULL_DEREFERENCE +npe/Npe_with_equal_names.m, EqualNamesTest, 3, NULL_DEREFERENCE +npe/UpdateDict.m, add_nil_in_dict, 10, NULL_DEREFERENCE +npe/UpdateDict.m, add_nil_to_array, 4, NULL_DEREFERENCE +npe/UpdateDict.m, insert_nil_in_array, 4, NULL_DEREFERENCE +npe/UpdateDict.m, nullable_NSDictionary_objectForKey, 4, NULL_DEREFERENCE +npe/UpdateDict.m, nullable_NSDictionary_objectForKeyedSubscript, 5, NULL_DEREFERENCE +npe/UpdateDict.m, nullable_NSMapTable_objectForKey, 4, NULL_DEREFERENCE +npe/UpdateDict.m, update_array_with_null, 5, NULL_DEREFERENCE +npe/UpdateDict.m, update_dict_with_key_null, 10, NULL_DEREFERENCE +npe/WeakCapturedVarsNPE.m, __objc_anonymous_block_WeakCapturedA_strongSelfNoCheck______2, 2, NULL_DEREFERENCE +npe/block.m, BlockA_doSomethingThenCallback:, 2, PARAMETER_NOT_NULL_CHECKED +npe/block.m, BlockA_foo, 5, NULL_DEREFERENCE +npe/block.m, BlockA_foo3:, 3, NULL_DEREFERENCE +npe/block.m, BlockA_foo4:, 6, NULL_DEREFERENCE +npe/block.m, BlockA_foo7, 2, IVAR_NOT_NULL_CHECKED +npe/blockenum.m, BlockEnumA_allResultsList:, 1, MEMORY_LEAK +npe/blockenum.m, BlockEnumA_foo1:, 2, MEMORY_LEAK +npe/nil_in_array_literal.m, Arr_nilInArrayLiteral0, 4, NULL_DEREFERENCE +npe/nil_in_array_literal.m, Arr_nilInArrayLiteral1, 4, NULL_DEREFERENCE +npe/nil_in_array_literal.m, Arr_nilInArrayLiteral2, 4, NULL_DEREFERENCE +npe/nil_in_array_literal.m, Arr_nilInArrayLiteral3, 4, NULL_DEREFERENCE +npe/nil_in_array_literal.m, Arr_nilInArrayWithObject, 4, NULL_DEREFERENCE +npe/nil_in_dictionary_literal.m, ADict_nilInDictionaryLiteralKey0, 4, NULL_DEREFERENCE +npe/nil_in_dictionary_literal.m, ADict_nilInDictionaryLiteralKey1, 4, NULL_DEREFERENCE +npe/nil_in_dictionary_literal.m, ADict_nilInDictionaryLiteralKey2, 4, NULL_DEREFERENCE +npe/nil_in_dictionary_literal.m, ADict_nilInDictionaryLiteralKey3, 4, NULL_DEREFERENCE +npe/nil_in_dictionary_literal.m, ADict_nilInDictionaryLiteralValue0, 4, NULL_DEREFERENCE +npe/nil_in_dictionary_literal.m, ADict_nilInDictionaryLiteralValue1, 4, NULL_DEREFERENCE +npe/nil_in_dictionary_literal.m, ADict_nilInDictionaryLiteralValue2, 4, NULL_DEREFERENCE +npe/nil_in_dictionary_literal.m, ADict_nilInDictionaryLiteralValue3, 4, NULL_DEREFERENCE +npe/nil_param.m, NilParamMain, 4, MEMORY_LEAK +npe/npe_conditional.m, conditionalNPE, 3, NULL_DEREFERENCE +npe/npe_self.m, CSelf_test, 3, NULL_DEREFERENCE +npe/null_returned_by_method.m, NullReturnedByMethodA_test1, 1, NULL_DEREFERENCE +npe/nullable.m, derefNullableParamDirect, 0, NULL_DEREFERENCE +npe/nullable.m, derefNullableParamIndirect, 2, NULL_DEREFERENCE +npe/nullable.m, parameter_nullable_bug, 5, NULL_DEREFERENCE +npe/skip_method_with_nil_object.m, SkipMethodNilA_testBug:, 6, PARAMETER_NOT_NULL_CHECKED +procdescs/main.c, ProcdescMain, 2, MEMORY_LEAK +procdescs/main.c, ProcdescMain, 3, MEMORY_LEAK +procdescs/main.c, call_nslog, 1, MEMORY_LEAK +procdescs/main.c, call_nslog, 2, MEMORY_LEAK +procdescs/main.c, call_nslog, 3, MEMORY_LEAK +property/ExplicitIvarName.m, ExplicitIvarNameA_testDefaultName, 7, NULL_DEREFERENCE +property/ExplicitIvarName.m, ExplicitIvarNameA_testExplicit, 6, NULL_DEREFERENCE +property/main.c, property_main, 2, MEMORY_LEAK +property/main.c, property_main, 3, MEMORY_LEAK +subtyping/KindOfClassExample.m, shouldThrowDivideByZero1, 2, DIVIDE_BY_ZERO +subtyping/KindOfClassExample.m, shouldThrowDivideByZero2, 2, DIVIDE_BY_ZERO +subtyping/KindOfClassExample.m, shouldThrowDivideByZero3, 3, DIVIDE_BY_ZERO +taint/sources.m, testNSHTTPCookie1, 5, TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION +taint/sources.m, testNSHTTPCookie2, 5, TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION +taint/sources.m, testNSHTTPCookie3, 5, TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION +taint/sources.m, testNSHTTPCookie4, 5, TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION +taint/viewController.m, ExampleDelegate_application:openURL:sourceApplication:annotation:, 7, TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION +variadic_methods/premature_nil_termination.m, PrematureNilTermA_nilInArrayWithObjects, 5, PREMATURE_NIL_TERMINATION_ARGUMENT +warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackChain:, 2, IVAR_NOT_NULL_CHECKED +warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackChain:, 2, PARAMETER_NOT_NULL_CHECKED +warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackField, 2, IVAR_NOT_NULL_CHECKED +warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackSimple:, 2, PARAMETER_NOT_NULL_CHECKED +warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackSimpleAliasing:, 3, PARAMETER_NOT_NULL_CHECKED +warnings/ParameterNotNullableExample.m, FBAudioRecorder_test, 3, NULL_DEREFERENCE diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/ArcExample.dot b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/ArcExample.dot index 5dbc192b0..a8be8c393 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/ArcExample.dot +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/ArcExample.dot @@ -8,10 +8,10 @@ digraph iCFG { 7 -> 6 ; -6 [label="6: Exit A_newS \n " color=yellow style=filled] +6 [label="6: Exit ArcA_newS \n " color=yellow style=filled] -5 [label="5: Start A_newS\nFormals: self:class A *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 28]\n " color=yellow style=filled] +5 [label="5: Start ArcA_newS\nFormals: self:class ArcA *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 28]\n " color=yellow style=filled] 5 -> 8 ; @@ -23,10 +23,10 @@ digraph iCFG { 3 -> 2 ; -2 [label="2: Exit A_getS \n " color=yellow style=filled] +2 [label="2: Exit ArcA_getS \n " color=yellow style=filled] -1 [label="1: Start A_getS\nFormals: self:class A *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 22]\n " color=yellow style=filled] +1 [label="1: Start ArcA_getS\nFormals: self:class ArcA *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 22]\n " color=yellow style=filled] 1 -> 4 ; diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/ArcExample.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/ArcExample.m index e0c571683..bff649799 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/ArcExample.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/ArcExample.m @@ -10,13 +10,13 @@ #import #import -@interface A : NSObject { +@interface ArcA : NSObject { int x; } -@property A* son; +@property ArcA* son; @end -@implementation A +@implementation ArcA /* autorelease is added */ - (NSString*)getS { diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/AutoreleaseExample.dot b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/AutoreleaseExample.dot index e86008cdd..ea4a2bff4 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/AutoreleaseExample.dot +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/AutoreleaseExample.dot @@ -16,38 +16,38 @@ digraph iCFG { 32 -> 31 ; -31 [label="31: Exit test3 \n " color=yellow style=filled] +31 [label="31: Exit autorelease_test3 \n " color=yellow style=filled] -30 [label="30: Start test3\nFormals: \nLocals: c:class NSString * string:class NSString * pool:class NSAutoreleasePool * \n DECLARE_LOCALS(&return,&c,&string,&pool); [line 59]\n " color=yellow style=filled] +30 [label="30: Start autorelease_test3\nFormals: \nLocals: c:class NSString * string:class NSString * pool:class NSAutoreleasePool * \n DECLARE_LOCALS(&return,&c,&string,&pool); [line 59]\n " color=yellow style=filled] 30 -> 35 ; -29 [label="29: DeclStmt \n *&s1:class A *=0 [line 48]\n " shape="box"] +29 [label="29: DeclStmt \n *&s1:class Auto *=0 [line 48]\n " shape="box"] 29 -> 28 ; -28 [label="28: DeclStmt \n *&s2:class A *=0 [line 49]\n " shape="box"] +28 [label="28: DeclStmt \n *&s2:class Auto *=0 [line 49]\n " shape="box"] 28 -> 27 ; -27 [label="27: DeclStmt \n *&s3:class A *=0 [line 50]\n " shape="box"] +27 [label="27: DeclStmt \n *&s3:class Auto *=0 [line 50]\n " shape="box"] 27 -> 26 ; -26 [label="26: BinaryOperatorStmt: Assign \n n$3=_fun_createA() [line 52]\n *&s1:class A *=n$3 [line 52]\n " shape="box"] +26 [label="26: BinaryOperatorStmt: Assign \n n$3=_fun_createA() [line 52]\n *&s1:class Auto *=n$3 [line 52]\n " shape="box"] 26 -> 25 ; -25 [label="25: BinaryOperatorStmt: Assign \n n$2=_fun_createA() [line 53]\n *&s2:class A *=n$2 [line 53]\n " shape="box"] +25 [label="25: BinaryOperatorStmt: Assign \n n$2=_fun_createA() [line 53]\n *&s2:class Auto *=n$2 [line 53]\n " shape="box"] 25 -> 24 ; -24 [label="24: BinaryOperatorStmt: Assign \n n$1=_fun_createA() [line 54]\n *&s3:class A *=n$1 [line 54]\n " shape="box"] +24 [label="24: BinaryOperatorStmt: Assign \n n$1=_fun_createA() [line 54]\n *&s3:class Auto *=n$1 [line 54]\n " shape="box"] 24 -> 23 ; -23 [label="23: Release the autorelease pool \n n$0=_fun___objc_release_autorelease_pool(&s1:class A *,&s3:class A *,&s2:class A *) [line 51]\n " shape="box"] +23 [label="23: Release the autorelease pool \n n$0=_fun___objc_release_autorelease_pool(&s1:class Auto *,&s3:class Auto *,&s2:class Auto *) [line 51]\n " shape="box"] 23 -> 22 ; @@ -55,42 +55,42 @@ digraph iCFG { 22 -> 21 ; -21 [label="21: Exit test2 \n " color=yellow style=filled] +21 [label="21: Exit autorelease_test2 \n " color=yellow style=filled] -20 [label="20: Start test2\nFormals: \nLocals: s3:class A * s2:class A * s1:class A * \n DECLARE_LOCALS(&return,&s3,&s2,&s1); [line 47]\n " color=yellow style=filled] +20 [label="20: Start autorelease_test2\nFormals: \nLocals: s3:class Auto * s2:class Auto * s1:class Auto * \n DECLARE_LOCALS(&return,&s3,&s2,&s1); [line 47]\n " color=yellow style=filled] 20 -> 29 ; -19 [label="19: DeclStmt \n *&s1:class A *=0 [line 35]\n " shape="box"] +19 [label="19: DeclStmt \n *&s1:class Auto *=0 [line 35]\n " shape="box"] 19 -> 18 ; -18 [label="18: DeclStmt \n *&s2:class A *=0 [line 36]\n " shape="box"] +18 [label="18: DeclStmt \n *&s2:class Auto *=0 [line 36]\n " shape="box"] 18 -> 17 ; -17 [label="17: DeclStmt \n *&s3:class A *=0 [line 37]\n " shape="box"] +17 [label="17: DeclStmt \n *&s3:class Auto *=0 [line 37]\n " shape="box"] 17 -> 16 ; -16 [label="16: BinaryOperatorStmt: Assign \n n$5=_fun_createA() [line 39]\n *&s1:class A *=n$5 [line 39]\n " shape="box"] +16 [label="16: BinaryOperatorStmt: Assign \n n$5=_fun_createA() [line 39]\n *&s1:class Auto *=n$5 [line 39]\n " shape="box"] 16 -> 15 ; -15 [label="15: Message Call: retain \n n$3=*&s1:class A * [line 40]\n n$4=_fun___objc_retain(n$3:class A *) [line 40]\n " shape="box"] +15 [label="15: Message Call: retain \n n$3=*&s1:class Auto * [line 40]\n n$4=_fun___objc_retain(n$3:class Auto *) [line 40]\n " shape="box"] 15 -> 14 ; -14 [label="14: BinaryOperatorStmt: Assign \n n$2=_fun_createA() [line 41]\n *&s2:class A *=n$2 [line 41]\n " shape="box"] +14 [label="14: BinaryOperatorStmt: Assign \n n$2=_fun_createA() [line 41]\n *&s2:class Auto *=n$2 [line 41]\n " shape="box"] 14 -> 13 ; -13 [label="13: BinaryOperatorStmt: Assign \n n$1=_fun_createA() [line 42]\n *&s3:class A *=n$1 [line 42]\n " shape="box"] +13 [label="13: BinaryOperatorStmt: Assign \n n$1=_fun_createA() [line 42]\n *&s3:class Auto *=n$1 [line 42]\n " shape="box"] 13 -> 12 ; -12 [label="12: Release the autorelease pool \n n$0=_fun___objc_release_autorelease_pool(&s1:class A *,&s2:class A *,&s3:class A *) [line 38]\n " shape="box"] +12 [label="12: Release the autorelease pool \n n$0=_fun___objc_release_autorelease_pool(&s1:class Auto *,&s2:class Auto *,&s3:class Auto *) [line 38]\n " shape="box"] 12 -> 11 ; @@ -98,25 +98,25 @@ digraph iCFG { 11 -> 10 ; -10 [label="10: Exit test1 \n " color=yellow style=filled] +10 [label="10: Exit autorelease_test1 \n " color=yellow style=filled] -9 [label="9: Start test1\nFormals: \nLocals: s3:class A * s2:class A * s1:class A * \n DECLARE_LOCALS(&return,&s3,&s2,&s1); [line 34]\n " color=yellow style=filled] +9 [label="9: Start autorelease_test1\nFormals: \nLocals: s3:class Auto * s2:class Auto * s1:class Auto * \n DECLARE_LOCALS(&return,&s3,&s2,&s1); [line 34]\n " color=yellow style=filled] 9 -> 19 ; -8 [label="8: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 30]\n n$3=_fun_NSObject_init(n$2:class A *) virtual [line 30]\n *&s1:class A *=n$3 [line 30]\n " shape="box"] +8 [label="8: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class Auto ):unsigned long ) [line 30]\n n$3=_fun_NSObject_init(n$2:class Auto *) virtual [line 30]\n *&s1:class Auto *=n$3 [line 30]\n " shape="box"] 8 -> 7 ; -7 [label="7: Return Stmt \n n$0=*&s1:class A * [line 31]\n n$1=_fun___set_autorelease_attribute(n$0:class A *) [line 31]\n *&return:class A *=n$1 [line 31]\n " shape="box"] +7 [label="7: Return Stmt \n n$0=*&s1:class Auto * [line 31]\n n$1=_fun___set_autorelease_attribute(n$0:class Auto *) [line 31]\n *&return:class Auto *=n$1 [line 31]\n " shape="box"] 7 -> 6 ; 6 [label="6: Exit createA \n " color=yellow style=filled] -5 [label="5: Start createA\nFormals: \nLocals: s1:class A * \n DECLARE_LOCALS(&return,&s1); [line 29]\n " color=yellow style=filled] +5 [label="5: Start createA\nFormals: \nLocals: s1:class Auto * \n DECLARE_LOCALS(&return,&s1); [line 29]\n " color=yellow style=filled] 5 -> 8 ; @@ -128,10 +128,10 @@ digraph iCFG { 3 -> 2 ; -2 [label="2: Exit A_main \n " color=yellow style=filled] +2 [label="2: Exit Auto_autorelease_main \n " color=yellow style=filled] -1 [label="1: Start A_main\nFormals: self:class A *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 22]\n " color=yellow style=filled] +1 [label="1: Start Auto_autorelease_main\nFormals: self:class Auto *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 22]\n " color=yellow style=filled] 1 -> 4 ; diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/AutoreleaseExample.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/AutoreleaseExample.m index 710e6d03d..42dfb5a57 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/AutoreleaseExample.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/AutoreleaseExample.m @@ -11,30 +11,30 @@ #import #import -@interface A : NSObject { +@interface Auto : NSObject { int x; } -@property A* son; +@property Auto* son; @end -@implementation A +@implementation Auto -- (NSString*)main { +- (NSString*)autorelease_main { NSString* s = [NSString alloc]; return [s autorelease]; } @end -A* createA() { - A* s1 = [[A alloc] init]; +Auto* createA() { + Auto* s1 = [[Auto alloc] init]; return [s1 autorelease]; } -int test1() { - A* s1 = nil; - A* s2 = nil; - A* s3 = nil; +int autorelease_test1() { + Auto* s1 = nil; + Auto* s2 = nil; + Auto* s3 = nil; @autoreleasepool { s1 = createA(); [s1 retain]; @@ -44,10 +44,10 @@ int test1() { return 0; } -int test2() { - A* s1 = nil; - A* s2 = nil; - A* s3 = nil; +int autorelease_test2() { + Auto* s1 = nil; + Auto* s2 = nil; + Auto* s3 = nil; @autoreleasepool { s1 = createA(); s2 = createA(); @@ -56,7 +56,7 @@ int test2() { return 0; } -void test3() { +void autorelease_test3() { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSString* string = [[NSString alloc] autorelease]; // use the string diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/CADisplayLinkRetainCycle.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/CADisplayLinkRetainCycle.m index 51ebacae8..381696f51 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/CADisplayLinkRetainCycle.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/CADisplayLinkRetainCycle.m @@ -10,14 +10,14 @@ #import #import -@interface A : NSObject +@interface CADisplay : NSObject @property(nonatomic, strong) CADisplayLink* displayLink; - (void)bla; - (void)invalidate; @end -@implementation A +@implementation CADisplay - init { _displayLink = @@ -41,13 +41,13 @@ void testCycle() { - A* a = [[A alloc] init]; - A* b = a; + CADisplay* a = [[CADisplay alloc] init]; + CADisplay* b = a; } void testNoCycle() { - A* a = [[A alloc] init]; + CADisplay* a = [[CADisplay alloc] init]; [a invalidate]; // break the cycle [a dealloc]; } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/MemoryLeakRaii.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/MemoryLeakRaii.m index 9cde8a7aa..e2e468dae 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/MemoryLeakRaii.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/MemoryLeakRaii.m @@ -10,13 +10,13 @@ #include #include -@interface A : NSObject +@interface Araii : NSObject @property char* buffer; @end -@implementation A +@implementation Araii - (instancetype)initWithBuffer { _buffer = malloc(sizeof(char)); @@ -29,7 +29,7 @@ @end -int main() { - [[A alloc] initWithBuffer]; +int memory_leak_raii_main() { + [[Araii alloc] initWithBuffer]; return 0; } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/NSStringInitWithBytesNoCopyExample.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/NSStringInitWithBytesNoCopyExample.m index a9cd5ef10..dfb62cfb1 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/NSStringInitWithBytesNoCopyExample.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/NSStringInitWithBytesNoCopyExample.m @@ -10,11 +10,11 @@ #import #import -@interface A : NSObject +@interface StringInitA : NSObject @end -@implementation A +@implementation StringInitA NSString* createURLQueryStringBodyEscaping(NSDictionary* parameters, NSString* s) { diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleStaticVar.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleStaticVar.m index 139597f39..5ed6b9778 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleStaticVar.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleStaticVar.m @@ -11,26 +11,30 @@ typedef void (^MyHandler)(NSString* name); -@interface C : NSObject +@interface RetainCSV : NSObject @property(nonatomic, strong) MyHandler handler; @property(nonatomic, strong) NSString* name; -@property(nonatomic, strong) C* bla1; -@property(nonatomic, strong) C* bla2; +@property(nonatomic, strong) RetainCSV* bla1; +@property(nonatomic, strong) RetainCSV* bla2; @end -@implementation C +@implementation RetainCSV + +- init { + return self; +} - (void)foo { static dispatch_once_t once; - static C* sharedInstance1; + static RetainCSV* sharedInstance1; dispatch_once(&once, ^{ - sharedInstance1 = [[C alloc] init]; + sharedInstance1 = [[RetainCSV alloc] init]; }); - static C* sharedInstance2; + static RetainCSV* sharedInstance2; dispatch_once(&once, ^{ - sharedInstance2 = [[C alloc] init]; + sharedInstance2 = [[RetainCSV alloc] init]; }); _bla1 = sharedInstance1; @@ -42,8 +46,8 @@ typedef void (^MyHandler)(NSString* name); @end -int main() { - C* c = [[C alloc] init]; +int RetainCSVycleStaticVar() { + RetainCSV* c = [[RetainCSV alloc] init]; [c foo]; return 0; } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample.dot b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample.dot index 5ddaf2781..2538667fb 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample.dot +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample.dot @@ -1,22 +1,33 @@ /* @generated */ digraph iCFG { -5 [label="5: DeclStmt \n n$3=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 21]\n n$4=_fun_NSObject_init(n$3:class A *) virtual [line 21]\n *&a:class A *=n$4 [line 21]\n " shape="box"] +8 [label="8: DeclStmt \n n$3=_fun___objc_alloc_no_fail(sizeof(class RRA ):unsigned long ) [line 25]\n n$4=_fun_RRA_init(n$3:class RRA *) virtual [line 25]\n *&a:class RRA *=n$4 [line 25]\n " shape="box"] - 5 -> 4 ; -4 [label="4: Message Call: retain \n n$1=*&a:class A * [line 22]\n n$2=_fun___objc_retain(n$1:class A *) [line 22]\n " shape="box"] + 8 -> 7 ; +7 [label="7: Message Call: retain \n n$1=*&a:class RRA * [line 26]\n n$2=_fun___objc_retain(n$1:class RRA *) [line 26]\n " shape="box"] - 4 -> 3 ; -3 [label="3: Message Call: release \n n$0=*&a:class A * [line 23]\n _fun___objc_release(n$0:class A *) [line 23]\n " shape="box"] + 7 -> 6 ; +6 [label="6: Message Call: release \n n$0=*&a:class RRA * [line 27]\n _fun___objc_release(n$0:class RRA *) [line 27]\n " shape="box"] + + + 6 -> 5 ; +5 [label="5: Exit retain_release_test \n " color=yellow style=filled] + + +4 [label="4: Start retain_release_test\nFormals: \nLocals: a:class RRA * \n DECLARE_LOCALS(&return,&a); [line 24]\n " color=yellow style=filled] + + + 4 -> 8 ; +3 [label="3: Return Stmt \n n$0=*&self:class RRA * [line 19]\n *&return:struct objc_object *=n$0 [line 19]\n " shape="box"] 3 -> 2 ; -2 [label="2: Exit test \n " color=yellow style=filled] +2 [label="2: Exit RRA_init \n " color=yellow style=filled] -1 [label="1: Start test\nFormals: \nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 20]\n " color=yellow style=filled] +1 [label="1: Start RRA_init\nFormals: self:class RRA *\nLocals: \n DECLARE_LOCALS(&return); [line 18]\n " color=yellow style=filled] - 1 -> 5 ; + 1 -> 3 ; } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample.m index a419560bc..eff2a94eb 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample.m @@ -9,16 +9,20 @@ #import -@interface A : NSObject +@interface RRA : NSObject @end -@implementation A +@implementation RRA + +- init { + return self; +} @end -void test() { - A* a = [[A alloc] init]; +void retain_release_test() { + RRA* a = [[RRA alloc] init]; [a retain]; [a release]; } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.dot b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.dot index 276741acc..c9e75f724 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.dot +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.dot @@ -1,129 +1,140 @@ /* @generated */ digraph iCFG { -33 [label="33: Call _fun___objc_release \n n$1=*&a:class A * [line 65]\n _fun___objc_release(n$1:class A *) [line 65]\n " shape="box"] +36 [label="36: Call _fun___objc_release \n n$1=*&a:class RR2 * [line 69]\n _fun___objc_release(n$1:class RR2 *) [line 69]\n " shape="box"] - 33 -> 29 ; -32 [label="32: Prune (false branch) \n n$0=*&a:class A * [line 64]\n PRUNE((n$0 == 0), false); [line 64]\n " shape="invhouse"] + 36 -> 32 ; +35 [label="35: Prune (false branch) \n n$0=*&a:class RR2 * [line 68]\n PRUNE((n$0 == 0), false); [line 68]\n " shape="invhouse"] - 32 -> 29 ; -31 [label="31: Prune (true branch) \n n$0=*&a:class A * [line 64]\n PRUNE((n$0 != 0), true); [line 64]\n " shape="invhouse"] + 35 -> 32 ; +34 [label="34: Prune (true branch) \n n$0=*&a:class RR2 * [line 68]\n PRUNE((n$0 != 0), true); [line 68]\n " shape="invhouse"] - 31 -> 33 ; -30 [label="30: between_join_and_exit \n " shape="box"] + 34 -> 36 ; +33 [label="33: between_join_and_exit \n " shape="box"] - 30 -> 28 ; -29 [label="29: + \n " ] + 33 -> 31 ; +32 [label="32: + \n " ] - 29 -> 30 ; -28 [label="28: Exit test7 \n " color=yellow style=filled] + 32 -> 33 ; +31 [label="31: Exit test7 \n " color=yellow style=filled] -27 [label="27: Start test7\nFormals: a:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 63]\n " color=yellow style=filled] +30 [label="30: Start test7\nFormals: a:class RR2 *\nLocals: \n DECLARE_LOCALS(&return); [line 67]\n " color=yellow style=filled] - 27 -> 31 ; - 27 -> 32 ; -26 [label="26: DeclStmt \n n$3=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 57]\n n$4=_fun_NSObject_init(n$3:class A *) virtual [line 57]\n *&a:class A *=n$4 [line 57]\n " shape="box"] + 30 -> 34 ; + 30 -> 35 ; +29 [label="29: DeclStmt \n n$3=_fun___objc_alloc_no_fail(sizeof(class RR2 ):unsigned long ) [line 61]\n n$4=_fun_RR2_init(n$3:class RR2 *) virtual [line 61]\n *&a:class RR2 *=n$4 [line 61]\n " shape="box"] - 26 -> 25 ; -25 [label="25: Message Call: retain \n n$1=*&a:class A * [line 58]\n n$2=_fun___objc_retain(n$1:class A *) [line 58]\n " shape="box"] + 29 -> 28 ; +28 [label="28: Message Call: retain \n n$1=*&a:class RR2 * [line 62]\n n$2=_fun___objc_retain(n$1:class RR2 *) [line 62]\n " shape="box"] - 25 -> 24 ; -24 [label="24: Message Call: release \n n$0=*&a:class A * [line 59]\n _fun___objc_release(n$0:class A *) [line 59]\n " shape="box"] + 28 -> 27 ; +27 [label="27: Message Call: release \n n$0=*&a:class RR2 * [line 63]\n _fun___objc_release(n$0:class RR2 *) [line 63]\n " shape="box"] + + + 27 -> 26 ; +26 [label="26: Exit test6 \n " color=yellow style=filled] + + +25 [label="25: Start test6\nFormals: \nLocals: a:class RR2 * \n DECLARE_LOCALS(&return,&a); [line 60]\n " color=yellow style=filled] + + + 25 -> 29 ; +24 [label="24: DeclStmt \n n$1=_fun___objc_alloc_no_fail(sizeof(class RR2 ):unsigned long ) [line 55]\n n$2=_fun_RR2_init(n$1:class RR2 *) virtual [line 55]\n *&a:class RR2 *=n$2 [line 55]\n " shape="box"] 24 -> 23 ; -23 [label="23: Exit test6 \n " color=yellow style=filled] +23 [label="23: Message Call: release \n n$0=*&a:class RR2 * [line 56]\n _fun___objc_release(n$0:class RR2 *) [line 56]\n " shape="box"] -22 [label="22: Start test6\nFormals: \nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 56]\n " color=yellow style=filled] + 23 -> 22 ; +22 [label="22: Exit test5 \n " color=yellow style=filled] - 22 -> 26 ; -21 [label="21: DeclStmt \n n$1=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 51]\n n$2=_fun_NSObject_init(n$1:class A *) virtual [line 51]\n *&a:class A *=n$2 [line 51]\n " shape="box"] +21 [label="21: Start test5\nFormals: \nLocals: a:class RR2 * \n DECLARE_LOCALS(&return,&a); [line 54]\n " color=yellow style=filled] - 21 -> 20 ; -20 [label="20: Message Call: release \n n$0=*&a:class A * [line 52]\n _fun___objc_release(n$0:class A *) [line 52]\n " shape="box"] + 21 -> 24 ; +20 [label="20: DeclStmt \n n$1=_fun_retain_release2_test() [line 49]\n *&b:class RR2 *=n$1 [line 49]\n " shape="box"] 20 -> 19 ; -19 [label="19: Exit test5 \n " color=yellow style=filled] +19 [label="19: Message Call: release \n n$0=*&b:class RR2 * [line 50]\n _fun___objc_release(n$0:class RR2 *) [line 50]\n " shape="box"] -18 [label="18: Start test5\nFormals: \nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 50]\n " color=yellow style=filled] + 19 -> 18 ; +18 [label="18: Exit test4 \n " color=yellow style=filled] - 18 -> 21 ; -17 [label="17: DeclStmt \n n$1=_fun_test() [line 45]\n *&b:class A *=n$1 [line 45]\n " shape="box"] +17 [label="17: Start test4\nFormals: \nLocals: b:class RR2 * \n DECLARE_LOCALS(&return,&b); [line 47]\n " color=yellow style=filled] - 17 -> 16 ; -16 [label="16: Message Call: release \n n$0=*&b:class A * [line 46]\n _fun___objc_release(n$0:class A *) [line 46]\n " shape="box"] + 17 -> 20 ; +16 [label="16: DeclStmt \n n$0=_fun_retain_release2_test() [line 44]\n *&b:class RR2 *=n$0 [line 44]\n " shape="box"] 16 -> 15 ; -15 [label="15: Exit test4 \n " color=yellow style=filled] +15 [label="15: Exit test3 \n " color=yellow style=filled] -14 [label="14: Start test4\nFormals: \nLocals: b:class A * \n DECLARE_LOCALS(&return,&b); [line 43]\n " color=yellow style=filled] +14 [label="14: Start test3\nFormals: \nLocals: b:class RR2 * \n DECLARE_LOCALS(&return,&b); [line 44]\n " color=yellow style=filled] - 14 -> 17 ; -13 [label="13: DeclStmt \n n$0=_fun_test() [line 40]\n *&b:class A *=n$0 [line 40]\n " shape="box"] + 14 -> 16 ; +13 [label="13: DeclStmt \n n$1=_fun_retain_release2_test() [line 39]\n *&b:class RR2 *=n$1 [line 39]\n " shape="box"] 13 -> 12 ; -12 [label="12: Exit test3 \n " color=yellow style=filled] +12 [label="12: BinaryOperatorStmt: Assign \n n$0=*&b:class RR2 * [line 40]\n *&#GB$g:class RR2 *=n$0 [line 40]\n " shape="box"] -11 [label="11: Start test3\nFormals: \nLocals: b:class A * \n DECLARE_LOCALS(&return,&b); [line 40]\n " color=yellow style=filled] + 12 -> 11 ; +11 [label="11: Exit retain_release2_test2 \n " color=yellow style=filled] - 11 -> 13 ; -10 [label="10: DeclStmt \n n$1=_fun_test() [line 35]\n *&b:class A *=n$1 [line 35]\n " shape="box"] +10 [label="10: Start retain_release2_test2\nFormals: \nLocals: b:class RR2 * \n DECLARE_LOCALS(&return,&b); [line 37]\n " color=yellow style=filled] - 10 -> 9 ; -9 [label="9: BinaryOperatorStmt: Assign \n n$0=*&b:class A * [line 36]\n *&#GB$g:class A *=n$0 [line 36]\n " shape="box"] + 10 -> 13 ; +9 [label="9: DeclStmt \n n$4=_fun___objc_alloc_no_fail(sizeof(class RR2 ):unsigned long ) [line 29]\n n$5=_fun_RR2_init(n$4:class RR2 *) virtual [line 29]\n *&a:class RR2 *=n$5 [line 29]\n " shape="box"] 9 -> 8 ; -8 [label="8: Exit test2 \n " color=yellow style=filled] +8 [label="8: Message Call: retain \n n$2=*&a:class RR2 * [line 30]\n n$3=_fun___objc_retain(n$2:class RR2 *) [line 30]\n " shape="box"] -7 [label="7: Start test2\nFormals: \nLocals: b:class A * \n DECLARE_LOCALS(&return,&b); [line 33]\n " color=yellow style=filled] + 8 -> 7 ; +7 [label="7: Message Call: release \n n$1=*&a:class RR2 * [line 31]\n _fun___objc_release(n$1:class RR2 *) [line 31]\n " shape="box"] - 7 -> 10 ; -6 [label="6: DeclStmt \n n$4=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 25]\n n$5=_fun_NSObject_init(n$4:class A *) virtual [line 25]\n *&a:class A *=n$5 [line 25]\n " shape="box"] + 7 -> 6 ; +6 [label="6: Return Stmt \n n$0=*&a:class RR2 * [line 33]\n *&return:class RR2 *=n$0 [line 33]\n " shape="box"] 6 -> 5 ; -5 [label="5: Message Call: retain \n n$2=*&a:class A * [line 26]\n n$3=_fun___objc_retain(n$2:class A *) [line 26]\n " shape="box"] +5 [label="5: Exit retain_release2_test \n " color=yellow style=filled] - 5 -> 4 ; -4 [label="4: Message Call: release \n n$1=*&a:class A * [line 27]\n _fun___objc_release(n$1:class A *) [line 27]\n " shape="box"] +4 [label="4: Start retain_release2_test\nFormals: \nLocals: a:class RR2 * \n DECLARE_LOCALS(&return,&a); [line 28]\n " color=yellow style=filled] - 4 -> 3 ; -3 [label="3: Return Stmt \n n$0=*&a:class A * [line 29]\n *&return:class A *=n$0 [line 29]\n " shape="box"] + 4 -> 9 ; +3 [label="3: Return Stmt \n n$0=*&self:class RR2 * [line 19]\n *&return:struct objc_object *=n$0 [line 19]\n " shape="box"] 3 -> 2 ; -2 [label="2: Exit test \n " color=yellow style=filled] +2 [label="2: Exit RR2_init \n " color=yellow style=filled] -1 [label="1: Start test\nFormals: \nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 24]\n " color=yellow style=filled] +1 [label="1: Start RR2_init\nFormals: self:class RR2 *\nLocals: \n DECLARE_LOCALS(&return); [line 18]\n " color=yellow style=filled] - 1 -> 6 ; + 1 -> 3 ; } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.m index 690f07341..5fb883a3e 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.m @@ -9,20 +9,24 @@ #import -@interface A : NSObject +@interface RR2 : NSObject @end -@implementation A +@implementation RR2 + +- init { + return self; +} @end -void __objc_release(A*); // infer builtin -A* g; +void __objc_release(RR2*); // infer builtin +RR2* g; // no leak -A* test() { - A* a = [[A alloc] init]; +RR2* retain_release2_test() { + RR2* a = [[RR2 alloc] init]; [a retain]; [a release]; @@ -30,37 +34,37 @@ A* test() { } // no leak -void test2() { +void retain_release2_test2() { - A* b = test(); + RR2* b = retain_release2_test(); g = b; } // leak -void test3() { A* b = test(); } +void test3() { RR2* b = retain_release2_test(); } // no leak void test4() { - A* b = test(); + RR2* b = retain_release2_test(); [b release]; } // No leak void test5() { - A* a = [[A alloc] init]; + RR2* a = [[RR2 alloc] init]; [a release]; } // leak void test6() { - A* a = [[A alloc] init]; + RR2* a = [[RR2 alloc] init]; [a retain]; [a release]; } // Creates specs -void test7(A* a) { +void test7(RR2* a) { if (a) __objc_release(a); } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExampleBucketing.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExampleBucketing.m index ef696b79e..878135348 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExampleBucketing.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExampleBucketing.m @@ -9,13 +9,17 @@ #import -@interface A : NSObject +@interface RRB : NSObject @end -@implementation A +@implementation RRB + +- init { + return self; +} @end // no leak in bucketing cf mode -void test() { A* a = [[A alloc] init]; } +void RetainReleaseTest() { RRB* a = [[RRB alloc] init]; } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExampleBucketingArc.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExampleBucketingArc.m new file mode 100644 index 000000000..cb2d3dd3c --- /dev/null +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExampleBucketingArc.m @@ -0,0 +1,25 @@ +/* + * 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 + +@interface RRBA : NSObject + +@end + +@implementation RRBA + +- init { + return self; +} + +@end + +// no leak in bucketing cf mode +void RetainReleaseArcTest() { RRBA* a = [[RRBA alloc] init]; } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/arc_methods.dot b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/arc_methods.dot index 2e80c8c20..8ddf758c4 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/arc_methods.dot +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/arc_methods.dot @@ -1,18 +1,18 @@ /* @generated */ digraph iCFG { -15 [label="15: DeclStmt \n n$3=_fun_A_newA() [line 42]\n *&a1:class A *=n$3 [line 42]\n " shape="box"] +15 [label="15: DeclStmt \n n$3=_fun_ArcMethodsA_newA() [line 42]\n *&a1:class ArcMethodsA *=n$3 [line 42]\n " shape="box"] 15 -> 14 ; -14 [label="14: DeclStmt \n n$2=*&a1:class A * [line 43]\n _fun___objc_retain(n$2:class A *) [line 43]\n *&aa:class A *=n$2 [line 43]\n " shape="box"] +14 [label="14: DeclStmt \n n$2=*&a1:class ArcMethodsA * [line 43]\n _fun___objc_retain(n$2:class ArcMethodsA *) [line 43]\n *&aa:class ArcMethodsA *=n$2 [line 43]\n " shape="box"] 14 -> 13 ; -13 [label="13: DeclStmt \n n$1=_fun_A_someA() [line 44]\n _fun___objc_retain(n$1:class A *) [line 44]\n *&a2:class A *=n$1 [line 44]\n " shape="box"] +13 [label="13: DeclStmt \n n$1=_fun_ArcMethodsA_someA() [line 44]\n _fun___objc_retain(n$1:class ArcMethodsA *) [line 44]\n *&a2:class ArcMethodsA *=n$1 [line 44]\n " shape="box"] 13 -> 12 ; -12 [label="12: DeclStmt \n n$0=*&a2:class A * [line 45]\n _fun___objc_retain(n$0:class A *) [line 45]\n *&ab:class A *=n$0 [line 45]\n " shape="box"] +12 [label="12: DeclStmt \n n$0=*&a2:class ArcMethodsA * [line 45]\n _fun___objc_retain(n$0:class ArcMethodsA *) [line 45]\n *&ab:class ArcMethodsA *=n$0 [line 45]\n " shape="box"] 12 -> 11 ; @@ -20,40 +20,40 @@ digraph iCFG { 11 -> 10 ; -10 [label="10: Exit main \n " color=yellow style=filled] +10 [label="10: Exit main_arc_methods \n " color=yellow style=filled] -9 [label="9: Start main\nFormals: \nLocals: ab:class A * a2:class A * aa:class A * a1:class A * \n DECLARE_LOCALS(&return,&ab,&a2,&aa,&a1); [line 35]\n " color=yellow style=filled] +9 [label="9: Start main_arc_methods\nFormals: \nLocals: ab:class ArcMethodsA * a2:class ArcMethodsA * aa:class ArcMethodsA * a1:class ArcMethodsA * \n DECLARE_LOCALS(&return,&ab,&a2,&aa,&a1); [line 35]\n " color=yellow style=filled] 9 -> 15 ; -8 [label="8: DeclStmt \n n$5=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 28]\n n$6=_fun_NSObject_init(n$5:class A *) virtual [line 28]\n *&a:class A *=n$6 [line 28]\n " shape="box"] +8 [label="8: DeclStmt \n n$5=_fun___objc_alloc_no_fail(sizeof(class ArcMethodsA ):unsigned long ) [line 28]\n n$6=_fun_NSObject_init(n$5:class ArcMethodsA *) virtual [line 28]\n *&a:class ArcMethodsA *=n$6 [line 28]\n " shape="box"] 8 -> 7 ; -7 [label="7: Return Stmt \n n$3=*&a:class A * [line 30]\n *&return:class A *=n$3 [line 30]\n n$4=_fun___set_autorelease_attribute(n$3:class A *) [line 30]\n " shape="box"] +7 [label="7: Return Stmt \n n$3=*&a:class ArcMethodsA * [line 30]\n *&return:class ArcMethodsA *=n$3 [line 30]\n n$4=_fun___set_autorelease_attribute(n$3:class ArcMethodsA *) [line 30]\n " shape="box"] 7 -> 6 ; -6 [label="6: Exit A_someA \n " color=yellow style=filled] +6 [label="6: Exit ArcMethodsA_someA \n " color=yellow style=filled] -5 [label="5: Start A_someA\nFormals: \nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 27]\n " color=yellow style=filled] +5 [label="5: Start ArcMethodsA_someA\nFormals: \nLocals: a:class ArcMethodsA * \n DECLARE_LOCALS(&return,&a); [line 27]\n " color=yellow style=filled] 5 -> 8 ; -4 [label="4: DeclStmt \n n$1=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 23]\n n$2=_fun_NSObject_init(n$1:class A *) virtual [line 23]\n *&a:class A *=n$2 [line 23]\n " shape="box"] +4 [label="4: DeclStmt \n n$1=_fun___objc_alloc_no_fail(sizeof(class ArcMethodsA ):unsigned long ) [line 23]\n n$2=_fun_NSObject_init(n$1:class ArcMethodsA *) virtual [line 23]\n *&a:class ArcMethodsA *=n$2 [line 23]\n " shape="box"] 4 -> 3 ; -3 [label="3: Return Stmt \n n$0=*&a:class A * [line 24]\n *&return:class A *=n$0 [line 24]\n " shape="box"] +3 [label="3: Return Stmt \n n$0=*&a:class ArcMethodsA * [line 24]\n *&return:class ArcMethodsA *=n$0 [line 24]\n " shape="box"] 3 -> 2 ; -2 [label="2: Exit A_newA \n " color=yellow style=filled] +2 [label="2: Exit ArcMethodsA_newA \n " color=yellow style=filled] -1 [label="1: Start A_newA\nFormals: \nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 22]\n " color=yellow style=filled] +1 [label="1: Start ArcMethodsA_newA\nFormals: \nLocals: a:class ArcMethodsA * \n DECLARE_LOCALS(&return,&a); [line 22]\n " color=yellow style=filled] 1 -> 4 ; diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/arc_methods.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/arc_methods.m index 98415d2bf..d1a0d79b2 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/arc_methods.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/arc_methods.m @@ -9,39 +9,39 @@ #import -@interface A : NSObject +@interface ArcMethodsA : NSObject -+ (A*)newA; ++ (ArcMethodsA*)newA; -+ (A*)someA; ++ (ArcMethodsA*)someA; @end -@implementation A +@implementation ArcMethodsA -+ (A*)newA { - A* a = [[A alloc] init]; ++ (ArcMethodsA*)newA { + ArcMethodsA* a = [[ArcMethodsA alloc] init]; return a; } -+ (A*)someA { - A* a = [[A alloc] init]; ++ (ArcMethodsA*)someA { + ArcMethodsA* a = [[ArcMethodsA alloc] init]; return a; } @end -int main() { +int main_arc_methods() { // A * __weak aWeakRef =0; // A * __strong a1 =0; // A * __unsafe_unretained anUnsafeUnretRef =0; // A * __autoreleasing anAutoRelRef =0; - A* a1 = [A newA]; - A* aa = a1; - A* a2 = [A someA]; - A* ab = a2; + ArcMethodsA* a1 = [ArcMethodsA newA]; + ArcMethodsA* aa = a1; + ArcMethodsA* a2 = [ArcMethodsA someA]; + ArcMethodsA* ab = a2; return 0; } diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle2.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle2.m index 4aaec373d..a50c7b678 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle2.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle2.m @@ -23,6 +23,10 @@ Child* child; } +- init { + return self; +} + - (void)setChild:(Child*)c { self->child = c; @@ -40,6 +44,10 @@ ChildW* child; } +- init { + return self; +} + - (void)setChild:(ChildW*)c { self->child = c; @@ -57,6 +65,10 @@ ChildUU* child; } +- init { + return self; +} + - (void)setChild:(ChildUU*)c { self->child = c; @@ -74,6 +86,10 @@ Parent* parent; } +- init { + return self; +} + - (void)setParent:(Parent*)p { self->parent = p; } @@ -90,6 +106,10 @@ ParentW __weak* parent; } +- init { + return self; +} + - (void)setParent:(ParentW*)p { self->parent = p; } @@ -106,27 +126,31 @@ ParentUU __unsafe_unretained* parent; } +- init { + return self; +} + - (void)setParent:(ParentUU*)p { self->parent = p; } @end -void strongcycle() { +void strongcycle2() { Parent* parent = [[Parent alloc] init]; Child* child = [[Child alloc] init]; [parent setChild:child]; [child setParent:parent]; } -void weakcycle() { +void weakcycle2() { ParentW* parent = [[ParentW alloc] init]; ChildW* child = [[ChildW alloc] init]; [parent setChild:child]; [child setParent:parent]; } -void unsafeunretainedcycle() { +void unsafeunretainedcycle2() { ParentUU* parent = [[ParentUU alloc] init]; ChildUU* child = [[ChildUU alloc] init]; [parent setChild:child]; diff --git a/infer/tests/codetoanalyze/objc/errors/npe/BoxedNumberExample.m b/infer/tests/codetoanalyze/objc/errors/npe/BoxedNumberExample.m index fc636cd3e..303e21ba2 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/BoxedNumberExample.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/BoxedNumberExample.m @@ -16,11 +16,11 @@ typedef NS_ENUM(NSUInteger, SpacingEnum) { SpacingTrailing, }; -@interface A : NSObject +@interface BoxedA : NSObject @end -@implementation A { +@implementation BoxedA { NSMutableDictionary* _spacingMap; } diff --git a/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.dot b/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.dot index 7e05d34ff..20c5f3988 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.dot +++ b/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.dot @@ -4,48 +4,48 @@ digraph iCFG { 13 -> 12 ; -12 [label="12: Call n$0 \n n$0=*&callback:_fn_ (*) [line 46]\n n$0(0:class NSError *,0:struct objc_object *) [line 46]\n " shape="box"] +12 [label="12: Call n$0 \n n$0=*&callback:_fn_ (*) [line 47]\n n$0(0:class NSError *,0:struct objc_object *) [line 47]\n " shape="box"] 12 -> 11 ; -11 [label="11: Exit test \n " color=yellow style=filled] +11 [label="11: Exit NonnullAtrributeTest \n " color=yellow style=filled] -10 [label="10: Start test\nFormals: callback:_fn_ (*)\nLocals: \n DECLARE_LOCALS(&return); [line 46]\n " color=yellow style=filled] +10 [label="10: Start NonnullAtrributeTest\nFormals: callback:_fn_ (*)\nLocals: \n DECLARE_LOCALS(&return); [line 46]\n " color=yellow style=filled] 10 -> 13 ; -9 [label="9: Call _fun___infer_assume \n n$5=*&a:class A * [line 38]\n n$6=_fun___infer_assume((n$5 != 0):class A *) [line 38]\n " shape="box"] +9 [label="9: Call _fun___infer_assume \n n$5=*&a:class NonnullA * [line 38]\n n$6=_fun___infer_assume((n$5 != 0):class NonnullA *) [line 38]\n " shape="box"] 9 -> 8 ; -8 [label="8: DeclStmt \n n$3=*&a:class A * [line 39]\n n$4=_fun_A_getA(n$3:class A *) virtual [line 39]\n _fun___objc_retain(n$4:class A *) [line 39]\n *&a1:class A *=n$4 [line 39]\n " shape="box"] +8 [label="8: DeclStmt \n n$3=*&a:class NonnullA * [line 39]\n n$4=_fun_NonnullA_getA(n$3:class NonnullA *) virtual [line 39]\n _fun___objc_retain(n$4:class NonnullA *) [line 39]\n *&a1:class NonnullA *=n$4 [line 39]\n " shape="box"] 8 -> 7 ; -7 [label="7: DeclStmt \n n$1=*&a1:class A * [line 40]\n n$2=*n$1.x:int [line 40]\n *&y:int =n$2 [line 40]\n " shape="box"] +7 [label="7: DeclStmt \n n$1=*&a1:class NonnullA * [line 40]\n n$2=*n$1.x:int [line 40]\n *&y:int =n$2 [line 40]\n " shape="box"] 7 -> 6 ; -6 [label="6: Return Stmt \n n$0=*&self:class C * [line 41]\n *&return:struct objc_object *=n$0 [line 41]\n " shape="box"] +6 [label="6: Return Stmt \n n$0=*&self:class NonnullC * [line 41]\n *&return:struct objc_object *=n$0 [line 41]\n " shape="box"] 6 -> 5 ; -5 [label="5: Exit C_initWithCoder:and: \n " color=yellow style=filled] +5 [label="5: Exit NonnullC_initWithCoder:and: \n " color=yellow style=filled] -4 [label="4: Start C_initWithCoder:and:\nFormals: self:class C * aDecoder:class NSString * a:class A *\nLocals: y:int a1:class A * \n DECLARE_LOCALS(&return,&y,&a1); [line 38]\n " color=yellow style=filled] +4 [label="4: Start NonnullC_initWithCoder:and:\nFormals: self:class NonnullC * aDecoder:class NSString * a:class NonnullA *\nLocals: y:int a1:class NonnullA * \n DECLARE_LOCALS(&return,&y,&a1); [line 38]\n " color=yellow style=filled] 4 -> 9 ; -3 [label="3: Return Stmt \n n$0=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 26]\n n$1=_fun_NSObject_init(n$0:class A *) virtual [line 26]\n *&return:class A *=n$1 [line 26]\n n$2=_fun___set_autorelease_attribute(n$1:class A *) [line 26]\n " shape="box"] +3 [label="3: Return Stmt \n n$0=_fun___objc_alloc_no_fail(sizeof(class NonnullA ):unsigned long ) [line 26]\n n$1=_fun_NSObject_init(n$0:class NonnullA *) virtual [line 26]\n *&return:class NonnullA *=n$1 [line 26]\n n$2=_fun___set_autorelease_attribute(n$1:class NonnullA *) [line 26]\n " shape="box"] 3 -> 2 ; -2 [label="2: Exit A_getA \n " color=yellow style=filled] +2 [label="2: Exit NonnullA_getA \n " color=yellow style=filled] -1 [label="1: Start A_getA\nFormals: self:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 25]\n " color=yellow style=filled] +1 [label="1: Start NonnullA_getA\nFormals: self:class NonnullA *\nLocals: \n DECLARE_LOCALS(&return); [line 25]\n " color=yellow style=filled] 1 -> 3 ; diff --git a/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.m b/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.m index dc7ffc16c..aa15f6a5f 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.m @@ -11,36 +11,38 @@ void __infer_assume(int cond); -@interface A : NSObject { +@interface NonnullA : NSObject { @public int x; } -- (A*)getA; +- (NonnullA*)getA; @end -@implementation A +@implementation NonnullA -- (A*)getA { - return [A new]; +- (NonnullA*)getA { + return [NonnullA new]; } @end -@interface C : NSObject +@interface NonnullC : NSObject @property(copy, nonnull) NSString* name; @end -@implementation C +@implementation NonnullC -- (instancetype)initWithCoder:(NSString*)aDecoder and:(A* __nonnull)a { - A* a1 = [a getA]; +- (instancetype)initWithCoder:(NSString*)aDecoder and:(NonnullA* __nonnull)a { + NonnullA* a1 = [a getA]; int y = a1->x; return self; } @end -void test(void (^__nonnull callback)(NSError*, id)) { callback(NULL, NULL); } +void NonnullAtrributeTest(void (^__nonnull callback)(NSError*, id)) { + callback(NULL, NULL); +} diff --git a/infer/tests/codetoanalyze/objc/errors/npe/Npe_with_equal_names.m b/infer/tests/codetoanalyze/objc/errors/npe/Npe_with_equal_names.m index 1ee88b101..0de364edb 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/Npe_with_equal_names.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/Npe_with_equal_names.m @@ -9,36 +9,36 @@ #import -@interface A : NSObject { +@interface EqualNamesA : NSObject { @public int x; } -+ (A*)meth; ++ (EqualNamesA*)meth; -@property(nonatomic, readonly) A* meth; +@property(nonatomic, readonly) EqualNamesA* meth; @end -@implementation A +@implementation EqualNamesA -+ (A*)meth { - return [A new]; ++ (EqualNamesA*)meth { + return [EqualNamesA new]; } -- (A*)meth { +- (EqualNamesA*)meth { return nil; } @end -int test() { - A* para = [A new]; - A* a = [para meth]; +int EqualNamesTest() { + EqualNamesA* para = [EqualNamesA new]; + EqualNamesA* a = [para meth]; return a->x; } -int test2(A* para) { - A* a = [A meth]; +int EqualNamesTest2(EqualNamesA* para) { + EqualNamesA* a = [EqualNamesA meth]; return a->x; } diff --git a/infer/tests/codetoanalyze/objc/errors/npe/ObjCMethodCallInCondition.m b/infer/tests/codetoanalyze/objc/errors/npe/ObjCMethodCallInCondition.m index 5578d48d3..5bfe85cb2 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/ObjCMethodCallInCondition.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/ObjCMethodCallInCondition.m @@ -10,15 +10,15 @@ #import #import -@interface A : NSObject +@interface CallInConditionA : NSObject -@property(nonatomic) A* child; +@property(nonatomic) CallInConditionA* child; -@property(nonatomic) A* url; +@property(nonatomic) CallInConditionA* url; @end -@implementation A +@implementation CallInConditionA - (void)testLength:(NSData*)imageData { unsigned char* pixels = (unsigned char*)[imageData bytes]; @@ -28,9 +28,9 @@ } } -A* testUrl(A* context) { +CallInConditionA* testUrl(CallInConditionA* context) { if (context.url) { - A* entityMemObject = context.child; + CallInConditionA* entityMemObject = context.child; return entityMemObject->_child; } return nil; diff --git a/infer/tests/codetoanalyze/objc/errors/npe/WeakCapturedVarsNPE.m b/infer/tests/codetoanalyze/objc/errors/npe/WeakCapturedVarsNPE.m index 981714032..7b644d45b 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/WeakCapturedVarsNPE.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/WeakCapturedVarsNPE.m @@ -9,11 +9,11 @@ #include -@interface A : NSObject +@interface WeakCapturedA : NSObject @end -@implementation A { +@implementation WeakCapturedA { int x; } diff --git a/infer/tests/codetoanalyze/objc/errors/npe/block.m b/infer/tests/codetoanalyze/objc/errors/npe/block.m index e9c13d353..5f2d568ab 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/block.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/block.m @@ -9,10 +9,10 @@ #import -@interface A : NSObject +@interface BlockA : NSObject @end -@implementation A { +@implementation BlockA { void (^_block_field)(void); } diff --git a/infer/tests/codetoanalyze/objc/errors/npe/blockenum.m b/infer/tests/codetoanalyze/objc/errors/npe/blockenum.m index 244bafdf3..96960bcff 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/blockenum.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/blockenum.m @@ -9,29 +9,29 @@ #import -@interface B : NSObject +@interface BlockEnumB : NSObject + foo:(id)obj; @end -@implementation B +@implementation BlockEnumB -+ (B*)foo:(id)obj { ++ (BlockEnumB*)foo:(id)obj { return obj; } @end -@interface A : NSObject +@interface BlockEnumA : NSObject - (NSMutableArray*)allResultsList:(NSArray*)allResults; @end -@implementation A +@implementation BlockEnumA // From a diff - (NSMutableArray*)allResultsList:(NSArray*)allResults { NSMutableArray* resultsList = [[NSMutableArray alloc] init]; [allResults enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL* stop) { - id* result = [B foo:obj]; + id* result = [BlockEnumB foo:obj]; if (result != nil) { [resultsList addObject:result]; } @@ -45,7 +45,7 @@ NSMutableArray* resultsList = [[NSMutableArray alloc] init]; void (^enumerateObjectsUsingBlock)(id, NSUInteger, BOOL*) = ^(id obj, NSUInteger idx, BOOL* stop) { - id* result = [B foo:obj]; + id* result = [BlockEnumB foo:obj]; if (result != nil) { [resultsList addObject:result]; } diff --git a/infer/tests/codetoanalyze/objc/errors/npe/nil_in_array_literal.m b/infer/tests/codetoanalyze/objc/errors/npe/nil_in_array_literal.m index d8422fcea..9c64a0db3 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/nil_in_array_literal.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/nil_in_array_literal.m @@ -9,11 +9,11 @@ #import -@interface A : NSObject { +@interface Arr : NSObject { } @end -@implementation A +@implementation Arr - (void)noProblem { NSArray* foo = @[ @"aaa", @"bbb" ]; @@ -64,8 +64,8 @@ @end -int main() { - A* a = [A alloc]; +int ArrMain() { + Arr* a = [Arr alloc]; [a noProblem]; [a nilInArrayLiteral0]; [a nilInArrayWithObject]; diff --git a/infer/tests/codetoanalyze/objc/errors/npe/nil_in_dictionary_literal.m b/infer/tests/codetoanalyze/objc/errors/npe/nil_in_dictionary_literal.m index 51b4a6f5c..7d64ea1ec 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/nil_in_dictionary_literal.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/nil_in_dictionary_literal.m @@ -9,11 +9,11 @@ #import -@interface A : NSObject { +@interface ADict : NSObject { } @end -@implementation A +@implementation ADict - (void)noProblem { NSDictionary* foo = @{ @"aaa" : @"a value", @"bbb" : @"b value" }; @@ -95,8 +95,8 @@ @end -int main() { - A* a = [A alloc]; +int DictMain() { + ADict* a = [ADict alloc]; [a noProblem]; [a nilInDictionaryLiteralKey0]; return 0; diff --git a/infer/tests/codetoanalyze/objc/errors/npe/nil_param.m b/infer/tests/codetoanalyze/objc/errors/npe/nil_param.m index a27b67356..389d6f289 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/nil_param.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/nil_param.m @@ -9,27 +9,27 @@ #import -@interface A : NSObject { +@interface NilParamA : NSObject { int x; } @end -@implementation A +@implementation NilParamA - (void)test2 { self->x = 1; } -- (void)test1:(A*)other { +- (void)test1:(NilParamA*)other { [other test2]; } @end -int main() { +int NilParamMain() { - A* a = [A alloc]; + NilParamA* a = [NilParamA alloc]; [a test1:nil]; [a release]; return 0; diff --git a/infer/tests/codetoanalyze/objc/errors/npe/npe_conditional.m b/infer/tests/codetoanalyze/objc/errors/npe/npe_conditional.m index a7f6dc8fc..c2d6d49bc 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/npe_conditional.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/npe_conditional.m @@ -9,7 +9,7 @@ #import -@interface A : NSObject { +@interface ConditionalA : NSObject { int x; } @@ -17,13 +17,13 @@ @end -@implementation A +@implementation ConditionalA - (NSString*)name { return @"1"; } -void binaryConditionalNoNPE(A* transfer) { +void binaryConditionalNoNPE(ConditionalA* transfer) { NSString* val = transfer.name ?: @"0"; NSMutableDictionary* extraBlock = [[NSMutableDictionary alloc] initWithDictionary:@{ @@ -31,7 +31,7 @@ void binaryConditionalNoNPE(A* transfer) { }]; } -void conditionalNPE(A* transfer) { +void conditionalNPE(ConditionalA* transfer) { NSString* val = transfer.name ? transfer.name : @"0"; NSMutableDictionary* extraBlock = [[NSMutableDictionary alloc] initWithDictionary:@{ diff --git a/infer/tests/codetoanalyze/objc/errors/npe/npe_malloc.dot b/infer/tests/codetoanalyze/objc/errors/npe/npe_malloc.dot index 23e673c86..f9144420b 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/npe_malloc.dot +++ b/infer/tests/codetoanalyze/objc/errors/npe/npe_malloc.dot @@ -12,10 +12,10 @@ digraph iCFG { 3 -> 2 ; -2 [label="2: Exit C_test \n " color=yellow style=filled] +2 [label="2: Exit NpeMallocC_test \n " color=yellow style=filled] -1 [label="1: Start C_test\nFormals: self:class C *\nLocals: person:struct Person * \n DECLARE_LOCALS(&return,&person); [line 24]\n " color=yellow style=filled] +1 [label="1: Start NpeMallocC_test\nFormals: self:class NpeMallocC *\nLocals: person:struct Person * \n DECLARE_LOCALS(&return,&person); [line 24]\n " color=yellow style=filled] 1 -> 5 ; diff --git a/infer/tests/codetoanalyze/objc/errors/npe/npe_malloc.m b/infer/tests/codetoanalyze/objc/errors/npe/npe_malloc.m index e8aba7a4e..d8f0692d2 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/npe_malloc.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/npe_malloc.m @@ -15,11 +15,11 @@ struct Person { int y; }; -@interface C : NSObject +@interface NpeMallocC : NSObject @end -@implementation C +@implementation NpeMallocC - (struct Person*)test { struct Person* person = (struct Person*)malloc(sizeof(struct Person)); diff --git a/infer/tests/codetoanalyze/objc/errors/npe/npe_self.m b/infer/tests/codetoanalyze/objc/errors/npe/npe_self.m index 17368809e..ed201b0aa 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/npe_self.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/npe_self.m @@ -10,15 +10,15 @@ #import #import -@interface C : NSObject { +@interface CSelf : NSObject { int x; - C* _currentCompositionState; + CSelf* _currentCompositionState; } @property(nonatomic, copy, readonly) NSString* JSON; @end -@implementation C +@implementation CSelf - (id)init { self = [super init]; @@ -27,8 +27,8 @@ } - (void)captureManagerSessionDidStart { - __weak C* weakSelf = self; - C* strongSelf = weakSelf; + __weak CSelf* weakSelf = self; + CSelf* strongSelf = weakSelf; int x = strongSelf->x; } @@ -43,7 +43,7 @@ return YES; if (![object isKindOfClass:[self class]]) return NO; - C* other = (C*)object; + CSelf* other = (CSelf*)object; return ([_JSON isEqualToString:other->_JSON]); } diff --git a/infer/tests/codetoanalyze/objc/errors/npe/null_returned_by_method.m b/infer/tests/codetoanalyze/objc/errors/npe/null_returned_by_method.m index f2ecb5a91..55c74608e 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/null_returned_by_method.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/null_returned_by_method.m @@ -9,15 +9,15 @@ #import -@interface A : NSObject +@interface NullReturnedByMethodA : NSObject @end -@implementation A { +@implementation NullReturnedByMethodA { int x; } -- (A*)test { +- (NullReturnedByMethodA*)test { return nil; } diff --git a/infer/tests/codetoanalyze/objc/errors/npe/nullable.m b/infer/tests/codetoanalyze/objc/errors/npe/nullable.m index 129bb66ec..060fdd005 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/nullable.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/nullable.m @@ -9,14 +9,14 @@ #import -@interface A : NSObject { +@interface NullableA : NSObject { @public int fld; } @end -@interface B : NSObject +@interface NullableB : NSObject @property int prop; @@ -24,27 +24,27 @@ @end -int derefNullableParamDirect(A* __nullable param) { return param->fld; } +int derefNullableParamDirect(NullableA* __nullable param) { return param->fld; } -int derefNullableParamIndirect(A* __nullable param) { - A* local = param; +int derefNullableParamIndirect(NullableA* __nullable param) { + NullableA* local = param; return local->fld; } -A* derefNullableParamOk(A* __nullable param) { +NullableA* derefNullableParamOk(NullableA* __nullable param) { if (!param) - param = [A new]; + param = [NullableA new]; param->fld = 7; return param; } int parameter_nullable_ok(NSString* body, - __nullable NSString* linkTapAction, - A* options) { + NSString* __nullable linkTapAction, + NullableA* options) { return options->fld; } -int parameter_nullable_bug(__nullable A* options, +int parameter_nullable_bug(NullableA* __nullable options, NSAttributedString* body, NSString* linkTapAction) @@ -52,8 +52,14 @@ int parameter_nullable_bug(__nullable A* options, return options->fld; } -int readNullableParamPropertyOk(B* __nullable param) { return param.prop; } +int readNullableParamPropertyOk(NullableB* __nullable param) { + return param.prop; +} -void writeNullableParamPropertyOk(B* __nullable param) { param.prop = 7; } +void writeNullableParamPropertyOk(NullableB* __nullable param) { + param.prop = 7; +} -void methodCallOnNullableParamOk(B* __nullable param) { [param method]; } +void methodCallOnNullableParamOk(NullableB* __nullable param) { + [param method]; +} diff --git a/infer/tests/codetoanalyze/objc/errors/npe/skip_method_with_nil_object.m b/infer/tests/codetoanalyze/objc/errors/npe/skip_method_with_nil_object.m index c509d564d..708f21f07 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/skip_method_with_nil_object.m +++ b/infer/tests/codetoanalyze/objc/errors/npe/skip_method_with_nil_object.m @@ -9,24 +9,24 @@ #import -@interface A : NSObject { +@interface SkipMethodNilA : NSObject { int x; } -- (A*)get_a; +- (SkipMethodNilA*)get_a; - (NSString*)skip_method; @end -@implementation A +@implementation SkipMethodNilA -- (A*)get_a { - return [A new]; +- (SkipMethodNilA*)get_a { + return [SkipMethodNilA new]; } -- (int)testOk:(A*)person { - A* personID = [person get_a]; +- (int)testOk:(SkipMethodNilA*)person { + SkipMethodNilA* personID = [person get_a]; NSString* lastRecord = [personID skip_method]; if (lastRecord) { personID->x = 6; @@ -36,8 +36,8 @@ } } -- (int)testBug:(A*)person { - A* personID = [person get_a]; +- (int)testBug:(SkipMethodNilA*)person { + SkipMethodNilA* personID = [person get_a]; NSString* lastRecord = [personID skip_method]; if (lastRecord) { return 0; diff --git a/infer/tests/codetoanalyze/objc/errors/procdescs/main.c b/infer/tests/codetoanalyze/objc/errors/procdescs/main.c index 49cf56262..7d5b091d8 100644 --- a/infer/tests/codetoanalyze/objc/errors/procdescs/main.c +++ b/infer/tests/codetoanalyze/objc/errors/procdescs/main.c @@ -10,7 +10,7 @@ #include "MethodCall.h" #include -int main() { +int ProcdescMain() { MethodCall* call = [MethodCall alloc]; int n = [call plusX:1 andY:3]; int* x = malloc(sizeof(int)); diff --git a/infer/tests/codetoanalyze/objc/errors/property/ExplicitIvarName.m b/infer/tests/codetoanalyze/objc/errors/property/ExplicitIvarName.m index 6487969c7..2a4d52139 100644 --- a/infer/tests/codetoanalyze/objc/errors/property/ExplicitIvarName.m +++ b/infer/tests/codetoanalyze/objc/errors/property/ExplicitIvarName.m @@ -9,23 +9,27 @@ #import -@interface A : NSObject +@interface ExplicitIvarNameA : NSObject @property(nonatomic) int x; @end -@interface B : NSObject +@interface ExplicitIvarNameB : NSObject @property(nonatomic) int y; @end -@implementation A +@implementation ExplicitIvarNameA + +- init { + return self; +} @synthesize x; -- (int)test { +- (int)testExplicit { int* p = 0; self->x = 5; if (self.x == 5) { // If NPE is found, means that getter is using the correct @@ -37,7 +41,7 @@ - (int)testDefaultName { int* p = 0; - B* b = [[B alloc] init]; + ExplicitIvarNameB* b = [[ExplicitIvarNameB alloc] init]; b.y = 5; if (b.y == 5) { // If NPE is found, means that getter is using default name _y // that is diff --git a/infer/tests/codetoanalyze/objc/errors/property/main.c b/infer/tests/codetoanalyze/objc/errors/property/main.c index a9fee8d58..ed3588d36 100644 --- a/infer/tests/codetoanalyze/objc/errors/property/main.c +++ b/infer/tests/codetoanalyze/objc/errors/property/main.c @@ -10,7 +10,7 @@ #include "IvarExample.h" #include -int main() { +int property_main() { IvarExample* i = [IvarExample alloc]; int a = i.aProperty; int* x = malloc(sizeof(int)); diff --git a/infer/tests/codetoanalyze/objc/errors/protocol_procdesc/main.c b/infer/tests/codetoanalyze/objc/errors/protocol_procdesc/main.c index 1197a67ed..a32b46255 100644 --- a/infer/tests/codetoanalyze/objc/errors/protocol_procdesc/main.c +++ b/infer/tests/codetoanalyze/objc/errors/protocol_procdesc/main.c @@ -9,7 +9,7 @@ #include "Bicycle.h" -int main() { +int ProtocolProcdescMain() { Bicycle* bike = [Bicycle alloc]; diff --git a/infer/tests/codetoanalyze/objc/errors/protocol_procdesc/main.dot b/infer/tests/codetoanalyze/objc/errors/protocol_procdesc/main.dot index d19336ca1..546d8e734 100644 --- a/infer/tests/codetoanalyze/objc/errors/protocol_procdesc/main.dot +++ b/infer/tests/codetoanalyze/objc/errors/protocol_procdesc/main.dot @@ -12,10 +12,10 @@ digraph iCFG { 3 -> 2 ; -2 [label="2: Exit main \n " color=yellow style=filled] +2 [label="2: Exit ProtocolProcdescMain \n " color=yellow style=filled] -1 [label="1: Start main\nFormals: \nLocals: bike:class Bicycle * \n DECLARE_LOCALS(&return,&bike); [line 12]\n " color=yellow style=filled] +1 [label="1: Start ProtocolProcdescMain\nFormals: \nLocals: bike:class Bicycle * \n DECLARE_LOCALS(&return,&bike); [line 12]\n " color=yellow style=filled] 1 -> 5 ; diff --git a/infer/tests/codetoanalyze/objc/errors/subtyping/KindOfClassExample.m b/infer/tests/codetoanalyze/objc/errors/subtyping/KindOfClassExample.m index 59911d148..72001e4b1 100644 --- a/infer/tests/codetoanalyze/objc/errors/subtyping/KindOfClassExample.m +++ b/infer/tests/codetoanalyze/objc/errors/subtyping/KindOfClassExample.m @@ -17,6 +17,10 @@ @implementation Base +- init { + return self; +} + + (int)returnsZero1:(Base*)b { if ([b isKindOfClass:[self class]]) { return 0; @@ -33,6 +37,10 @@ @implementation Derived +- init { + return self; +} + @end int returnsZero2(Base* b) { diff --git a/infer/tests/codetoanalyze/objc/errors/taint/viewController.m b/infer/tests/codetoanalyze/objc/errors/taint/viewController.m index 4594d80ca..1978a3cac 100644 --- a/infer/tests/codetoanalyze/objc/errors/taint/viewController.m +++ b/infer/tests/codetoanalyze/objc/errors/taint/viewController.m @@ -10,6 +10,8 @@ #import #import +void __set_untaint_attribute(void*); + BOOL ExampleSanitizer(NSURL* u, int f) { if (f) __set_untaint_attribute(u); @@ -21,30 +23,45 @@ BOOL ExampleSanitizer(NSURL* u, int f) { @end @implementation ExampleViewController + +- init { + return self; +} + - (void)loadURL:(NSURL*)URL trackingCodes:(NSArray*)trackingCodes{ // Require untainted URL }; @end -@interface B : NSObject +@interface VCB : NSObject - (void)another_url_pass:(NSURL*)u; @end -@implementation B +@implementation VCB + +- init { + return self; +} + - (void)another_url_pass:(NSURL*)u { ExampleViewController* vc = [[ExampleViewController alloc] init]; [vc loadURL:u trackingCodes:nil]; } @end -@interface A : NSObject +@interface VCA : NSObject - (void)pass_url_arond:(NSURL*)u; @end -@implementation A +@implementation VCA + +- init { + return self; +} + - (void)pass_url_arond:(NSURL*)u { - B* b = [[B alloc] init]; + VCB* b = [[VCB alloc] init]; [b another_url_pass:u]; } @end @@ -57,12 +74,17 @@ BOOL ExampleSanitizer(NSURL* u, int f) { @end @implementation ExampleDelegate + +- init { + return self; +} + - (BOOL)application:(UIApplication*)application openURL:(NSURL*)URL sourceApplication:(NSString*)sourceApplication annotation:(id)annotation { // Assume tainted URL; - A* a = [[A alloc] init]; + VCA* a = [[VCA alloc] init]; if (!ExampleSanitizer(URL, 0)) { [a pass_url_arond:URL]; // report taint } diff --git a/infer/tests/codetoanalyze/objc/errors/variadic_methods/premature_nil_termination.m b/infer/tests/codetoanalyze/objc/errors/variadic_methods/premature_nil_termination.m index 152b605cc..d5319ea3d 100644 --- a/infer/tests/codetoanalyze/objc/errors/variadic_methods/premature_nil_termination.m +++ b/infer/tests/codetoanalyze/objc/errors/variadic_methods/premature_nil_termination.m @@ -9,11 +9,11 @@ #import -@interface A : NSObject { +@interface PrematureNilTermA : NSObject { } @end -@implementation A +@implementation PrematureNilTermA - (void)noProblem { NSArray* foo = [NSArray arrayWithObjects:@"aaa", @"bbb", nil]; @@ -29,8 +29,8 @@ @end -int main() { - A* a = [A alloc]; +int PrematureNilMain() { + PrematureNilTermA* a = [PrematureNilTermA alloc]; [a noProblem]; [a nilInArrayWithObjects]; return 0; diff --git a/infer/tests/codetoanalyze/objc/warnings/ParameterNotNullableExample.m b/infer/tests/codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m similarity index 100% rename from infer/tests/codetoanalyze/objc/warnings/ParameterNotNullableExample.m rename to infer/tests/codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m diff --git a/infer/tests/codetoanalyze/objc/frontend/assertions/NSAssert_example.dot b/infer/tests/codetoanalyze/objc/frontend/assertions/NSAssert_example.dot index 12be4fadf..e7cd40f04 100644 --- a/infer/tests/codetoanalyze/objc/frontend/assertions/NSAssert_example.dot +++ b/infer/tests/codetoanalyze/objc/frontend/assertions/NSAssert_example.dot @@ -78,11 +78,11 @@ digraph iCFG { 87 -> 84 ; -86 [label="86: Prune (false branch) \n n$3=*&target:class A * [line 36]\n PRUNE((n$3 == 0), false); [line 36]\n " shape="invhouse"] +86 [label="86: Prune (false branch) \n n$3=*&target:class NSAssert * [line 36]\n PRUNE((n$3 == 0), false); [line 36]\n " shape="invhouse"] 86 -> 88 ; -85 [label="85: Prune (true branch) \n n$3=*&target:class A * [line 36]\n PRUNE((n$3 != 0), true); [line 36]\n " shape="invhouse"] +85 [label="85: Prune (true branch) \n n$3=*&target:class NSAssert * [line 36]\n PRUNE((n$3 != 0), true); [line 36]\n " shape="invhouse"] 85 -> 87 ; @@ -109,14 +109,14 @@ digraph iCFG { 80 -> 85 ; 80 -> 86 ; -79 [label="79: Return Stmt \n n$0=*&target:class A * [line 37]\n n$1=_fun_A_x(n$0:class A *) [line 37]\n *&return:int =n$1 [line 37]\n " shape="box"] +79 [label="79: Return Stmt \n n$0=*&target:class NSAssert * [line 37]\n n$1=_fun_NSAssert_x(n$0:class NSAssert *) [line 37]\n *&return:int =n$1 [line 37]\n " shape="box"] 79 -> 78 ; 78 [label="78: Exit test2 \n " color=yellow style=filled] -77 [label="77: Start test2\nFormals: target:class A *\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$2:int 0$?%__sil_tmpSIL_temp_conditional___n$10:class NSString * __assert_file__:class NSString * 0$?%__sil_tmpSIL_temp_conditional___n$17:class NSString * __assert_fn__:class NSString * \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$2,&0$?%__sil_tmpSIL_temp_conditional___n$10,&__assert_file__,&0$?%__sil_tmpSIL_temp_conditional___n$17,&__assert_fn__); [line 35]\n " color=yellow style=filled] +77 [label="77: Start test2\nFormals: target:class NSAssert *\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$2:int 0$?%__sil_tmpSIL_temp_conditional___n$10:class NSString * __assert_file__:class NSString * 0$?%__sil_tmpSIL_temp_conditional___n$17:class NSString * __assert_fn__:class NSString * \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$2,&0$?%__sil_tmpSIL_temp_conditional___n$10,&__assert_file__,&0$?%__sil_tmpSIL_temp_conditional___n$17,&__assert_fn__); [line 35]\n " color=yellow style=filled] 77 -> 80 ; @@ -206,7 +206,7 @@ digraph iCFG { 56 -> 58 ; -55 [label="55: BinaryOperatorStmt: NE \n n$3=*&target:class A * [line 31]\n " shape="box"] +55 [label="55: BinaryOperatorStmt: NE \n n$3=*&target:class NSAssert * [line 31]\n " shape="box"] 55 -> 56 ; @@ -233,14 +233,14 @@ digraph iCFG { 50 -> 55 ; -49 [label="49: Return Stmt \n n$0=*&target:class A * [line 32]\n n$1=_fun_A_x(n$0:class A *) [line 32]\n *&return:int =n$1 [line 32]\n " shape="box"] +49 [label="49: Return Stmt \n n$0=*&target:class NSAssert * [line 32]\n n$1=_fun_NSAssert_x(n$0:class NSAssert *) [line 32]\n *&return:int =n$1 [line 32]\n " shape="box"] 49 -> 48 ; 48 [label="48: Exit test1 \n " color=yellow style=filled] -47 [label="47: Start test1\nFormals: target:class A *\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$2:int 0$?%__sil_tmpSIL_temp_conditional___n$9:class NSString * __assert_file__:class NSString * 0$?%__sil_tmpSIL_temp_conditional___n$16:class NSString * __assert_fn__:class NSString * \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$2,&0$?%__sil_tmpSIL_temp_conditional___n$9,&__assert_file__,&0$?%__sil_tmpSIL_temp_conditional___n$16,&__assert_fn__); [line 30]\n " color=yellow style=filled] +47 [label="47: Start test1\nFormals: target:class NSAssert *\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$2:int 0$?%__sil_tmpSIL_temp_conditional___n$9:class NSString * __assert_file__:class NSString * 0$?%__sil_tmpSIL_temp_conditional___n$16:class NSString * __assert_fn__:class NSString * \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$2,&0$?%__sil_tmpSIL_temp_conditional___n$9,&__assert_file__,&0$?%__sil_tmpSIL_temp_conditional___n$16,&__assert_fn__); [line 30]\n " color=yellow style=filled] 47 -> 50 ; @@ -301,7 +301,7 @@ digraph iCFG { 33 -> 35 ; -32 [label="32: BinaryOperatorStmt: NE \n n$20=*&a:class A * [line 24]\n " shape="box"] +32 [label="32: BinaryOperatorStmt: NE \n n$20=*&a:class NSAssert * [line 24]\n " shape="box"] 32 -> 33 ; @@ -328,14 +328,14 @@ digraph iCFG { 27 -> 32 ; -26 [label="26: Return Stmt \n n$17=*&a:class A * [line 25]\n n$18=_fun_A_x(n$17:class A *) [line 25]\n *&return:int =n$18 [line 25]\n " shape="box"] +26 [label="26: Return Stmt \n n$17=*&a:class NSAssert * [line 25]\n n$18=_fun_NSAssert_x(n$17:class NSAssert *) [line 25]\n *&return:int =n$18 [line 25]\n " shape="box"] 26 -> 25 ; -25 [label="25: Exit A_initWithRequest: \n " color=yellow style=filled] +25 [label="25: Exit NSAssert_initWithRequest: \n " color=yellow style=filled] -24 [label="24: Start A_initWithRequest:\nFormals: self:class A * a:class A *\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$19:int 0$?%__sil_tmpSIL_temp_conditional___n$27:class NSString * __assert_file__:class NSString * \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$19,&0$?%__sil_tmpSIL_temp_conditional___n$27,&__assert_file__); [line 23]\n " color=yellow style=filled] +24 [label="24: Start NSAssert_initWithRequest:\nFormals: self:class NSAssert * a:class NSAssert *\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$19:int 0$?%__sil_tmpSIL_temp_conditional___n$27:class NSString * __assert_file__:class NSString * \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$19,&0$?%__sil_tmpSIL_temp_conditional___n$27,&__assert_file__); [line 23]\n " color=yellow style=filled] 24 -> 27 ; @@ -396,7 +396,7 @@ digraph iCFG { 10 -> 12 ; -9 [label="9: BinaryOperatorStmt: NE \n n$3=*&target:class A * [line 19]\n " shape="box"] +9 [label="9: BinaryOperatorStmt: NE \n n$3=*&target:class NSAssert * [line 19]\n " shape="box"] 9 -> 10 ; @@ -423,14 +423,14 @@ digraph iCFG { 4 -> 9 ; -3 [label="3: Return Stmt \n n$0=*&target:class A * [line 20]\n n$1=_fun_A_x(n$0:class A *) [line 20]\n *&return:int =n$1 [line 20]\n " shape="box"] +3 [label="3: Return Stmt \n n$0=*&target:class NSAssert * [line 20]\n n$1=_fun_NSAssert_x(n$0:class NSAssert *) [line 20]\n *&return:int =n$1 [line 20]\n " shape="box"] 3 -> 2 ; -2 [label="2: Exit A_addTarget: \n " color=yellow style=filled] +2 [label="2: Exit NSAssert_addTarget: \n " color=yellow style=filled] -1 [label="1: Start A_addTarget:\nFormals: self:class A * target:class A *\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$2:int 0$?%__sil_tmpSIL_temp_conditional___n$10:class NSString * __assert_file__:class NSString * \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$2,&0$?%__sil_tmpSIL_temp_conditional___n$10,&__assert_file__); [line 18]\n " color=yellow style=filled] +1 [label="1: Start NSAssert_addTarget:\nFormals: self:class NSAssert * target:class NSAssert *\nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$2:int 0$?%__sil_tmpSIL_temp_conditional___n$10:class NSString * __assert_file__:class NSString * \n DECLARE_LOCALS(&return,&0$?%__sil_tmpSIL_temp_conditional___n$2,&0$?%__sil_tmpSIL_temp_conditional___n$10,&__assert_file__); [line 18]\n " color=yellow style=filled] 1 -> 4 ; diff --git a/infer/tests/codetoanalyze/objc/frontend/assertions/NSAssert_example.m b/infer/tests/codetoanalyze/objc/frontend/assertions/NSAssert_example.m index f501a9604..75af4c8ad 100644 --- a/infer/tests/codetoanalyze/objc/frontend/assertions/NSAssert_example.m +++ b/infer/tests/codetoanalyze/objc/frontend/assertions/NSAssert_example.m @@ -9,30 +9,30 @@ #import -@interface A : NSObject +@interface NSAssert : NSObject @property int x; @end -@implementation A +@implementation NSAssert -- (int)addTarget:(A*)target { +- (int)addTarget:(NSAssert*)target { NSAssert(target != nil, @"target must not be nil"); return target.x; } -- (int)initWithRequest:(A*)a { +- (int)initWithRequest:(NSAssert*)a { NSAssert1(a != nil, @"target must not be nil %s", "a"); return a.x; } @end -int test1(A* target) { +int test1(NSAssert* target) { NSCAssert(target != nil, @"target must not be nil"); return target.x; } -int test2(A* target) { +int test2(NSAssert* target) { NSCParameterAssert(target); return target.x; } diff --git a/infer/tests/codetoanalyze/objc/frontend/block/block.dot b/infer/tests/codetoanalyze/objc/frontend/block/block.dot index 957519213..55043a3cc 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/block.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/block.dot @@ -4,10 +4,10 @@ digraph iCFG { 25 -> 24 ; -24 [label="24: Exit main \n " color=yellow style=filled] +24 [label="24: Exit BlockMain \n " color=yellow style=filled] -23 [label="23: Start main\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 46]\n " color=yellow style=filled] +23 [label="23: Start BlockMain\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 46]\n " color=yellow style=filled] 23 -> 25 ; diff --git a/infer/tests/codetoanalyze/objc/frontend/block/block.m b/infer/tests/codetoanalyze/objc/frontend/block/block.m index 907d11c1f..dc55fe16b 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/block.m +++ b/infer/tests/codetoanalyze/objc/frontend/block/block.m @@ -43,4 +43,4 @@ int main1(int y) { return y; } -int main() { return main1(4); } +int BlockMain() { return main1(4); } diff --git a/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot b/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot index 4308b2ee2..a4b3711b4 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot @@ -1,174 +1,185 @@ /* @generated */ digraph iCFG { -45 [label="45: DeclStmt \n n$3=_fun_A_sharedInstance() [line 72]\n *&b:class A *=n$3 [line 72]\n " shape="box"] +48 [label="48: DeclStmt \n n$3=_fun_DispatchA_sharedInstance() [line 76]\n *&b:class DispatchA *=n$3 [line 76]\n " shape="box"] - 45 -> 44 ; -44 [label="44: DeclStmt \n *&p:int *=0 [line 73]\n " shape="box"] + 48 -> 47 ; +47 [label="47: DeclStmt \n *&p:int *=0 [line 77]\n " shape="box"] - 44 -> 39 ; -43 [label="43: Return Stmt \n *&return:int =0 [line 77]\n " shape="box"] + 47 -> 42 ; +46 [label="46: Return Stmt \n *&return:int =0 [line 81]\n " shape="box"] - 43 -> 36 ; -42 [label="42: Return Stmt \n n$1=*&p:int * [line 75]\n n$2=*n$1:int [line 75]\n *&return:int =n$2 [line 75]\n " shape="box"] + 46 -> 39 ; +45 [label="45: Return Stmt \n n$1=*&p:int * [line 79]\n n$2=*n$1:int [line 79]\n *&return:int =n$2 [line 79]\n " shape="box"] - 42 -> 36 ; -41 [label="41: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 74]\n " shape="invhouse"] + 45 -> 39 ; +44 [label="44: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 78]\n " shape="invhouse"] - 41 -> 43 ; -40 [label="40: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 74]\n " shape="invhouse"] + 44 -> 46 ; +43 [label="43: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 78]\n " shape="invhouse"] - 40 -> 42 ; -39 [label="39: BinaryOperatorStmt: EQ \n n$0=*&b:class A * [line 74]\n " shape="box"] + 43 -> 45 ; +42 [label="42: BinaryOperatorStmt: EQ \n n$0=*&b:class DispatchA * [line 78]\n " shape="box"] - 39 -> 40 ; - 39 -> 41 ; -38 [label="38: between_join_and_exit \n " shape="box"] + 42 -> 43 ; + 42 -> 44 ; +41 [label="41: between_join_and_exit \n " shape="box"] - 38 -> 36 ; -37 [label="37: + \n " ] + 41 -> 39 ; +40 [label="40: + \n " ] - 37 -> 38 ; -36 [label="36: Exit main \n " color=yellow style=filled] + 40 -> 41 ; +39 [label="39: Exit DispatchMain \n " color=yellow style=filled] -35 [label="35: Start main\nFormals: \nLocals: p:int * b:class A * \n DECLARE_LOCALS(&return,&p,&b); [line 71]\n " color=yellow style=filled] +38 [label="38: Start DispatchMain\nFormals: \nLocals: p:int * b:class DispatchA * \n DECLARE_LOCALS(&return,&p,&b); [line 75]\n " color=yellow style=filled] - 35 -> 45 ; -34 [label="34: DeclStmt \n n$29=_fun_A_dispatch_a_block_variable_from_macro() [line 64]\n *&a:class A *=n$29 [line 64]\n " shape="box"] + 38 -> 48 ; +37 [label="37: DeclStmt \n n$30=_fun_DispatchA_dispatch_a_block_variable_from_macro() [line 68]\n *&a:class DispatchA *=n$30 [line 68]\n " shape="box"] - 34 -> 33 ; -33 [label="33: BinaryOperatorStmt: Assign \n n$28=*&a:class A * [line 65]\n *n$28._x:int =5 [line 65]\n " shape="box"] + 37 -> 36 ; +36 [label="36: BinaryOperatorStmt: Assign \n n$29=*&a:class DispatchA * [line 69]\n *n$29._x:int =5 [line 69]\n " shape="box"] - 33 -> 32 ; -32 [label="32: Return Stmt \n n$26=*&a:class A * [line 66]\n n$27=*n$26._x:int [line 66]\n *&return:int =(1 / (n$27 - 5)) [line 66]\n " shape="box"] + 36 -> 35 ; +35 [label="35: Return Stmt \n n$27=*&a:class DispatchA * [line 70]\n n$28=*n$27._x:int [line 70]\n *&return:int =(1 / (n$28 - 5)) [line 70]\n " shape="box"] - 32 -> 31 ; -31 [label="31: Exit A_dispatch_a_block_variable_from_macro_delivers_initialised_object \n " color=yellow style=filled] + 35 -> 34 ; +34 [label="34: Exit DispatchA_dispatch_a_block_variable_from_macro_delivers_initialised_object \n " color=yellow style=filled] -30 [label="30: Start A_dispatch_a_block_variable_from_macro_delivers_initialised_object\nFormals: \nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 63]\n " color=yellow style=filled] +33 [label="33: Start DispatchA_dispatch_a_block_variable_from_macro_delivers_initialised_object\nFormals: \nLocals: a:class DispatchA * \n DECLARE_LOCALS(&return,&a); [line 67]\n " color=yellow style=filled] - 30 -> 34 ; -29 [label="29: Return Stmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_a_block_variable_from_macro______4); [line 54]\n n$24=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_a_block_variable_from_macro______4 ):unsigned long ) [line 54]\n *&__objc_anonymous_block_A_dispatch_a_block_variable_from_macro______4:class __objc_anonymous_block_A_dispatch_a_block_variable_from_macro______4 =n$24 [line 54]\n n$25=*&#GB$A_dispatch_a_block_variable_from_macro_static_storage__:struct objc_object * [line 54]\n *n$24.A_dispatch_a_block_variable_from_macro_static_storage__:struct objc_object *=n$25 [line 54]\n *&initialization_block__:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_a_block_variable_from_macro______4) [line 54]\n n$20=*&initialization_block__:_fn_ (*) [line 58]\n n$21=n$20() [line 58]\n n$19=*&#GB$A_dispatch_a_block_variable_from_macro_static_storage__:struct objc_object * [line 59]\n *&return:struct objc_object *=n$19 [line 52]\n " shape="box"] + 33 -> 37 ; +32 [label="32: Return Stmt \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchA_dispatch_a_block_variable_from_macro______4); [line 58]\n n$25=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchA_dispatch_a_block_variable_from_macro______4 ):unsigned long ) [line 58]\n *&__objc_anonymous_block_DispatchA_dispatch_a_block_variable_from_macro______4:class __objc_anonymous_block_DispatchA_dispatch_a_block_variable_from_macro______4 =n$25 [line 58]\n n$26=*&#GB$DispatchA_dispatch_a_block_variable_from_macro_static_storage__:struct objc_object * [line 58]\n *n$25.DispatchA_dispatch_a_block_variable_from_macro_static_storage__:struct objc_object *=n$26 [line 58]\n *&initialization_block__:_fn_ (*)=(_fun___objc_anonymous_block_DispatchA_dispatch_a_block_variable_from_macro______4) [line 58]\n n$21=*&initialization_block__:_fn_ (*) [line 62]\n n$22=n$21() [line 62]\n n$20=*&#GB$DispatchA_dispatch_a_block_variable_from_macro_static_storage__:struct objc_object * [line 63]\n *&return:struct objc_object *=n$20 [line 56]\n " shape="box"] - 29 -> 25 ; -28 [label="28: BinaryOperatorStmt: Assign \n n$22=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 55]\n n$23=_fun_A_init(n$22:class A *) virtual [line 55]\n *&#GB$A_dispatch_a_block_variable_from_macro_static_storage__:struct objc_object *=n$23 [line 55]\n " shape="box"] + 32 -> 28 ; +31 [label="31: BinaryOperatorStmt: Assign \n n$23=_fun___objc_alloc_no_fail(sizeof(class DispatchA ):unsigned long ) [line 59]\n n$24=_fun_DispatchA_init(n$23:class DispatchA *) virtual [line 59]\n *&#GB$DispatchA_dispatch_a_block_variable_from_macro_static_storage__:struct objc_object *=n$24 [line 59]\n " shape="box"] - 28 -> 27 ; -27 [label="27: Exit __objc_anonymous_block_A_dispatch_a_block_variable_from_macro______4 \n " color=yellow style=filled] + 31 -> 30 ; +30 [label="30: Exit __objc_anonymous_block_DispatchA_dispatch_a_block_variable_from_macro______4 \n " color=yellow style=filled] -26 [label="26: Start __objc_anonymous_block_A_dispatch_a_block_variable_from_macro______4\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 54]\n " color=yellow style=filled] +29 [label="29: Start __objc_anonymous_block_DispatchA_dispatch_a_block_variable_from_macro______4\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 58]\n " color=yellow style=filled] - 26 -> 28 ; -25 [label="25: Exit A_dispatch_a_block_variable_from_macro \n " color=yellow style=filled] + 29 -> 31 ; +28 [label="28: Exit DispatchA_dispatch_a_block_variable_from_macro \n " color=yellow style=filled] -24 [label="24: Start A_dispatch_a_block_variable_from_macro\nFormals: \nLocals: initialization_block__:_fn_ (*) \n DECLARE_LOCALS(&return,&initialization_block__); [line 51]\n " color=yellow style=filled] +27 [label="27: Start DispatchA_dispatch_a_block_variable_from_macro\nFormals: \nLocals: initialization_block__:_fn_ (*) \n DECLARE_LOCALS(&return,&initialization_block__); [line 55]\n " color=yellow style=filled] - 24 -> 29 ; -23 [label="23: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_a_block_variable______3); [line 43]\n n$17=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_a_block_variable______3 ):unsigned long ) [line 43]\n *&__objc_anonymous_block_A_dispatch_a_block_variable______3:class __objc_anonymous_block_A_dispatch_a_block_variable______3 =n$17 [line 43]\n n$18=*&#GB$A_dispatch_a_block_variable_static_storage__:struct objc_object * [line 43]\n *n$17.A_dispatch_a_block_variable_static_storage__:struct objc_object *=n$18 [line 43]\n *&initialization_block__:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_a_block_variable______3) [line 43]\n " shape="box"] + 27 -> 32 ; +26 [label="26: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchA_dispatch_a_block_variable______3); [line 47]\n n$18=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchA_dispatch_a_block_variable______3 ):unsigned long ) [line 47]\n *&__objc_anonymous_block_DispatchA_dispatch_a_block_variable______3:class __objc_anonymous_block_DispatchA_dispatch_a_block_variable______3 =n$18 [line 47]\n n$19=*&#GB$DispatchA_dispatch_a_block_variable_static_storage__:struct objc_object * [line 47]\n *n$18.DispatchA_dispatch_a_block_variable_static_storage__:struct objc_object *=n$19 [line 47]\n *&initialization_block__:_fn_ (*)=(_fun___objc_anonymous_block_DispatchA_dispatch_a_block_variable______3) [line 47]\n " shape="box"] - 23 -> 19 ; -22 [label="22: BinaryOperatorStmt: Assign \n n$15=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 44]\n n$16=_fun_A_init(n$15:class A *) virtual [line 44]\n *&#GB$A_dispatch_a_block_variable_static_storage__:struct objc_object *=n$16 [line 44]\n " shape="box"] + 26 -> 22 ; +25 [label="25: BinaryOperatorStmt: Assign \n n$16=_fun___objc_alloc_no_fail(sizeof(class DispatchA ):unsigned long ) [line 48]\n n$17=_fun_DispatchA_init(n$16:class DispatchA *) virtual [line 48]\n *&#GB$DispatchA_dispatch_a_block_variable_static_storage__:struct objc_object *=n$17 [line 48]\n " shape="box"] + + + 25 -> 24 ; +24 [label="24: Exit __objc_anonymous_block_DispatchA_dispatch_a_block_variable______3 \n " color=yellow style=filled] + + +23 [label="23: Start __objc_anonymous_block_DispatchA_dispatch_a_block_variable______3\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 47]\n " color=yellow style=filled] + + + 23 -> 25 ; +22 [label="22: Call n$14 \n n$14=*&initialization_block__:_fn_ (*) [line 51]\n n$15=n$14() [line 51]\n " shape="box"] 22 -> 21 ; -21 [label="21: Exit __objc_anonymous_block_A_dispatch_a_block_variable______3 \n " color=yellow style=filled] +21 [label="21: Return Stmt \n n$13=*&#GB$DispatchA_dispatch_a_block_variable_static_storage__:struct objc_object * [line 52]\n *&return:struct objc_object *=n$13 [line 52]\n " shape="box"] -20 [label="20: Start __objc_anonymous_block_A_dispatch_a_block_variable______3\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 43]\n " color=yellow style=filled] + 21 -> 20 ; +20 [label="20: Exit DispatchA_dispatch_a_block_variable \n " color=yellow style=filled] - 20 -> 22 ; -19 [label="19: Call n$13 \n n$13=*&initialization_block__:_fn_ (*) [line 47]\n n$14=n$13() [line 47]\n " shape="box"] +19 [label="19: Start DispatchA_dispatch_a_block_variable\nFormals: \nLocals: initialization_block__:_fn_ (*) \n DECLARE_LOCALS(&return,&initialization_block__); [line 45]\n " color=yellow style=filled] - 19 -> 18 ; -18 [label="18: Return Stmt \n n$12=*&#GB$A_dispatch_a_block_variable_static_storage__:struct objc_object * [line 48]\n *&return:struct objc_object *=n$12 [line 48]\n " shape="box"] + 19 -> 26 ; +18 [label="18: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchA_trans______2); [line 38]\n n$11=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchA_trans______2 ):unsigned long ) [line 38]\n *&__objc_anonymous_block_DispatchA_trans______2:class __objc_anonymous_block_DispatchA_trans______2 =n$11 [line 38]\n n$12=*&#GB$DispatchA_trans_sharedInstance:struct objc_object * [line 38]\n *n$11.DispatchA_trans_sharedInstance:struct objc_object *=n$12 [line 38]\n *&dummy_block:_fn_ (*)=(_fun___objc_anonymous_block_DispatchA_trans______2) [line 38]\n " shape="box"] - 18 -> 17 ; -17 [label="17: Exit A_dispatch_a_block_variable \n " color=yellow style=filled] + 18 -> 14 ; +17 [label="17: BinaryOperatorStmt: Assign \n n$9=_fun___objc_alloc_no_fail(sizeof(class DispatchA ):unsigned long ) [line 39]\n n$10=_fun_DispatchA_init(n$9:class DispatchA *) virtual [line 39]\n *&#GB$DispatchA_trans_sharedInstance:struct objc_object *=n$10 [line 39]\n " shape="box"] -16 [label="16: Start A_dispatch_a_block_variable\nFormals: \nLocals: initialization_block__:_fn_ (*) \n DECLARE_LOCALS(&return,&initialization_block__); [line 41]\n " color=yellow style=filled] + 17 -> 16 ; +16 [label="16: Exit __objc_anonymous_block_DispatchA_trans______2 \n " color=yellow style=filled] - 16 -> 23 ; -15 [label="15: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_trans______2); [line 34]\n n$10=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_trans______2 ):unsigned long ) [line 34]\n *&__objc_anonymous_block_A_trans______2:class __objc_anonymous_block_A_trans______2 =n$10 [line 34]\n n$11=*&#GB$A_trans_sharedInstance:struct objc_object * [line 34]\n *n$10.A_trans_sharedInstance:struct objc_object *=n$11 [line 34]\n *&dummy_block:_fn_ (*)=(_fun___objc_anonymous_block_A_trans______2) [line 34]\n " shape="box"] +15 [label="15: Start __objc_anonymous_block_DispatchA_trans______2\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 38]\n " color=yellow style=filled] - 15 -> 11 ; -14 [label="14: BinaryOperatorStmt: Assign \n n$8=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 35]\n n$9=_fun_A_init(n$8:class A *) virtual [line 35]\n *&#GB$A_trans_sharedInstance:struct objc_object *=n$9 [line 35]\n " shape="box"] + 15 -> 17 ; +14 [label="14: Call n$8 \n n$8=*&dummy_block:_fn_ (*) [line 41]\n n$8() [line 41]\n " shape="box"] 14 -> 13 ; -13 [label="13: Exit __objc_anonymous_block_A_trans______2 \n " color=yellow style=filled] +13 [label="13: Return Stmt \n n$7=*&#GB$DispatchA_trans_sharedInstance:struct objc_object * [line 42]\n *&return:struct objc_object *=n$7 [line 42]\n " shape="box"] -12 [label="12: Start __objc_anonymous_block_A_trans______2\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 34]\n " color=yellow style=filled] + 13 -> 12 ; +12 [label="12: Exit DispatchA_trans \n " color=yellow style=filled] - 12 -> 14 ; -11 [label="11: Call n$7 \n n$7=*&dummy_block:_fn_ (*) [line 37]\n n$7() [line 37]\n " shape="box"] +11 [label="11: Start DispatchA_trans\nFormals: \nLocals: dummy_block:_fn_ (*) \n DECLARE_LOCALS(&return,&dummy_block); [line 36]\n " color=yellow style=filled] - 11 -> 10 ; -10 [label="10: Return Stmt \n n$6=*&#GB$A_trans_sharedInstance:struct objc_object * [line 38]\n *&return:struct objc_object *=n$6 [line 38]\n " shape="box"] + 11 -> 18 ; +10 [label="10: Call (_fun___objc_anonymous_block_DispatchA_sharedInstance______1) \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchA_sharedInstance______1); [line 30]\n n$4=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchA_sharedInstance______1 ):unsigned long ) [line 30]\n *&__objc_anonymous_block_DispatchA_sharedInstance______1:class __objc_anonymous_block_DispatchA_sharedInstance______1 =n$4 [line 30]\n n$5=*&#GB$DispatchA_sharedInstance_sharedInstance:struct objc_object * [line 30]\n *n$4.DispatchA_sharedInstance_sharedInstance:struct objc_object *=n$5 [line 30]\n n$6=(_fun___objc_anonymous_block_DispatchA_sharedInstance______1)() [line 30]\n " shape="box"] - 10 -> 9 ; -9 [label="9: Exit A_trans \n " color=yellow style=filled] + 10 -> 6 ; +9 [label="9: BinaryOperatorStmt: Assign \n n$2=_fun___objc_alloc_no_fail(sizeof(class DispatchA ):unsigned long ) [line 31]\n n$3=_fun_DispatchA_init(n$2:class DispatchA *) virtual [line 31]\n *&#GB$DispatchA_sharedInstance_sharedInstance:struct objc_object *=n$3 [line 31]\n " shape="box"] -8 [label="8: Start A_trans\nFormals: \nLocals: dummy_block:_fn_ (*) \n DECLARE_LOCALS(&return,&dummy_block); [line 32]\n " color=yellow style=filled] + 9 -> 8 ; +8 [label="8: Exit __objc_anonymous_block_DispatchA_sharedInstance______1 \n " color=yellow style=filled] - 8 -> 15 ; -7 [label="7: Call (_fun___objc_anonymous_block_A_sharedInstance______1) \n DECLARE_LOCALS(&__objc_anonymous_block_A_sharedInstance______1); [line 26]\n n$3=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_sharedInstance______1 ):unsigned long ) [line 26]\n *&__objc_anonymous_block_A_sharedInstance______1:class __objc_anonymous_block_A_sharedInstance______1 =n$3 [line 26]\n n$4=*&#GB$A_sharedInstance_sharedInstance:struct objc_object * [line 26]\n *n$3.A_sharedInstance_sharedInstance:struct objc_object *=n$4 [line 26]\n n$5=(_fun___objc_anonymous_block_A_sharedInstance______1)() [line 26]\n " shape="box"] +7 [label="7: Start __objc_anonymous_block_DispatchA_sharedInstance______1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 30]\n " color=yellow style=filled] - 7 -> 3 ; -6 [label="6: BinaryOperatorStmt: Assign \n n$1=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 27]\n n$2=_fun_A_init(n$1:class A *) virtual [line 27]\n *&#GB$A_sharedInstance_sharedInstance:struct objc_object *=n$2 [line 27]\n " shape="box"] + 7 -> 9 ; +6 [label="6: Return Stmt \n n$1=*&#GB$DispatchA_sharedInstance_sharedInstance:struct objc_object * [line 33]\n *&return:struct objc_object *=n$1 [line 33]\n " shape="box"] 6 -> 5 ; -5 [label="5: Exit __objc_anonymous_block_A_sharedInstance______1 \n " color=yellow style=filled] +5 [label="5: Exit DispatchA_sharedInstance \n " color=yellow style=filled] -4 [label="4: Start __objc_anonymous_block_A_sharedInstance______1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 26]\n " color=yellow style=filled] +4 [label="4: Start DispatchA_sharedInstance\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 27]\n " color=yellow style=filled] - 4 -> 6 ; -3 [label="3: Return Stmt \n n$0=*&#GB$A_sharedInstance_sharedInstance:struct objc_object * [line 29]\n *&return:struct objc_object *=n$0 [line 29]\n " shape="box"] + 4 -> 10 ; +3 [label="3: Return Stmt \n n$0=*&self:class DispatchA * [line 24]\n *&return:struct objc_object *=n$0 [line 24]\n " shape="box"] 3 -> 2 ; -2 [label="2: Exit A_sharedInstance \n " color=yellow style=filled] +2 [label="2: Exit DispatchA_init \n " color=yellow style=filled] -1 [label="1: Start A_sharedInstance\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 23]\n " color=yellow style=filled] +1 [label="1: Start DispatchA_init\nFormals: self:class DispatchA *\nLocals: \n DECLARE_LOCALS(&return); [line 23]\n " color=yellow style=filled] - 1 -> 7 ; + 1 -> 3 ; } diff --git a/infer/tests/codetoanalyze/objc/frontend/block/dispatch.m b/infer/tests/codetoanalyze/objc/frontend/block/dispatch.m index a82a2402b..405d2ee77 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/dispatch.m +++ b/infer/tests/codetoanalyze/objc/frontend/block/dispatch.m @@ -9,7 +9,7 @@ #import -@interface A : NSObject +@interface DispatchA : NSObject @property(nonatomic) int x; @@ -17,7 +17,11 @@ @end -@implementation A { +@implementation DispatchA { +} + +- init { + return self; } + (instancetype)sharedInstance { @@ -61,15 +65,15 @@ } + (int)dispatch_a_block_variable_from_macro_delivers_initialised_object { - A* a = [A dispatch_a_block_variable_from_macro]; + DispatchA* a = [DispatchA dispatch_a_block_variable_from_macro]; a->_x = 5; return 1 / (a->_x - 5); } @end -int main() { - A* b = [A sharedInstance]; +int DispatchMain() { + DispatchA* b = [DispatchA sharedInstance]; int* p = 0; if (b == 0) return *p; diff --git a/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.dot b/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.dot index 43080495d..9dfb85557 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.dot @@ -1,207 +1,218 @@ /* @generated */ digraph iCFG { -54 [label="54: DeclStmt \n *&#GB$A_dispatch_barrier_example_a:class A *=0 [line 72]\n " shape="box"] +57 [label="57: DeclStmt \n *&#GB$DispatchEx_dispatch_barrier_example_a:class DispatchEx *=0 [line 76]\n " shape="box"] + + + 57 -> 56 ; +56 [label="56: Call (_fun___objc_anonymous_block_DispatchEx_dispatch_barrier_example______6) \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchEx_dispatch_barrier_example______6); [line 77]\n n$46=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchEx_dispatch_barrier_example______6 ):unsigned long ) [line 77]\n *&__objc_anonymous_block_DispatchEx_dispatch_barrier_example______6:class __objc_anonymous_block_DispatchEx_dispatch_barrier_example______6 =n$46 [line 77]\n n$47=*&#GB$DispatchEx_dispatch_barrier_example_a:class DispatchEx * [line 77]\n *n$46.DispatchEx_dispatch_barrier_example_a:class DispatchEx *=n$47 [line 77]\n n$48=(_fun___objc_anonymous_block_DispatchEx_dispatch_barrier_example______6)() [line 77]\n " shape="box"] + + + 56 -> 51 ; +55 [label="55: BinaryOperatorStmt: Assign \n n$44=_fun___objc_alloc_no_fail(sizeof(class DispatchEx ):unsigned long ) [line 78]\n n$45=_fun_DispatchEx_init(n$44:class DispatchEx *) virtual [line 78]\n *&#GB$DispatchEx_dispatch_barrier_example_a:class DispatchEx *=n$45 [line 78]\n " shape="box"] + + + 55 -> 54 ; +54 [label="54: BinaryOperatorStmt: Assign \n n$43=*&#GB$DispatchEx_dispatch_barrier_example_a:class DispatchEx * [line 79]\n *n$43.x:int =10 [line 79]\n " shape="box"] 54 -> 53 ; -53 [label="53: Call (_fun___objc_anonymous_block_A_dispatch_barrier_example______6) \n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_barrier_example______6); [line 73]\n n$45=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_barrier_example______6 ):unsigned long ) [line 73]\n *&__objc_anonymous_block_A_dispatch_barrier_example______6:class __objc_anonymous_block_A_dispatch_barrier_example______6 =n$45 [line 73]\n n$46=*&#GB$A_dispatch_barrier_example_a:class A * [line 73]\n *n$45.A_dispatch_barrier_example_a:class A *=n$46 [line 73]\n n$47=(_fun___objc_anonymous_block_A_dispatch_barrier_example______6)() [line 73]\n " shape="box"] +53 [label="53: Exit __objc_anonymous_block_DispatchEx_dispatch_barrier_example______6 \n " color=yellow style=filled] - 53 -> 48 ; -52 [label="52: BinaryOperatorStmt: Assign \n n$43=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 74]\n n$44=_fun_NSObject_init(n$43:class A *) virtual [line 74]\n *&#GB$A_dispatch_barrier_example_a:class A *=n$44 [line 74]\n " shape="box"] +52 [label="52: Start __objc_anonymous_block_DispatchEx_dispatch_barrier_example______6\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 77]\n " color=yellow style=filled] - 52 -> 51 ; -51 [label="51: BinaryOperatorStmt: Assign \n n$42=*&#GB$A_dispatch_barrier_example_a:class A * [line 75]\n *n$42.x:int =10 [line 75]\n " shape="box"] + 52 -> 55 ; +51 [label="51: Return Stmt \n n$41=*&#GB$DispatchEx_dispatch_barrier_example_a:class DispatchEx * [line 81]\n n$42=*n$41.x:int [line 81]\n *&return:int =n$42 [line 81]\n " shape="box"] 51 -> 50 ; -50 [label="50: Exit __objc_anonymous_block_A_dispatch_barrier_example______6 \n " color=yellow style=filled] +50 [label="50: Exit DispatchEx_dispatch_barrier_example \n " color=yellow style=filled] -49 [label="49: Start __objc_anonymous_block_A_dispatch_barrier_example______6\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 73]\n " color=yellow style=filled] +49 [label="49: Start DispatchEx_dispatch_barrier_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 75]\n " color=yellow style=filled] - 49 -> 52 ; -48 [label="48: Return Stmt \n n$40=*&#GB$A_dispatch_barrier_example_a:class A * [line 77]\n n$41=*n$40.x:int [line 77]\n *&return:int =n$41 [line 77]\n " shape="box"] + 49 -> 57 ; +48 [label="48: DeclStmt \n *&#GB$DispatchEx_dispatch_group_notify_example_a:class DispatchEx *=0 [line 67]\n " shape="box"] 48 -> 47 ; -47 [label="47: Exit A_dispatch_barrier_example \n " color=yellow style=filled] +47 [label="47: Call (_fun___objc_anonymous_block_DispatchEx_dispatch_group_notify_example______5) \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchEx_dispatch_group_notify_example______5); [line 68]\n n$38=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchEx_dispatch_group_notify_example______5 ):unsigned long ) [line 68]\n *&__objc_anonymous_block_DispatchEx_dispatch_group_notify_example______5:class __objc_anonymous_block_DispatchEx_dispatch_group_notify_example______5 =n$38 [line 68]\n n$39=*&#GB$DispatchEx_dispatch_group_notify_example_a:class DispatchEx * [line 68]\n *n$38.DispatchEx_dispatch_group_notify_example_a:class DispatchEx *=n$39 [line 68]\n n$40=(_fun___objc_anonymous_block_DispatchEx_dispatch_group_notify_example______5)() [line 68]\n " shape="box"] -46 [label="46: Start A_dispatch_barrier_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 71]\n " color=yellow style=filled] + 47 -> 42 ; +46 [label="46: BinaryOperatorStmt: Assign \n n$36=_fun___objc_alloc_no_fail(sizeof(class DispatchEx ):unsigned long ) [line 69]\n n$37=_fun_DispatchEx_init(n$36:class DispatchEx *) virtual [line 69]\n *&#GB$DispatchEx_dispatch_group_notify_example_a:class DispatchEx *=n$37 [line 69]\n " shape="box"] - 46 -> 54 ; -45 [label="45: DeclStmt \n *&#GB$A_dispatch_group_notify_example_a:class A *=0 [line 63]\n " shape="box"] + 46 -> 45 ; +45 [label="45: BinaryOperatorStmt: Assign \n n$35=*&#GB$DispatchEx_dispatch_group_notify_example_a:class DispatchEx * [line 70]\n *n$35.x:int =10 [line 70]\n " shape="box"] 45 -> 44 ; -44 [label="44: Call (_fun___objc_anonymous_block_A_dispatch_group_notify_example______5) \n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_notify_example______5); [line 64]\n n$37=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_notify_example______5 ):unsigned long ) [line 64]\n *&__objc_anonymous_block_A_dispatch_group_notify_example______5:class __objc_anonymous_block_A_dispatch_group_notify_example______5 =n$37 [line 64]\n n$38=*&#GB$A_dispatch_group_notify_example_a:class A * [line 64]\n *n$37.A_dispatch_group_notify_example_a:class A *=n$38 [line 64]\n n$39=(_fun___objc_anonymous_block_A_dispatch_group_notify_example______5)() [line 64]\n " shape="box"] +44 [label="44: Exit __objc_anonymous_block_DispatchEx_dispatch_group_notify_example______5 \n " color=yellow style=filled] - 44 -> 39 ; -43 [label="43: BinaryOperatorStmt: Assign \n n$35=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 65]\n n$36=_fun_NSObject_init(n$35:class A *) virtual [line 65]\n *&#GB$A_dispatch_group_notify_example_a:class A *=n$36 [line 65]\n " shape="box"] +43 [label="43: Start __objc_anonymous_block_DispatchEx_dispatch_group_notify_example______5\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 68]\n " color=yellow style=filled] - 43 -> 42 ; -42 [label="42: BinaryOperatorStmt: Assign \n n$34=*&#GB$A_dispatch_group_notify_example_a:class A * [line 66]\n *n$34.x:int =10 [line 66]\n " shape="box"] + 43 -> 46 ; +42 [label="42: Return Stmt \n n$33=*&#GB$DispatchEx_dispatch_group_notify_example_a:class DispatchEx * [line 72]\n n$34=*n$33.x:int [line 72]\n *&return:int =n$34 [line 72]\n " shape="box"] 42 -> 41 ; -41 [label="41: Exit __objc_anonymous_block_A_dispatch_group_notify_example______5 \n " color=yellow style=filled] +41 [label="41: Exit DispatchEx_dispatch_group_notify_example \n " color=yellow style=filled] -40 [label="40: Start __objc_anonymous_block_A_dispatch_group_notify_example______5\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 64]\n " color=yellow style=filled] +40 [label="40: Start DispatchEx_dispatch_group_notify_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 66]\n " color=yellow style=filled] - 40 -> 43 ; -39 [label="39: Return Stmt \n n$32=*&#GB$A_dispatch_group_notify_example_a:class A * [line 68]\n n$33=*n$32.x:int [line 68]\n *&return:int =n$33 [line 68]\n " shape="box"] + 40 -> 48 ; +39 [label="39: DeclStmt \n *&#GB$DispatchEx_dispatch_group_example_a:class DispatchEx *=0 [line 58]\n " shape="box"] 39 -> 38 ; -38 [label="38: Exit A_dispatch_group_notify_example \n " color=yellow style=filled] +38 [label="38: Call (_fun___objc_anonymous_block_DispatchEx_dispatch_group_example______4) \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchEx_dispatch_group_example______4); [line 59]\n n$30=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchEx_dispatch_group_example______4 ):unsigned long ) [line 59]\n *&__objc_anonymous_block_DispatchEx_dispatch_group_example______4:class __objc_anonymous_block_DispatchEx_dispatch_group_example______4 =n$30 [line 59]\n n$31=*&#GB$DispatchEx_dispatch_group_example_a:class DispatchEx * [line 59]\n *n$30.DispatchEx_dispatch_group_example_a:class DispatchEx *=n$31 [line 59]\n n$32=(_fun___objc_anonymous_block_DispatchEx_dispatch_group_example______4)() [line 59]\n " shape="box"] -37 [label="37: Start A_dispatch_group_notify_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 62]\n " color=yellow style=filled] + 38 -> 33 ; +37 [label="37: BinaryOperatorStmt: Assign \n n$28=_fun___objc_alloc_no_fail(sizeof(class DispatchEx ):unsigned long ) [line 60]\n n$29=_fun_DispatchEx_init(n$28:class DispatchEx *) virtual [line 60]\n *&#GB$DispatchEx_dispatch_group_example_a:class DispatchEx *=n$29 [line 60]\n " shape="box"] - 37 -> 45 ; -36 [label="36: DeclStmt \n *&#GB$A_dispatch_group_example_a:class A *=0 [line 54]\n " shape="box"] + 37 -> 36 ; +36 [label="36: BinaryOperatorStmt: Assign \n n$27=*&#GB$DispatchEx_dispatch_group_example_a:class DispatchEx * [line 61]\n *n$27.x:int =10 [line 61]\n " shape="box"] 36 -> 35 ; -35 [label="35: Call (_fun___objc_anonymous_block_A_dispatch_group_example______4) \n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_example______4); [line 55]\n n$29=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_example______4 ):unsigned long ) [line 55]\n *&__objc_anonymous_block_A_dispatch_group_example______4:class __objc_anonymous_block_A_dispatch_group_example______4 =n$29 [line 55]\n n$30=*&#GB$A_dispatch_group_example_a:class A * [line 55]\n *n$29.A_dispatch_group_example_a:class A *=n$30 [line 55]\n n$31=(_fun___objc_anonymous_block_A_dispatch_group_example______4)() [line 55]\n " shape="box"] +35 [label="35: Exit __objc_anonymous_block_DispatchEx_dispatch_group_example______4 \n " color=yellow style=filled] - 35 -> 30 ; -34 [label="34: BinaryOperatorStmt: Assign \n n$27=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 56]\n n$28=_fun_NSObject_init(n$27:class A *) virtual [line 56]\n *&#GB$A_dispatch_group_example_a:class A *=n$28 [line 56]\n " shape="box"] +34 [label="34: Start __objc_anonymous_block_DispatchEx_dispatch_group_example______4\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 59]\n " color=yellow style=filled] - 34 -> 33 ; -33 [label="33: BinaryOperatorStmt: Assign \n n$26=*&#GB$A_dispatch_group_example_a:class A * [line 57]\n *n$26.x:int =10 [line 57]\n " shape="box"] + 34 -> 37 ; +33 [label="33: Return Stmt \n n$25=*&#GB$DispatchEx_dispatch_group_example_a:class DispatchEx * [line 63]\n n$26=*n$25.x:int [line 63]\n *&return:int =n$26 [line 63]\n " shape="box"] 33 -> 32 ; -32 [label="32: Exit __objc_anonymous_block_A_dispatch_group_example______4 \n " color=yellow style=filled] +32 [label="32: Exit DispatchEx_dispatch_group_example \n " color=yellow style=filled] -31 [label="31: Start __objc_anonymous_block_A_dispatch_group_example______4\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 55]\n " color=yellow style=filled] +31 [label="31: Start DispatchEx_dispatch_group_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 57]\n " color=yellow style=filled] - 31 -> 34 ; -30 [label="30: Return Stmt \n n$24=*&#GB$A_dispatch_group_example_a:class A * [line 59]\n n$25=*n$24.x:int [line 59]\n *&return:int =n$25 [line 59]\n " shape="box"] + 31 -> 39 ; +30 [label="30: DeclStmt \n *&#GB$DispatchEx_dispatch_after_example_a:class DispatchEx *=0 [line 47]\n " shape="box"] 30 -> 29 ; -29 [label="29: Exit A_dispatch_group_example \n " color=yellow style=filled] +29 [label="29: Call (_fun___objc_anonymous_block_DispatchEx_dispatch_after_example______3) \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchEx_dispatch_after_example______3); [line 50]\n n$22=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchEx_dispatch_after_example______3 ):unsigned long ) [line 50]\n *&__objc_anonymous_block_DispatchEx_dispatch_after_example______3:class __objc_anonymous_block_DispatchEx_dispatch_after_example______3 =n$22 [line 50]\n n$23=*&#GB$DispatchEx_dispatch_after_example_a:class DispatchEx * [line 50]\n *n$22.DispatchEx_dispatch_after_example_a:class DispatchEx *=n$23 [line 50]\n n$24=(_fun___objc_anonymous_block_DispatchEx_dispatch_after_example______3)() [line 48]\n " shape="box"] -28 [label="28: Start A_dispatch_group_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 53]\n " color=yellow style=filled] + 29 -> 24 ; +28 [label="28: BinaryOperatorStmt: Assign \n n$20=_fun___objc_alloc_no_fail(sizeof(class DispatchEx ):unsigned long ) [line 51]\n n$21=_fun_DispatchEx_init(n$20:class DispatchEx *) virtual [line 51]\n *&#GB$DispatchEx_dispatch_after_example_a:class DispatchEx *=n$21 [line 51]\n " shape="box"] - 28 -> 36 ; -27 [label="27: DeclStmt \n *&#GB$A_dispatch_after_example_a:class A *=0 [line 43]\n " shape="box"] + 28 -> 27 ; +27 [label="27: BinaryOperatorStmt: Assign \n n$19=*&#GB$DispatchEx_dispatch_after_example_a:class DispatchEx * [line 52]\n *n$19.x:int =10 [line 52]\n " shape="box"] 27 -> 26 ; -26 [label="26: Call (_fun___objc_anonymous_block_A_dispatch_after_example______3) \n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_after_example______3); [line 46]\n n$21=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_after_example______3 ):unsigned long ) [line 46]\n *&__objc_anonymous_block_A_dispatch_after_example______3:class __objc_anonymous_block_A_dispatch_after_example______3 =n$21 [line 46]\n n$22=*&#GB$A_dispatch_after_example_a:class A * [line 46]\n *n$21.A_dispatch_after_example_a:class A *=n$22 [line 46]\n n$23=(_fun___objc_anonymous_block_A_dispatch_after_example______3)() [line 44]\n " shape="box"] +26 [label="26: Exit __objc_anonymous_block_DispatchEx_dispatch_after_example______3 \n " color=yellow style=filled] - 26 -> 21 ; -25 [label="25: BinaryOperatorStmt: Assign \n n$19=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 47]\n n$20=_fun_NSObject_init(n$19:class A *) virtual [line 47]\n *&#GB$A_dispatch_after_example_a:class A *=n$20 [line 47]\n " shape="box"] +25 [label="25: Start __objc_anonymous_block_DispatchEx_dispatch_after_example______3\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 50]\n " color=yellow style=filled] - 25 -> 24 ; -24 [label="24: BinaryOperatorStmt: Assign \n n$18=*&#GB$A_dispatch_after_example_a:class A * [line 48]\n *n$18.x:int =10 [line 48]\n " shape="box"] + 25 -> 28 ; +24 [label="24: Return Stmt \n n$17=*&#GB$DispatchEx_dispatch_after_example_a:class DispatchEx * [line 54]\n n$18=*n$17.x:int [line 54]\n *&return:int =n$18 [line 54]\n " shape="box"] 24 -> 23 ; -23 [label="23: Exit __objc_anonymous_block_A_dispatch_after_example______3 \n " color=yellow style=filled] +23 [label="23: Exit DispatchEx_dispatch_after_example \n " color=yellow style=filled] -22 [label="22: Start __objc_anonymous_block_A_dispatch_after_example______3\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 46]\n " color=yellow style=filled] +22 [label="22: Start DispatchEx_dispatch_after_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 46]\n " color=yellow style=filled] - 22 -> 25 ; -21 [label="21: Return Stmt \n n$16=*&#GB$A_dispatch_after_example_a:class A * [line 50]\n n$17=*n$16.x:int [line 50]\n *&return:int =n$17 [line 50]\n " shape="box"] + 22 -> 30 ; +21 [label="21: DeclStmt \n *&#GB$DispatchEx_dispatch_async_example_a:class DispatchEx *=0 [line 37]\n " shape="box"] 21 -> 20 ; -20 [label="20: Exit A_dispatch_after_example \n " color=yellow style=filled] +20 [label="20: Call (_fun___objc_anonymous_block_DispatchEx_dispatch_async_example______2) \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchEx_dispatch_async_example______2); [line 39]\n n$14=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchEx_dispatch_async_example______2 ):unsigned long ) [line 39]\n *&__objc_anonymous_block_DispatchEx_dispatch_async_example______2:class __objc_anonymous_block_DispatchEx_dispatch_async_example______2 =n$14 [line 39]\n n$15=*&#GB$DispatchEx_dispatch_async_example_a:class DispatchEx * [line 39]\n *n$14.DispatchEx_dispatch_async_example_a:class DispatchEx *=n$15 [line 39]\n n$16=(_fun___objc_anonymous_block_DispatchEx_dispatch_async_example______2)() [line 38]\n " shape="box"] -19 [label="19: Start A_dispatch_after_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 42]\n " color=yellow style=filled] + 20 -> 15 ; +19 [label="19: BinaryOperatorStmt: Assign \n n$12=_fun___objc_alloc_no_fail(sizeof(class DispatchEx ):unsigned long ) [line 40]\n n$13=_fun_DispatchEx_init(n$12:class DispatchEx *) virtual [line 40]\n *&#GB$DispatchEx_dispatch_async_example_a:class DispatchEx *=n$13 [line 40]\n " shape="box"] - 19 -> 27 ; -18 [label="18: DeclStmt \n *&#GB$A_dispatch_async_example_a:class A *=0 [line 33]\n " shape="box"] + 19 -> 18 ; +18 [label="18: BinaryOperatorStmt: Assign \n n$11=*&#GB$DispatchEx_dispatch_async_example_a:class DispatchEx * [line 41]\n *n$11.x:int =10 [line 41]\n " shape="box"] 18 -> 17 ; -17 [label="17: Call (_fun___objc_anonymous_block_A_dispatch_async_example______2) \n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_async_example______2); [line 35]\n n$13=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_async_example______2 ):unsigned long ) [line 35]\n *&__objc_anonymous_block_A_dispatch_async_example______2:class __objc_anonymous_block_A_dispatch_async_example______2 =n$13 [line 35]\n n$14=*&#GB$A_dispatch_async_example_a:class A * [line 35]\n *n$13.A_dispatch_async_example_a:class A *=n$14 [line 35]\n n$15=(_fun___objc_anonymous_block_A_dispatch_async_example______2)() [line 34]\n " shape="box"] +17 [label="17: Exit __objc_anonymous_block_DispatchEx_dispatch_async_example______2 \n " color=yellow style=filled] - 17 -> 12 ; -16 [label="16: BinaryOperatorStmt: Assign \n n$11=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 36]\n n$12=_fun_NSObject_init(n$11:class A *) virtual [line 36]\n *&#GB$A_dispatch_async_example_a:class A *=n$12 [line 36]\n " shape="box"] +16 [label="16: Start __objc_anonymous_block_DispatchEx_dispatch_async_example______2\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 39]\n " color=yellow style=filled] - 16 -> 15 ; -15 [label="15: BinaryOperatorStmt: Assign \n n$10=*&#GB$A_dispatch_async_example_a:class A * [line 37]\n *n$10.x:int =10 [line 37]\n " shape="box"] + 16 -> 19 ; +15 [label="15: Return Stmt \n n$9=*&#GB$DispatchEx_dispatch_async_example_a:class DispatchEx * [line 43]\n n$10=*n$9.x:int [line 43]\n *&return:int =n$10 [line 43]\n " shape="box"] 15 -> 14 ; -14 [label="14: Exit __objc_anonymous_block_A_dispatch_async_example______2 \n " color=yellow style=filled] +14 [label="14: Exit DispatchEx_dispatch_async_example \n " color=yellow style=filled] -13 [label="13: Start __objc_anonymous_block_A_dispatch_async_example______2\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 35]\n " color=yellow style=filled] +13 [label="13: Start DispatchEx_dispatch_async_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 36]\n " color=yellow style=filled] - 13 -> 16 ; -12 [label="12: Return Stmt \n n$8=*&#GB$A_dispatch_async_example_a:class A * [line 39]\n n$9=*n$8.x:int [line 39]\n *&return:int =n$9 [line 39]\n " shape="box"] + 13 -> 21 ; +12 [label="12: DeclStmt \n *&#GB$DispatchEx_dispatch_once_example_a:class DispatchEx *=0 [line 25]\n " shape="box"] 12 -> 11 ; -11 [label="11: Exit A_dispatch_async_example \n " color=yellow style=filled] +11 [label="11: Call (_fun___objc_anonymous_block_DispatchEx_dispatch_once_example______1) \n DECLARE_LOCALS(&__objc_anonymous_block_DispatchEx_dispatch_once_example______1); [line 29]\n n$6=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_DispatchEx_dispatch_once_example______1 ):unsigned long ) [line 29]\n *&__objc_anonymous_block_DispatchEx_dispatch_once_example______1:class __objc_anonymous_block_DispatchEx_dispatch_once_example______1 =n$6 [line 29]\n n$7=*&#GB$DispatchEx_dispatch_once_example_a:class DispatchEx * [line 29]\n *n$6.DispatchEx_dispatch_once_example_a:class DispatchEx *=n$7 [line 29]\n n$8=(_fun___objc_anonymous_block_DispatchEx_dispatch_once_example______1)() [line 29]\n " shape="box"] -10 [label="10: Start A_dispatch_async_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 32]\n " color=yellow style=filled] + 11 -> 6 ; +10 [label="10: BinaryOperatorStmt: Assign \n n$4=_fun___objc_alloc_no_fail(sizeof(class DispatchEx ):unsigned long ) [line 30]\n n$5=_fun_DispatchEx_init(n$4:class DispatchEx *) virtual [line 30]\n *&#GB$DispatchEx_dispatch_once_example_a:class DispatchEx *=n$5 [line 30]\n " shape="box"] - 10 -> 18 ; -9 [label="9: DeclStmt \n *&#GB$A_dispatch_once_example_a:class A *=0 [line 21]\n " shape="box"] + 10 -> 9 ; +9 [label="9: BinaryOperatorStmt: Assign \n n$3=*&#GB$DispatchEx_dispatch_once_example_a:class DispatchEx * [line 31]\n *n$3.x:int =10 [line 31]\n " shape="box"] 9 -> 8 ; -8 [label="8: Call (_fun___objc_anonymous_block_A_dispatch_once_example______1) \n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_once_example______1); [line 25]\n n$5=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_once_example______1 ):unsigned long ) [line 25]\n *&__objc_anonymous_block_A_dispatch_once_example______1:class __objc_anonymous_block_A_dispatch_once_example______1 =n$5 [line 25]\n n$6=*&#GB$A_dispatch_once_example_a:class A * [line 25]\n *n$5.A_dispatch_once_example_a:class A *=n$6 [line 25]\n n$7=(_fun___objc_anonymous_block_A_dispatch_once_example______1)() [line 25]\n " shape="box"] +8 [label="8: Exit __objc_anonymous_block_DispatchEx_dispatch_once_example______1 \n " color=yellow style=filled] - 8 -> 3 ; -7 [label="7: BinaryOperatorStmt: Assign \n n$3=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 26]\n n$4=_fun_NSObject_init(n$3:class A *) virtual [line 26]\n *&#GB$A_dispatch_once_example_a:class A *=n$4 [line 26]\n " shape="box"] +7 [label="7: Start __objc_anonymous_block_DispatchEx_dispatch_once_example______1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 29]\n " color=yellow style=filled] - 7 -> 6 ; -6 [label="6: BinaryOperatorStmt: Assign \n n$2=*&#GB$A_dispatch_once_example_a:class A * [line 27]\n *n$2.x:int =10 [line 27]\n " shape="box"] + 7 -> 10 ; +6 [label="6: Return Stmt \n n$1=*&#GB$DispatchEx_dispatch_once_example_a:class DispatchEx * [line 33]\n n$2=*n$1.x:int [line 33]\n *&return:int =n$2 [line 33]\n " shape="box"] 6 -> 5 ; -5 [label="5: Exit __objc_anonymous_block_A_dispatch_once_example______1 \n " color=yellow style=filled] +5 [label="5: Exit DispatchEx_dispatch_once_example \n " color=yellow style=filled] -4 [label="4: Start __objc_anonymous_block_A_dispatch_once_example______1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 25]\n " color=yellow style=filled] +4 [label="4: Start DispatchEx_dispatch_once_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 24]\n " color=yellow style=filled] - 4 -> 7 ; -3 [label="3: Return Stmt \n n$0=*&#GB$A_dispatch_once_example_a:class A * [line 29]\n n$1=*n$0.x:int [line 29]\n *&return:int =n$1 [line 29]\n " shape="box"] + 4 -> 12 ; +3 [label="3: Return Stmt \n n$0=*&self:class DispatchEx * [line 21]\n *&return:struct objc_object *=n$0 [line 21]\n " shape="box"] 3 -> 2 ; -2 [label="2: Exit A_dispatch_once_example \n " color=yellow style=filled] +2 [label="2: Exit DispatchEx_init \n " color=yellow style=filled] -1 [label="1: Start A_dispatch_once_example\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 20]\n " color=yellow style=filled] +1 [label="1: Start DispatchEx_init\nFormals: self:class DispatchEx *\nLocals: \n DECLARE_LOCALS(&return); [line 20]\n " color=yellow style=filled] - 1 -> 9 ; + 1 -> 3 ; } diff --git a/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.m b/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.m index 9e3b4fc9a..fa3f5633a 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.m +++ b/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.m @@ -9,69 +9,73 @@ #import -@interface A : NSObject { +@interface DispatchEx : NSObject { int x; } @end -@implementation A +@implementation DispatchEx + +- init { + return self; +} + (int)dispatch_once_example { - static A* a = nil; + static DispatchEx* a = nil; // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, // 0),^{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - a = [[A alloc] init]; + a = [[DispatchEx alloc] init]; a->x = 10; }); return a->x; } + (int)dispatch_async_example { - static A* a = nil; + static DispatchEx* a = nil; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - a = [[A alloc] init]; + a = [[DispatchEx alloc] init]; a->x = 10; }); return a->x; } + (int)dispatch_after_example { - static A* a = nil; + static DispatchEx* a = nil; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - a = [[A alloc] init]; + a = [[DispatchEx alloc] init]; a->x = 10; }); return a->x; } + (int)dispatch_group_example { - static A* a = nil; + static DispatchEx* a = nil; dispatch_group_async(NULL, dispatch_get_main_queue(), ^{ - a = [[A alloc] init]; + a = [[DispatchEx alloc] init]; a->x = 10; }); return a->x; } + (int)dispatch_group_notify_example { - static A* a = nil; + static DispatchEx* a = nil; dispatch_group_async(NULL, dispatch_get_main_queue(), ^{ - a = [[A alloc] init]; + a = [[DispatchEx alloc] init]; a->x = 10; }); return a->x; } + (int)dispatch_barrier_example { - static A* a = nil; + static DispatchEx* a = nil; dispatch_barrier_async(dispatch_get_main_queue(), ^{ - a = [[A alloc] init]; + a = [[DispatchEx alloc] init]; a->x = 10; }); return a->x; diff --git a/infer/tests/codetoanalyze/objc/frontend/block/dispatch_in_macro.m b/infer/tests/codetoanalyze/objc/frontend/block/dispatch_in_macro.m index 079e4063f..e63d5c2da 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/dispatch_in_macro.m +++ b/infer/tests/codetoanalyze/objc/frontend/block/dispatch_in_macro.m @@ -19,4 +19,6 @@ static_storage; \ }) -id test() { return INITIALIZE_AND_RETURN_STATIC([NSObject new]); } +id DispatchInMacroTest() { + return INITIALIZE_AND_RETURN_STATIC([NSObject new]); +} diff --git a/infer/tests/codetoanalyze/objc/frontend/property/GetterExample.h b/infer/tests/codetoanalyze/objc/frontend/property/GetterExample.h index bf6c594e9..f43a246f0 100644 --- a/infer/tests/codetoanalyze/objc/frontend/property/GetterExample.h +++ b/infer/tests/codetoanalyze/objc/frontend/property/GetterExample.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -@interface A +@interface GetterExample : NSObject @property int name; diff --git a/infer/tests/codetoanalyze/objc/frontend/property/GetterExample.m b/infer/tests/codetoanalyze/objc/frontend/property/GetterExample.m index cd9269512..883f58a5b 100644 --- a/infer/tests/codetoanalyze/objc/frontend/property/GetterExample.m +++ b/infer/tests/codetoanalyze/objc/frontend/property/GetterExample.m @@ -12,7 +12,7 @@ #import "GetterExample.h" int should_have_div0() { - A* a = [[A alloc] init]; + GetterExample* a = [[GetterExample alloc] init]; a.name = 5; return 1 / (a.name - 5); } diff --git a/infer/tests/codetoanalyze/objc/frontend/property/PropertyAttributes.dot b/infer/tests/codetoanalyze/objc/frontend/property/PropertyAttributes.dot index 51924bf40..3feeb71a1 100644 --- a/infer/tests/codetoanalyze/objc/frontend/property/PropertyAttributes.dot +++ b/infer/tests/codetoanalyze/objc/frontend/property/PropertyAttributes.dot @@ -1,73 +1,84 @@ /* @generated */ digraph iCFG { -18 [label="18: Exit frontend_checks_23a4fcc8f25cc8087aa9202ac0edfbf5 \n " color=yellow style=filled] +21 [label="21: Exit frontend_checks_23a4fcc8f25cc8087aa9202ac0edfbf5 \n " color=yellow style=filled] -17 [label="17: Start frontend_checks_23a4fcc8f25cc8087aa9202ac0edfbf5\nFormals: \nLocals: \n " color=yellow style=filled] +20 [label="20: Start frontend_checks_23a4fcc8f25cc8087aa9202ac0edfbf5\nFormals: \nLocals: \n " color=yellow style=filled] - 17 -> 18 ; -16 [label="16: DeclStmt \n n$3=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 39]\n n$4=_fun_NSObject_init(n$3:class A *) virtual [line 39]\n *&a:class A *=n$4 [line 39]\n " shape="box"] + 20 -> 21 ; +19 [label="19: DeclStmt \n n$3=_fun___objc_alloc_no_fail(sizeof(class PropertyA ):unsigned long ) [line 43]\n n$4=_fun_PropertyA_init(n$3:class PropertyA *) virtual [line 43]\n *&a:class PropertyA *=n$4 [line 43]\n " shape="box"] + + + 19 -> 18 ; +18 [label="18: Message Call: setLast_name: \n n$1=*&a:class PropertyA * [line 44]\n n$2=*&a2:class PropertyA * [line 44]\n _fun_PropertyA_setLast_name:(n$1:class PropertyA *,n$2:class PropertyA *) [line 44]\n " shape="box"] + + + 18 -> 17 ; +17 [label="17: Message Call: release \n n$0=*&a:class PropertyA * [line 45]\n _fun___objc_release(n$0:class PropertyA *) [line 45]\n " shape="box"] + + + 17 -> 16 ; +16 [label="16: Return Stmt \n *&return:int =0 [line 46]\n " shape="box"] 16 -> 15 ; -15 [label="15: Message Call: setLast_name: \n n$1=*&a:class A * [line 40]\n n$2=*&a2:class A * [line 40]\n _fun_A_setLast_name:(n$1:class A *,n$2:class A *) [line 40]\n " shape="box"] +15 [label="15: Exit test \n " color=yellow style=filled] - 15 -> 14 ; -14 [label="14: Message Call: release \n n$0=*&a:class A * [line 41]\n _fun___objc_release(n$0:class A *) [line 41]\n " shape="box"] +14 [label="14: Start test\nFormals: a2:class PropertyA *\nLocals: a:class PropertyA * \n DECLARE_LOCALS(&return,&a); [line 42]\n " color=yellow style=filled] - 14 -> 13 ; -13 [label="13: Return Stmt \n *&return:int =0 [line 42]\n " shape="box"] + 14 -> 19 ; +13 [label="13: DeclStmt \n n$12=_fun___objc_alloc_no_fail(sizeof(class PropertyA ):unsigned long ) [line 31]\n n$13=_fun_PropertyA_init(n$12:class PropertyA *) virtual [line 31]\n *&other:class PropertyA *=n$13 [line 31]\n " shape="box"] - 13 -> 12 ; -12 [label="12: Exit test \n " color=yellow style=filled] + 13 -> 8 ; + 13 -> 9 ; +12 [label="12: BinaryOperatorStmt: Assign \n n$9=*&other:class PropertyA * [line 33]\n n$10=*&self:class PropertyA * [line 33]\n n$11=*n$10._name:class PropertyA * [line 33]\n *n$9._name:class PropertyA *=n$11 [line 33]\n " shape="box"] -11 [label="11: Start test\nFormals: a2:class A *\nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 38]\n " color=yellow style=filled] + 12 -> 11 ; +11 [label="11: BinaryOperatorStmt: Assign \n n$6=*&other:class PropertyA * [line 34]\n n$7=*&self:class PropertyA * [line 34]\n n$8=*n$7._last_name:class PropertyA * [line 34]\n *n$6._last_name:class PropertyA *=n$8 [line 34]\n " shape="box"] - 11 -> 16 ; -10 [label="10: DeclStmt \n n$11=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 27]\n n$12=_fun_NSObject_init(n$11:class A *) virtual [line 27]\n *&other:class A *=n$12 [line 27]\n " shape="box"] + 11 -> 10 ; +10 [label="10: BinaryOperatorStmt: Assign \n n$3=*&other:class PropertyA * [line 35]\n n$4=*&self:class PropertyA * [line 35]\n n$5=*n$4._child:class PropertyA * [line 35]\n *n$3._child:class PropertyA *=n$5 [line 35]\n " shape="box"] - 10 -> 5 ; - 10 -> 6 ; -9 [label="9: BinaryOperatorStmt: Assign \n n$8=*&other:class A * [line 29]\n n$9=*&self:class A * [line 29]\n n$10=*n$9._name:class A * [line 29]\n *n$8._name:class A *=n$10 [line 29]\n " shape="box"] + 10 -> 7 ; +9 [label="9: Prune (false branch) \n n$2=*&other:class PropertyA * [line 32]\n PRUNE((n$2 == 0), false); [line 32]\n " shape="invhouse"] - 9 -> 8 ; -8 [label="8: BinaryOperatorStmt: Assign \n n$5=*&other:class A * [line 30]\n n$6=*&self:class A * [line 30]\n n$7=*n$6._last_name:class A * [line 30]\n *n$5._last_name:class A *=n$7 [line 30]\n " shape="box"] + 9 -> 7 ; +8 [label="8: Prune (true branch) \n n$2=*&other:class PropertyA * [line 32]\n PRUNE((n$2 != 0), true); [line 32]\n " shape="invhouse"] - 8 -> 7 ; -7 [label="7: BinaryOperatorStmt: Assign \n n$2=*&other:class A * [line 31]\n n$3=*&self:class A * [line 31]\n n$4=*n$3._child:class A * [line 31]\n *n$2._child:class A *=n$4 [line 31]\n " shape="box"] + 8 -> 12 ; +7 [label="7: + \n " ] - 7 -> 4 ; -6 [label="6: Prune (false branch) \n n$1=*&other:class A * [line 28]\n PRUNE((n$1 == 0), false); [line 28]\n " shape="invhouse"] + 7 -> 6 ; +6 [label="6: Return Stmt \n n$1=*&other:class PropertyA * [line 37]\n *&return:class PropertyA *=n$1 [line 37]\n " shape="box"] - 6 -> 4 ; -5 [label="5: Prune (true branch) \n n$1=*&other:class A * [line 28]\n PRUNE((n$1 != 0), true); [line 28]\n " shape="invhouse"] + 6 -> 5 ; +5 [label="5: Exit PropertyA_copy \n " color=yellow style=filled] - 5 -> 9 ; -4 [label="4: + \n " ] +4 [label="4: Start PropertyA_copy\nFormals: self:class PropertyA *\nLocals: other:class PropertyA * \n DECLARE_LOCALS(&return,&other); [line 30]\n " color=yellow style=filled] - 4 -> 3 ; -3 [label="3: Return Stmt \n n$0=*&other:class A * [line 33]\n *&return:class A *=n$0 [line 33]\n " shape="box"] + 4 -> 13 ; +3 [label="3: Return Stmt \n n$0=*&self:class PropertyA * [line 27]\n *&return:struct objc_object *=n$0 [line 27]\n " shape="box"] 3 -> 2 ; -2 [label="2: Exit A_copy \n " color=yellow style=filled] +2 [label="2: Exit PropertyA_init \n " color=yellow style=filled] -1 [label="1: Start A_copy\nFormals: self:class A *\nLocals: other:class A * \n DECLARE_LOCALS(&return,&other); [line 26]\n " color=yellow style=filled] +1 [label="1: Start PropertyA_init\nFormals: self:class PropertyA *\nLocals: \n DECLARE_LOCALS(&return); [line 26]\n " color=yellow style=filled] - 1 -> 10 ; + 1 -> 3 ; } diff --git a/infer/tests/codetoanalyze/objc/frontend/property/PropertyAttributes.m b/infer/tests/codetoanalyze/objc/frontend/property/PropertyAttributes.m index 411d5f199..911fc7824 100644 --- a/infer/tests/codetoanalyze/objc/frontend/property/PropertyAttributes.m +++ b/infer/tests/codetoanalyze/objc/frontend/property/PropertyAttributes.m @@ -9,22 +9,26 @@ #import -@interface A : NSObject +@interface PropertyA : NSObject -@property(nonatomic, copy) A* child; +@property(nonatomic, copy) PropertyA* child; -@property(nonatomic, retain) A* name; +@property(nonatomic, retain) PropertyA* name; -@property(nonatomic, unsafe_unretained) A* last_name; +@property(nonatomic, unsafe_unretained) PropertyA* last_name; -- (A*)copy; +- (PropertyA*)copy; @end -@implementation A +@implementation PropertyA -- (A*)copy { - A* other = [[A alloc] init]; +- init { + return self; +} + +- (PropertyA*)copy { + PropertyA* other = [[PropertyA alloc] init]; if (other) { other->_name = self->_name; other->_last_name = self->_last_name; @@ -35,8 +39,8 @@ @end -int test(A* a2) { - A* a = [[A alloc] init]; +int test(PropertyA* a2) { + PropertyA* a = [[PropertyA alloc] init]; a.last_name = a2; [a release]; return 0; diff --git a/infer/tests/endtoend/objc/infer/AutoreleaseTest.java b/infer/tests/endtoend/objc/infer/AutoreleaseTest.java index 9079dfb87..54663943c 100644 --- a/infer/tests/endtoend/objc/infer/AutoreleaseTest.java +++ b/infer/tests/endtoend/objc/infer/AutoreleaseTest.java @@ -57,7 +57,7 @@ public class AutoreleaseTest { doesNotContain( MEMORY_LEAK, memory_leak_file, - "main")); + "autorelease_main")); } /* @Test @@ -71,7 +71,7 @@ public class AutoreleaseTest { inferError( MEMORY_LEAK, memory_leak_file, - "test1"))); + "autorelease_test1"))); } */ @Test @@ -84,7 +84,7 @@ public class AutoreleaseTest { doesNotContain( MEMORY_LEAK, memory_leak_file, - "test2")); + "autorelease_test2")); } @Test @@ -97,7 +97,7 @@ public class AutoreleaseTest { doesNotContain( MEMORY_LEAK, memory_leak_file, - "test3")); + "autorelease_test3")); } } diff --git a/infer/tests/endtoend/objc/infer/BlockDispatchTest.java b/infer/tests/endtoend/objc/infer/BlockDispatchTest.java index fb3b7c61d..75884a92e 100644 --- a/infer/tests/endtoend/objc/infer/BlockDispatchTest.java +++ b/infer/tests/endtoend/objc/infer/BlockDispatchTest.java @@ -48,7 +48,7 @@ public class BlockDispatchTest { throws InterruptedException, IOException, InferException { InferResults inferResults = InferRunner.runInferC(inferCmd); String[] procedures = { - "A_dispatch_a_block_variable_from_macro_delivers_initialised_object" + "DispatchA_dispatch_a_block_variable_from_macro_delivers_initialised_object" }; assertThat( "Results should contain the expected " + DIVIDE_BY_ZERO, diff --git a/infer/tests/endtoend/objc/infer/CategoryProcdescTest.java b/infer/tests/endtoend/objc/infer/CategoryProcdescTest.java index d627e6a7c..d9dc7f337 100644 --- a/infer/tests/endtoend/objc/infer/CategoryProcdescTest.java +++ b/infer/tests/endtoend/objc/infer/CategoryProcdescTest.java @@ -55,7 +55,7 @@ public class CategoryProcdescTest { contains( MEMORY_LEAK, MAIN_FILE, - "main" + "CategoryProcdescMain" ) ); } diff --git a/infer/tests/endtoend/objc/infer/ExplicitIvarNameInGetterTest.java b/infer/tests/endtoend/objc/infer/ExplicitIvarNameInGetterTest.java index 0ae8f6b26..9139c8ad6 100644 --- a/infer/tests/endtoend/objc/infer/ExplicitIvarNameInGetterTest.java +++ b/infer/tests/endtoend/objc/infer/ExplicitIvarNameInGetterTest.java @@ -58,7 +58,7 @@ public class ExplicitIvarNameInGetterTest { NULL_DEREFERENCE, FILE, new String[]{ - "test", + "testExplicit", "testDefaultName" } ) diff --git a/infer/tests/endtoend/objc/infer/MemoryLeakBucketingArcTest.java b/infer/tests/endtoend/objc/infer/MemoryLeakBucketingArcTest.java index 56a8c96fa..2d38dbda6 100644 --- a/infer/tests/endtoend/objc/infer/MemoryLeakBucketingArcTest.java +++ b/infer/tests/endtoend/objc/infer/MemoryLeakBucketingArcTest.java @@ -28,7 +28,8 @@ import utils.InferRunner; public class MemoryLeakBucketingArcTest { public static final String memory_leak_file = - "infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExampleBucketing.m"; + "infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/" + + "RetainReleaseExampleBucketingArc.m"; private static ImmutableList inferCmd; @@ -57,7 +58,7 @@ public class MemoryLeakBucketingArcTest { doesNotContain( MEMORY_LEAK, memory_leak_file, - "test")); + "RetainReleaseArcTest")); } diff --git a/infer/tests/endtoend/objc/infer/MemoryLeakBucketingTest.java b/infer/tests/endtoend/objc/infer/MemoryLeakBucketingTest.java index 52f71c38f..f29cc8072 100644 --- a/infer/tests/endtoend/objc/infer/MemoryLeakBucketingTest.java +++ b/infer/tests/endtoend/objc/infer/MemoryLeakBucketingTest.java @@ -57,7 +57,7 @@ public class MemoryLeakBucketingTest { doesNotContain( MEMORY_LEAK, memory_leak_file, - "test")); + "RetainReleaseTest")); } diff --git a/infer/tests/endtoend/objc/infer/NPEEqualNamesTest.java b/infer/tests/endtoend/objc/infer/NPEEqualNamesTest.java index 853e1c87c..46bcbc2f0 100644 --- a/infer/tests/endtoend/objc/infer/NPEEqualNamesTest.java +++ b/infer/tests/endtoend/objc/infer/NPEEqualNamesTest.java @@ -52,7 +52,7 @@ public class NPEEqualNamesTest { public void nullDereferenceTest() throws InterruptedException, IOException, InferException { InferResults inferResults = InferRunner.runInferObjC(inferCmdNPD); String[] procedures = { - "test", + "EqualNamesTest", }; assertThat( "Results should contain null pointer dereference error", diff --git a/infer/tests/endtoend/objc/infer/ParameterNotNullableTest.java b/infer/tests/endtoend/objc/infer/ParameterNotNullableTest.java index ffe9bf93a..0013811bb 100644 --- a/infer/tests/endtoend/objc/infer/ParameterNotNullableTest.java +++ b/infer/tests/endtoend/objc/infer/ParameterNotNullableTest.java @@ -29,7 +29,7 @@ import utils.InferRunner; public class ParameterNotNullableTest { public static final String FILE = - "infer/tests/codetoanalyze/objc/warnings/ParameterNotNullableExample.m"; + "infer/tests/codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m"; private static ImmutableList inferCmdFraction; diff --git a/infer/tests/endtoend/objc/infer/ProcdescTest.java b/infer/tests/endtoend/objc/infer/ProcdescTest.java index cba69caaf..e9608dff5 100644 --- a/infer/tests/endtoend/objc/infer/ProcdescTest.java +++ b/infer/tests/endtoend/objc/infer/ProcdescTest.java @@ -54,7 +54,7 @@ public class ProcdescTest { contains( MEMORY_LEAK, MAIN_FILE, - "main" + "ProcdescMain" ) ); } diff --git a/infer/tests/endtoend/objc/infer/PropertyTest.java b/infer/tests/endtoend/objc/infer/PropertyTest.java index e0517d947..a03cf24c2 100644 --- a/infer/tests/endtoend/objc/infer/PropertyTest.java +++ b/infer/tests/endtoend/objc/infer/PropertyTest.java @@ -53,7 +53,7 @@ public class PropertyTest { contains( MEMORY_LEAK, MAIN_FILE, - "main" + "property_main" ) ); } diff --git a/infer/tests/endtoend/objc/infer/ProtocolProcdescTest.java b/infer/tests/endtoend/objc/infer/ProtocolProcdescTest.java index e71d7ba97..d94af3921 100644 --- a/infer/tests/endtoend/objc/infer/ProtocolProcdescTest.java +++ b/infer/tests/endtoend/objc/infer/ProtocolProcdescTest.java @@ -54,7 +54,7 @@ public class ProtocolProcdescTest { contains( MEMORY_LEAK, MAIN_FILE, - "main" + "ProcdescMain" ) ); } diff --git a/infer/tests/endtoend/objc/infer/RetainCycle2Test.java b/infer/tests/endtoend/objc/infer/RetainCycle2Test.java index 5b60d9ff7..e61183d00 100644 --- a/infer/tests/endtoend/objc/infer/RetainCycle2Test.java +++ b/infer/tests/endtoend/objc/infer/RetainCycle2Test.java @@ -61,7 +61,7 @@ public class RetainCycle2Test { containsExactly( RETAIN_CYCLE, retain_cycle_file, - new String[]{"strongcycle"})); + new String[]{"strongcycle2"})); } diff --git a/infer/tests/endtoend/objc/infer/RetainCycleStaticVarTest.java b/infer/tests/endtoend/objc/infer/RetainCycleStaticVarTest.java index 5ff73cd91..bb1dd2c8c 100644 --- a/infer/tests/endtoend/objc/infer/RetainCycleStaticVarTest.java +++ b/infer/tests/endtoend/objc/infer/RetainCycleStaticVarTest.java @@ -50,7 +50,7 @@ public class RetainCycleStaticVarTest { throws InterruptedException, IOException, InferException { InferResults inferResults = InferRunner.runInferObjC(inferCmd); String[] procedures = { - "main", + "RetainCSVycleStaticVar", }; assertThat( "Results should contain the expected retain cycles", diff --git a/infer/tests/endtoend/objc/infer/SubtypingTest.java b/infer/tests/endtoend/objc/infer/SubtypingTest.java index 7f4abc8f6..86772a923 100644 --- a/infer/tests/endtoend/objc/infer/SubtypingTest.java +++ b/infer/tests/endtoend/objc/infer/SubtypingTest.java @@ -49,7 +49,7 @@ public class SubtypingTest { InferResults inferResults = InferRunner.runInferC(inferCmd); String[] procedures = { "Employee_initWithName:andAge:andEducation:", - "test" + "subtyping_test" }; assertThat( "Results should contain the expected divide by zero", diff --git a/infer/tests/endtoend/objc/infer/WeakVariableInBlockNPETest.java b/infer/tests/endtoend/objc/infer/WeakVariableInBlockNPETest.java index 042cba608..e7f2afbd5 100644 --- a/infer/tests/endtoend/objc/infer/WeakVariableInBlockNPETest.java +++ b/infer/tests/endtoend/objc/infer/WeakVariableInBlockNPETest.java @@ -51,7 +51,7 @@ public class WeakVariableInBlockNPETest { public void whenInferRunsOnWeakCapturedVariablesNPEThenNPEsFound() throws InterruptedException, IOException, InferException { InferResults inferResults = InferRunner.runInferC(inferCmdNPD); - String[] procedures = {"__objc_anonymous_block_A_strongSelfNoCheck______2"}; + String[] procedures = {"__objc_anonymous_block_WeakCapturedA_strongSelfNoCheck______2"}; assertThat( "Results should not contain null dereference", inferResults,