rems-project / cerberus

Cerberus C semantics
https://www.cl.cam.ac.uk/~pes20/cerberus/
Other
39 stars 18 forks source link

[CN] Difficult to work with multiple multidimensional arrays that share indices #357

Open peterohanley opened 1 week ago

peterohanley commented 1 week ago

This may just be working as intended but it seems surprising. These functions process arrays and access them in the same way, and each works fine isolated but if they're in the same loop body it doesn't work. I thought this should work because the extracts are given different types so they could not interact.

#include <stdint.h>

extern uint8_t three[2][2][2];

void handle_three(void)
/*@
    accesses three;
@*/
{
    for (int c = 0; c < 2; ++c)
    /*@ inv c >= 0i32; c <= 2i32;
    @*/
    {
        for (int s = 0; s < 2; ++s)
        /*@ inv s >= 0i32; s <= 2i32;
            c < 2i32;
            c >= 0i32;
         @*/
        {
            /*@ extract Owned<uint8_t[2][2]>, (u64)c; @*/
            /*@ extract Owned<uint8_t[2]>, (u64)s; @*/
            /*@ extract Owned<uint8_t>, 0u64; @*/
            /*@ extract Owned<uint8_t>, 1u64; @*/

            three[c][s][0] = 0;
            three[c][s][1] = 0;
        }
    }
}

extern uint8_t two[2][2];

void handle_two(void)
/*@
    accesses two;
@*/
{
    for (int c = 0; c < 2; ++c)
    /*@ inv c >= 0i32; c <= 2i32;
     @*/
    {
        for (int s = 0; s < 2; ++s)
        /*@ inv s >= 0i32; s <= 2i32;
                c < 2i32;
                c >= 0i32;
        @*/
        {
            /*@ extract Owned<uint8_t[2]>, (u64)c; @*/
            /*@ extract Owned<uint8_t>, (u64)s; @*/

            two[c][s] = 0;
        }
    }
}
void handle_both(void)
/*@
    accesses two;
    accesses three;
@*/
{
    for (int c = 0; c < 2; ++c)
    /*@ inv c >= 0i32; c <= 2i32;
    @*/
    {
        for (int s = 0; s < 2; ++s)
        /*@ inv s >= 0i32; s <= 2i32;
            c < 2i32;
            c >= 0i32;
         @*/
        {
            // either block is ok by itself but if both are in it fails
            /*@ extract Owned<uint8_t[2]>, (u64)c; @*/
            /*@ extract Owned<uint8_t>, (u64)s; @*/
            two[c][s] = 0;

            /*@ extract Owned<uint8_t[2][2]>, (u64)c; @*/
            /*@ extract Owned<uint8_t[2]>, (u64)s; @*/
            /*@ extract Owned<uint8_t>, 0u64; @*/
            /*@ extract Owned<uint8_t>, 1u64; @*/
            three[c][s][0] = 0;
            three[c][s][1] = 0;
        }
    }
}
dc-mak commented 6 days ago

Potentially related: https://github.com/rems-project/cerberus/issues/320