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

Type inference failure for linked list #1442

Open
Qcloud1223 opened this issue Apr 22, 2024 · 1 comment
Open

Type inference failure for linked list #1442

Qcloud1223 opened this issue Apr 22, 2024 · 1 comment

Comments

@Qcloud1223
Copy link
Contributor

Hi,

I was trying to play with type inference under SVF using linked list, and found an unexpected result.
Here is a minimal reproducible example:

struct ll
{
    int a;
    ll *next;
};

int main()
{
    ll node;
    node.next = new ll;
    node.next->a = 1;
    
    return 0;
}

And (related part of) its PAG is:

	Node0x55f8222e1180 [shape=record,shape=box,label="{[main] ValVar ID: 30\n   %3 = call noalias noundef nonnull ptr @_Znwm(i64 noundef 16) #2 }"];
	Node0x55f8222e1180 -> Node0x55f822317e60[color=blue];
	Node0x55f8222ea110 [shape=record,shape=box3d,label="{[main] FIObjVar ID: 31 (base object)\n   %3 = call noalias noundef nonnull ptr @_Znwm(i64 noundef 16) #2 }"];
	Node0x55f8222ea110 -> Node0x55f8222e1180[color=green];

So the PAG node ID of the object on heap is 31.

The type inference result for this object is:

(gdb) p *pag->getGNode(31)->getType()
$10 = {_vptr.SVFType = 0x55555682f698 <vtable for SVF::SVFIntegerType+16>, static svfPtrTy = 0x5555568df290, 
  static svfI8Ty = 0x5555568caea0, kind = 2, typeinfo = 0x5555568ea490, isSingleValTy = true, byteSize = 1}

which presents the default type SVFIntegerType, indicating that type inference does not work correctly.

Here is the IR of main:

define dso_local noundef i32 @main() #0 {
  %1 = alloca i32, align 4
  %2 = alloca %struct.ll, align 8
  store i32 0, ptr %1, align 4
  %3 = call noalias noundef nonnull ptr @_Znwm(i64 noundef 16) #2
  %4 = getelementptr inbounds %struct.ll, ptr %2, i32 0, i32 1
  store ptr %3, ptr %4, align 8
  %5 = getelementptr inbounds %struct.ll, ptr %2, i32 0, i32 1
  %6 = load ptr, ptr %5, align 8
  %7 = getelementptr inbounds %struct.ll, ptr %6, i32 0, i32 0
  store i32 1, ptr %7, align 8
  ret i32 0
}

I believe in the bitcode, store ptr %3, ptr %4 and %4 = getelementptr inbounds %struct.ll, ptr %2, i32 0, i32 1 together is enough to infer %3 is also pointing to struct ll, but SVF does not seem to catch that.

@jumormt Could you kindly help me have a look at this issue? I'm a little confused even after single-stepping SVF.

@jumormt
Copy link
Contributor

jumormt commented Apr 22, 2024

Thanks for reporting. Should be fixed via PR #1443. Actually the type inference site for %3 should be %7 = getelementptr inbounds %struct.ll, ptr %6, i32 0, i32 0 because %6 and %3 are aliases.

yuleisui added a commit that referenced this issue Apr 22, 2024
add typeinference pattern: alloc->gep->store->gep->load (issue #1442)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants