Skip to content

Inconsistent casting results for nested structures #6956

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

Closed
celinval opened this issue Jun 22, 2022 · 2 comments · Fixed by #6959
Closed

Inconsistent casting results for nested structures #6956

celinval opened this issue Jun 22, 2022 · 2 comments · Fixed by #6959
Labels
aws Bugs or features of importance to AWS CBMC users aws-high Kani Bugs or features of importance to Kani Rust Verifier pending merge

Comments

@celinval
Copy link
Collaborator

CBMC version: 5.59.0 (cbmc-5.59.0)
Operating system: Ubuntu 18.04
Exact command line resulting in the issue: cbmc casting.c
What behaviour did you expect: The test should succeed.
What happened instead: The property fn.assertion.2 fails.

For the following test case:

// casting.c
#include<assert.h>

struct PtrWrapperInner {
    int* value;
};

struct PtrWrapper {
    int* value;
    struct PtrWrapperInner inner;
};

struct AltPtrWrapperInner {
    int* value;
};

struct AltPtrWrapper {
    unsigned int* value;
    // A) Doesn't work
    struct AltPtrWrapperInner inner;
    // B) Works
    //struct PtrWrapperInner inner;
};


void fn(struct PtrWrapper wrapper) {
    assert(*wrapper.value == 10);
    assert(*wrapper.inner.value == 10);
}

int main() {
    int ret = 10;
    int* ptr = &ret;

    struct AltPtrWrapper alt;
    alt.inner.value = ptr;
    alt.value = ptr;

    // Casting the structure itself works.
    struct PtrWrapper wrapper = *(struct PtrWrapper*) &alt;
    assert(*wrapper.value == 10);
    assert(*wrapper.inner.value == 10);

    // This only works if there is one level of casting.
    int (*alias) (struct AltPtrWrapper) = (int (*) (struct AltPtrWrapper)) fn;
    alias(alt);
}

The casting between AltPtrWrapper and PtrWrapper is successful when done explicitly but not due to calling the function alias, it seems that CBMC is casting the outer structure members, but not the inner ones. Note that if the inner structures have the same type (by commenting A and uncommenting B), the test succeeds.

@danielsn danielsn added aws Bugs or features of importance to AWS CBMC users aws-high Kani Bugs or features of importance to Kani Rust Verifier labels Jun 22, 2022
tautschnig added a commit to tautschnig/cbmc that referenced this issue Jun 23, 2022
Only POD can be handled via type casts, all other cases require
reinterpreting the byte sequence. For POD, the simplifier will clean up
the byte extract.

The same problem had already been fixed for goto-symex' function
argument conversion back in bb80cdc.

Co-authored-by: Celina G. Val <[email protected]>

Fixes: diffblue#6956
@tautschnig
Copy link
Collaborator

Thank you for the nice reproducer! I've created #6959 to fix the issue.

tautschnig added a commit to tautschnig/cbmc that referenced this issue Jun 23, 2022
Only POD can be handled via type casts, all other cases require
reinterpreting the byte sequence. For POD, the simplifier will clean up
the byte extract.

The same problem had already been fixed for goto-symex' function
argument conversion back in bb80cdc.

Co-authored-by: Celina G. Val <[email protected]>

Fixes: diffblue#6956
@celinval
Copy link
Collaborator Author

That's amazing! Thank you for fixing this so fast.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws Bugs or features of importance to AWS CBMC users aws-high Kani Bugs or features of importance to Kani Rust Verifier pending merge
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants