corrode icon indicating copy to clipboard operation
corrode copied to clipboard

Functions may be translated with wrong environment

Open jameysharp opened this issue 7 years ago • 0 comments

Consider this program:

static int x;

static void f(void) {
    x = 1;
}

void g(void) {
    char *x;
    f();
}

Because f is static, Corrode defers translating it until it encounters the call from g. Because the translation was deferred, right now, it runs in the scope where the first call was encountered. That means that when it translates the assignment x = 1, Corrode believes that the type of x is char *, not int as it should be. The result is that f translates this way:

unsafe extern fn f() {
    x = 1i32 as (*mut u8);
}

Which is, of course, complete nonsense, and the Rust compiler sensibly reports "mismatched types" on the assignment. (This example also triggers issue #92 but this problem should be solved independently of that one.)

One way to solve this would be:

  1. get the EnvState value at the beginning of interpretFunction, so we have a reference to the right environment to use later.
  2. Inside the block that begins with mapExceptT (local setRetTy) $ scope $ do, reset the EnvState to the saved version. But this is a little tricky, because we must not reset the GlobalState that's inside the EnvState. So something like this should work:
lift (modify (\ current -> old { globalState = globalState current }))

Another way to solve this would do pretty much exactly the same thing, except you'd do it in runOnce instead of in interpretFunction, so that all deferred computations would be guaranteed to run in the environment as it stood at the time they were deferred. That's probably better.

jameysharp avatar Nov 16 '16 07:11 jameysharp