Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Higher optimization level leads to broken value flow in virtual functions #1312

Closed
Qcloud1223 opened this issue Jan 1, 2024 · 7 comments
Closed

Comments

@Qcloud1223
Copy link
Contributor

Hi, I encounter some problems when playing with virtual functions under SVF. Below is a minimal reproducible example:

// using external variable and printf to prevent O3 from optimizing the whole call
#include <stdio.h>
extern int unknown;

class myClass 
{
public:
    virtual void foo(int *a);
    virtual void foo(int *a, int b);
};

__attribute__((noinline))
void myClass::foo(int *a)
{
    foo(a, unknown);
}

__attribute__((noinline))
void myClass::foo(int *a, int b)
{
    a += b;
    printf("%d\n", *a);
}

int main()
{
    myClass mc;
    int a;
    mc.foo(&a);

    return 0;
}

Obviously, a from main is passed through myClass::foo(int *a), and eventually modified in myClass::foo(int *a, int b). This is a consistent value flow, and is captured by SVF when compiled without optimization, as shown in two red arrows in the graph below.

value-flow-O0

However, when compiled with O3, SVFG is as follows:

value-flow-O3

There is only one red arrow, indicating the value flow from main to myClass::foo(int *a). a in myClass::foo(int *a, int b) does not have any source in this case. I was expecting to see a red arrow connecting node 58 and 62, but there is not. Is it an expected behavior?

FYI, both bitcodes are compiled under clang++ 14.0.0.

Thanks for your time and happy new year!

@yuleisui
Copy link
Collaborator

yuleisui commented Jan 2, 2024

Thanks for reporting this, could you upload the bc files before and after the optimisation?

@Qcloud1223
Copy link
Contributor Author

virtual-func-bc.zip

Here are the bitcodes compiled with both O0 and O3.

@Qcloud1223
Copy link
Contributor Author

May I ask if there is any update on this issue? @yuleisui

@yuleisui
Copy link
Collaborator

yuleisui commented Jan 4, 2024

@xudon9 could you have a look at this issue?

@xudon9
Copy link
Contributor

xudon9 commented Jan 4, 2024

We have received several issues with virtual functions. We are reviewing related parts of C++ feature handling. It might take a while before all the problems get solved. Thanks.

@Qcloud1223
Copy link
Contributor Author

Though it's a bit late, I still want to add a tiny finding.

The SVFG remains a consistent value flow if wpa runs with -v-call-cha. I dived a little into the code and found that in this case virtual function information is directly retrieved from CHG, instead of pointer analysis results. So the problem should come from pointer analysis.

FYI, all the results above are generated under -ander.

@Qcloud1223
Copy link
Contributor Author

For anymore who might concern, this issue is resolved possibly due to #1369.

Below is the SVFG on O3-optimized bitcode, from which we can clearly see the consistent value-flow now (two read arrows).

image

Make sure to use LLVM 16 otherwise latest SVF would fail on:

wpa: /home/iom/SVF/svf-llvm/lib/CHGBuilder.cpp:520: void SVF::CHGBuilder::analyzeVTables(const Module&): Assertion `opcode == Instruction::IntToPtr' failed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants