Skip to content

Treatment of local uninitialised variables in AutoCorres and C Parser #955

Description

@AntanasKal

While experimenting with AutoCorres we noticed something unexpected in the way the C Parser treats local uninitialised variables when translating to SIMPL. The concrete examples in AutoCorres and AutoCorres2 are bellow.

Example in AutoCorres 1.12

In this example we are using AutoCorres 1.12 with Isabelle2025 and L4V_ARCH=ARM environment variable. Consider the following function:

int bogus(void) {
    int x;
    if (x < 100) {
        return 0;
    } else {
        return 1;
    }
}

If we import this using AutoCorres, we see by inspecting bogus'_def that the abstracted definition of bogus function becomes:

bogus'do x___int <- unknown;
             return (if x___int < 100 then 0 else 1)
          od

Where unknown is a nondeterministic selector from all integers. As far as we understand, the function in C has undefined behaviour as the local variable x is not initialised and it is accessed in the if statement. Because of this, we would expect that we should not be able to reason about this program. However, with the abstracted definition above we can prove that the function returns 0 or 1:

theory Bogus
imports
  "AutoCorres.AutoCorres"
begin

external_file  "bogus.c"

install_C_file  "bogus.c"

thm Bogus.bogus_global_addresses.bogus_body_def

autocorres "bogus.c"

context bogus begin

thm bogus'_def

lemma bogus_res:
       "⦃ λs. True ⦄
           bogus'
        ⦃ λr _. r = 0 ∨ r = 1 ⦄!"
  apply (unfold bogus'_def)
  apply wp
  by meson

end

end

We can see that the result of translating C to SIMPL is this:

bogus_global_addresses.bogus_bodyTRY
  lvar_nondet_init x_' x_'_update;;
  IF ´x <s 0x64 THEN
    creturn global_exn_var_'_update ret__int_'_update (λs. 0)
  ELSE
    creturn global_exn_var_'_update ret__int_'_update (λs. 1)
  FI;;
  Guard DontReach {} SKIP
CATCH SKIP
END

x seems to be initialised as a nondeterministic variable. We would expect there to be some guards before IF statement that prevent branching on an uninitialised value.

Same example in AutoCorres2

We originally spotted this using AutoCorres2 as provided in AFP 2025-12-27 version and Isabelle 2025-1.

Abstracted definition of the function bogus:

bogus'do {
  xunknown;
  return (if x < 100 then 0 else 1)
}

Proof that it returns 0 or 1:

theory Bogus
imports
  "AutoCorres2_Main.AutoCorres_Main"
begin

install_C_file  "bogus.c"

thm bogus_body_def

autocorres "bogus.c"

thm bogus'_def

lemma bogus_res:
  "bogus' ∙ s ⦃ λRes r _. r = 0 ∨ r = 1 ⦄"
  unfolding bogus'_def
  by runs_to_vcg

end

Result of the translation to SIMPL:

bogus_bodyTRY
  lvar_nondet_init (λupd. bogus.ret':=⇩ℒ upd);;
  (lvar_nondet_init (λupd. bogus.x:=⇩ℒ upd);;
   IF ´bogus.x <s 0x64 THEN
     creturn global_exn_var'_'_update (λupd. bogus.ret':=⇩ℒ upd) (λs. 0)
   ELSE
     creturn global_exn_var'_'_update (λupd. bogus.ret':=⇩ℒ upd) (λs. 1)
   FI);;
  Guard DontReach {} SKIP
CATCH ccatchreturn global_exn_var'_'
END

Questions

We would like to ask:

  • Is this a known issue?
  • Are there some additional assumptions about the C semantics, target compilers, or architectures where such treatment of locals is valid?
  • Is there a way that the C Parser could be configured to add guards to disallow such UB?
  • Do you have a strategy for dealing with such programs?

One naive patch maybe could be to disallow declarations of locals without assigning value. E.g. forbidding statements like int x; but allowing int x = 0; in function bodies in the C subset of C Parser. Though we don't know if this could have some larger implications, e.g. while dealing with structs that are locals or regarding efficiency. For our use case we could perhaps circumvent this in a way by using some linter on the C source to detect such patterns.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions