AIM for today: - Extract out the pointer that is being used to call the vfunc from the current region. - Search it's regions to find out which subclass the pointer is actually pointing to. - Make use of this information to filter out one most probable call to function out of all of the possible functions that can be called at that callsite.
— PROGRESS : - From observation, a typical vfunc call that isn't devirtualised by the compiler's front end looks something like this "OBJ_TYPE_REF(_2;(struct A)a_ptr_5(D)->0) (a_ptr_5(D))" where "a_ptr_5(D)" is pointer that is being used to call the virtual function. - We can access it's region to see what is the type of the object the pointer is actually pointing to. - This is then used to find a call with DECL_CONTEXT of the object from the all the possible targets of that polymorphic call. - The changes can be tested on refs/users/arsenic/heads/polymorphic_cal branch of the repository. - I tested the changes with on the following test program ( https://godbolt.org/z/fqrsE1d84 ) And it successfully provided the following analysis : ``` /Users/ankursaini/Desktop/test.cpp: In member function ‘virtual int B::deallocate()’: /Users/ankursaini/Desktop/test.cpp:25:13: warning: double-‘free’ of ‘b.B::ptr’ [CWE-415] [-Wanalyzer-double-free] 25 | free(ptr); | ~~~~^~~~~ ‘void test()’: events 1-2 | | 35 | void test() | | ^~~~ | | | | | (1) entry to ‘test’ |...... | 40 | b.allocate(); | | ~~~~~~~~~~~~ | | | | | (2) calling ‘B::allocate’ from ‘test’ | +--> ‘void B::allocate()’: events 3-4 | | 19 | void allocate () | | ^~~~~~~~ | | | | | (3) entry to ‘B::allocate’ | 20 | { | 21 | ptr = (int*)malloc(sizeof(int)); | | ~~~~~~~~~~~~~~~~~~~ | | | | | (4) allocated here | <------+ | ‘void test()’: events 5-6 | | 40 | b.allocate(); | | ~~~~~~~~~~^~ | | | | | (5) returning to ‘test’ from ‘B::allocate’ | 41 | foo(aptr); | | ~~~~~~~~~ | | | | | (6) calling ‘foo’ from ‘test’ | +--> ‘void foo(A*)’: events 7-8 | | 30 | void foo(A *a_ptr) | | ^~~ | | | | | (7) entry to ‘foo’ | 31 | { | 32 | printf("%d\n",a_ptr->deallocate()); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (8) calling ‘B::deallocate’ from ‘foo’ | +--> ‘virtual int B::deallocate()’: events 9-10 | | 23 | int deallocate (void) | | ^~~~~~~~~~ | | | | | (9) entry to ‘B::deallocate’ | 24 | { | 25 | free(ptr); | | ~~~~~~~~~ | | | | | (10) first ‘free’ here | <------+ | ‘void foo(A*)’: event 11 | | 32 | printf("%d\n",a_ptr->deallocate()); | | ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (11) returning to ‘foo’ from ‘B::deallocate’ | <------+ | ‘void test()’: events 12-13 | | 41 | foo(aptr); | | ~~~^~~~~~ | | | | | (12) returning to ‘test’ from ‘foo’ |...... | 45 | foo(aptr); | | ~~~~~~~~~ | | | | | (13) calling ‘foo’ from ‘test’ | +--> ‘void foo(A*)’: events 14-15 | | 30 | void foo(A *a_ptr) | | ^~~ | | | | | (14) entry to ‘foo’ | 31 | { | 32 | printf("%d\n",a_ptr->deallocate()); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (15) calling ‘B::deallocate’ from ‘foo’ | +--> ‘virtual int B::deallocate()’: events 16-17 | | 23 | int deallocate (void) | | ^~~~~~~~~~ | | | | | (16) entry to ‘B::deallocate’ | 24 | { | 25 | free(ptr); | | ~~~~~~~~~ | | | | | (17) second ‘free’ here; first ‘free’ was at (10) | ``` — STATUS AT THE END OF THE DAY :- - Extract out the pointer that is being used to call the vfunc from the current region. (done) - Search it's regions to find out which subclass the pointer is actually pointing to. (done) - Make use of this information to filter out one most probable call to function out of all of the possible functions that can be called at that call-site. (done) --- Patch file ( prototype ) :
indirect_calls.patch
Description: Binary data
Thank you - Ankur