SVF icon indicating copy to clipboard operation
SVF copied to clipboard

Regarding the field-sensitive capability of SVF.

Open Ehu1 opened this issue 6 months ago • 0 comments

My goal is to determine that among the following three for_each functions, the first and second operate on the same memory, while the first and third operate on different memory. Here, since each for_each in Clang uses a distinct function name, there is no issue with context sensitivity. However, I still cannot make this determination using SVF.

class domain{
public:
    domain(std::vector<int> xx, std::vector<int> yy) : x(xx), y(yy) {};

    std::vector<int> x;
    std::vector<int> y;
};

int main() {
    std::vector<int> x1 = {1, 2, 3,4};
    std::vector<int> y1 = {4, 5, 6,7};
    std::vector<int> x2 = {7, 8, 9,10};
    std::vector<int> y2 = {10, 11, 12,13};
    domain d1(x1, y1);
    domain d2(x2, y2);
    std::for_each(d1.x.begin(), d1.x.end(), [](auto& elem) {
        elem = 0;
    });
    std::for_each(d1.x.begin(), d1.x.end(), [](auto& elem) {
        elem = 0;
    });
    std::for_each(d1.y.begin(), d1.y.end(), [](auto& elem) {
        elem = 0;
    });

    return 0;
}

Below is the key part of the LLVM IR:

%x = getelementptr inbounds %class.domain, %class.domain* %d1, i64 0, i32 0
  %call = call i32* @_ZNSt6vectorIiSaIiEE5beginEv(%"class.std::vector"* noundef nonnull align 8 dereferenceable(24) %x) #14
  %call61 = call i32* @_ZNSt6vectorIiSaIiEE3endEv(%"class.std::vector"* noundef nonnull align 8 dereferenceable(24) %x) #14
  call fastcc void @"_ZSt8for_eachIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEZ4mainE3$_0ET0_T_S9_S8_"(i32* %call, i32* %call61)
  %call70 = call i32* @_ZNSt6vectorIiSaIiEE5beginEv(%"class.std::vector"* noundef nonnull align 8 dereferenceable(24) %x) #14
  %call74 = call i32* @_ZNSt6vectorIiSaIiEE3endEv(%"class.std::vector"* noundef nonnull align 8 dereferenceable(24) %x) #14
  call fastcc void @"_ZSt8for_eachIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEZ4mainE3$_1ET0_T_S9_S8_"(i32* %call70, i32* %call74)
  %y = getelementptr inbounds %class.domain, %class.domain* %d1, i64 0, i32 1
  %call82 = call i32* @_ZNSt6vectorIiSaIiEE5beginEv(%"class.std::vector"* noundef nonnull align 8 dereferenceable(24) %y) #14
  %call86 = call i32* @_ZNSt6vectorIiSaIiEE3endEv(%"class.std::vector"* noundef nonnull align 8 dereferenceable(24) %y) #14
  call fastcc void @"_ZSt8for_eachIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEZ4mainE3$_2ET0_T_S9_S8_"(i32* %call82, i32* %call86)

Below are the options I used to generate the .dot file:

wpa -nander -stat=false -print-pts -dump-pag -dump-constraint-graph test.ll

However, the final graph looks like this. Can I interpret this as being due to the calls to .begin() functions and SVF's lack of context-sensitive capability, preventing me from achieving the desired analysis result?

Image

Ehu1 avatar May 14 '25 07:05 Ehu1