|
|
|
digraph iCFG {
|
|
|
|
51 [label="51: Return Stmt \n *&return:int =0 [line 99]\n APPLY_ABSTRACTION; [line 99]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
51 -> 45 ;
|
|
|
|
50 [label="50: Return Stmt \n *&return:int =1 [line 98]\n APPLY_ABSTRACTION; [line 98]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
50 -> 45 ;
|
|
|
|
49 [label="49: Prune (false branch) \n PRUNE(((sizeof(class A ) != n$23) == 0), false); [line 98]\n REMOVE_TEMPS(n$23); [line 98]\n " shape="invhouse"]
|
|
|
|
|
|
|
|
|
|
|
|
49 -> 51 ;
|
|
|
|
48 [label="48: Prune (true branch) \n PRUNE(((sizeof(class A ) != n$23) != 0), true); [line 98]\n REMOVE_TEMPS(n$23); [line 98]\n " shape="invhouse"]
|
|
|
|
|
|
|
|
|
|
|
|
48 -> 50 ;
|
|
|
|
47 [label="47: BinaryOperatorStmt: NE \n n$23=*&c:struct objc_class * [line 98]\n NULLIFY(&c,false); [line 98]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
47 -> 48 ;
|
|
|
|
47 -> 49 ;
|
|
|
|
46 [label="46: + \n NULLIFY(&c,false); [line 98]\n " ]
|
|
|
|
|
|
|
|
|
|
|
|
46 -> 45 ;
|
|
|
|
45 [label="45: Exit A_used_in_binary_op: \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
44 [label="44: Start A_used_in_binary_op:\nFormals: c:struct objc_class *\nLocals: \n DECLARE_LOCALS(&return); [line 96]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
44 -> 47 ;
|
|
|
|
43 [label="43: Return Stmt \n n$22=_fun_NSStringFromClass(sizeof(class A ):unsigned long ) [line 93]\n *&return:class NSString *=n$22 [line 93]\n REMOVE_TEMPS(n$22); [line 93]\n APPLY_ABSTRACTION; [line 93]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
43 -> 42 ;
|
|
|
|
42 [label="42: Exit A_loggerName \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
41 [label="41: Start A_loggerName\nFormals: self:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 91]\n NULLIFY(&self,false); [line 91]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
41 -> 43 ;
|
Using clang's method resolution if possible
Summary: public
Using clang's method resolution. This means that, in method calls, clang gives you a pointer to the declaration of the method.
In some cases though, clang doesn't find the right method. For example, when it finds a method in a category, we
need to make it into a method in the corresponding class, because that's how we treat categories in Infer. Moreover,
when it finds a method in a protocol, that is not useful for us, since the implementation will be in some class. Finally,
sometimes the call is on an object of type id, in which case clang doesn't know what is the correct declaration. In
those cases, we fall back to what we were doing before of approximating the method resolution. We also refactor
some of the code.
Reviewed By: akotulski
Differential Revision: D2679766
fb-gh-sync-id: b79bb85
9 years ago
|
|
|
40 [label="40: Message Call: init \n n$19=*&self:class A * [line 88]\n n$18=_fun_NSObject_init(n$19:class A *) [line 88]\n REMOVE_TEMPS(n$18,n$19); [line 88]\n NULLIFY(&self,false); [line 88]\n APPLY_ABSTRACTION; [line 88]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
40 -> 39 ;
|
|
|
|
39 [label="39: Exit A_init \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
38 [label="38: Start A_init\nFormals: self:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 87]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
38 -> 40 ;
|
|
|
|
37 [label="37: Message Call: test_class \n _fun_C_test_class() [line 84]\n APPLY_ABSTRACTION; [line 84]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
37 -> 36 ;
|
|
|
|
36 [label="36: Exit A_calling_super \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
35 [label="35: Start A_calling_super\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 83]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
35 -> 37 ;
|
|
|
|
34 [label="34: Return Stmt \n n$15=*&object:class B * [line 80]\n n$14=_fun_B_isC:(n$15:class B *,sizeof(class A ):unsigned long ) virtual [line 80]\n *&return:_Bool =n$14 [line 80]\n REMOVE_TEMPS(n$14,n$15); [line 80]\n NULLIFY(&object,false); [line 80]\n APPLY_ABSTRACTION; [line 80]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
34 -> 33 ;
|
|
|
|
33 [label="33: Exit A_use_class_in_other_ways: \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
32 [label="32: Start A_use_class_in_other_ways:\nFormals: self:class A * object:class B *\nLocals: \n DECLARE_LOCALS(&return); [line 79]\n NULLIFY(&self,false); [line 79]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
32 -> 34 ;
|
Using clang's method resolution if possible
Summary: public
Using clang's method resolution. This means that, in method calls, clang gives you a pointer to the declaration of the method.
In some cases though, clang doesn't find the right method. For example, when it finds a method in a category, we
need to make it into a method in the corresponding class, because that's how we treat categories in Infer. Moreover,
when it finds a method in a protocol, that is not useful for us, since the implementation will be in some class. Finally,
sometimes the call is on an object of type id, in which case clang doesn't know what is the correct declaration. In
those cases, we fall back to what we were doing before of approximating the method resolution. We also refactor
some of the code.
Reviewed By: akotulski
Differential Revision: D2679766
fb-gh-sync-id: b79bb85
9 years ago
|
|
|
31 [label="31: DeclStmt \n n$12=_fun___objc_alloc_no_fail(sizeof(class B ):unsigned long ) [line 75]\n n$13=_fun_NSObject_init(n$12:class B *) virtual [line 75]\n *&b:class B *=n$13 [line 75]\n REMOVE_TEMPS(n$12,n$13); [line 75]\n NULLIFY(&b,false); [line 75]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
31 -> 30 ;
|
|
|
|
30 [label="30: Message Call: b_m \n _fun_B_b_m() [line 76]\n APPLY_ABSTRACTION; [line 76]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
30 -> 29 ;
|
|
|
|
29 [label="29: Exit A_t \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
28 [label="28: Start A_t\nFormals: self:class A *\nLocals: b:class B * \n DECLARE_LOCALS(&return,&b); [line 74]\n NULLIFY(&b,false); [line 74]\n NULLIFY(&self,false); [line 74]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
28 -> 31 ;
|
|
|
|
27 [label="27: Message Call: test_class \n _fun_A_test_class() [line 71]\n APPLY_ABSTRACTION; [line 71]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
27 -> 26 ;
|
|
|
|
26 [label="26: Exit A_call_class_instance_with_class_name \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
25 [label="25: Start A_call_class_instance_with_class_name\nFormals: self:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 70]\n NULLIFY(&self,false); [line 70]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
25 -> 27 ;
|
|
|
|
24 [label="24: Message Call: test_class \n _fun_A_test_class() [line 67]\n APPLY_ABSTRACTION; [line 67]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
24 -> 23 ;
|
|
|
|
23 [label="23: Exit A_call_class_instance \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
22 [label="22: Start A_call_class_instance\nFormals: self:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 66]\n NULLIFY(&self,false); [line 66]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
22 -> 24 ;
|
|
|
|
21 [label="21: Call alloc \n n$6=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 63]\n REMOVE_TEMPS(n$6); [line 63]\n APPLY_ABSTRACTION; [line 63]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
21 -> 20 ;
|
|
|
|
20 [label="20: Exit A_call_alloc_instance \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
19 [label="19: Start A_call_alloc_instance\nFormals: self:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 62]\n NULLIFY(&self,false); [line 62]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
19 -> 21 ;
|
|
|
|
18 [label="18: Call alloc \n n$2=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 59]\n REMOVE_TEMPS(n$2); [line 59]\n APPLY_ABSTRACTION; [line 59]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
18 -> 17 ;
|
|
|
|
17 [label="17: Exit A_call_alloc_class \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
16 [label="16: Start A_call_alloc_class\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 58]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
16 -> 18 ;
|
|
|
|
15 [label="15: Message Call: test_class \n _fun_A_test_class() [line 55]\n APPLY_ABSTRACTION; [line 55]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
15 -> 14 ;
|
|
|
|
14 [label="14: Exit A_call_test_class \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
13 [label="13: Start A_call_test_class\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 54]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
13 -> 15 ;
|
|
|
|
12 [label="12: Exit A_test_class \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
11 [label="11: Start A_test_class\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 51]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
11 -> 12 ;
|
|
|
|
10 [label="10: Message Call: test \n n$0=*&self:class A * [line 48]\n _fun_A_test(n$0:class A *) virtual [line 48]\n REMOVE_TEMPS(n$0); [line 48]\n NULLIFY(&self,false); [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
10 -> 9 ;
|
|
|
|
9 [label="9: Exit A_call_test \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
8 [label="8: Start A_call_test\nFormals: self:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 47]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
8 -> 10 ;
|
|
|
|
7 [label="7: Exit A_test \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
6 [label="6: Start A_test\nFormals: self:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 42]\n NULLIFY(&self,false); [line 42]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
6 -> 7 ;
|
|
|
|
5 [label="5: Return Stmt \n *&return:_Bool =1 [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"]
|
|
|
|
|
|
|
|
|
|
|
|
5 -> 4 ;
|
|
|
|
4 [label="4: Exit B_isC: \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
3 [label="3: Start B_isC:\nFormals: self:class B * aClass:struct objc_class *\nLocals: \n DECLARE_LOCALS(&return); [line 22]\n NULLIFY(&aClass,false); [line 22]\n NULLIFY(&self,false); [line 22]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
3 -> 5 ;
|
|
|
|
2 [label="2: Exit B_b_m \n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
1 [label="1: Start B_b_m\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 20]\n " color=yellow style=filled]
|
|
|
|
|
|
|
|
|
|
|
|
1 -> 2 ;
|
|
|
|
}
|