Bool/Int coercion for C is incomplete
Opened this issue · 3 comments
The PR #1170 started implementing a coercion between boolean and integer values in C, since booleans are a type of integer there. It works for simple examples like https://github.com/utwente-fmt/vercors/blob/9b74fd74a18ad232784329ba78fab55d623a1511/examples/technical/intBoolCoercion.c. But for the program below, it still fails on the comparison:
//@ ensures 0 <= \result ;
_Bool __VERIFIER_nondet_bool();
To type-check the AmbiguousLessEq
operation, the CoercingRewriter
tries to convert both sides to int
. Here, \result
has the type CPrimitiveType
, which wraps a TBool
. So I tried extending the coercion to this specific combination of types.
However, it seems that at some point in the process, the node is assigned the simple type TBool
. Afterwards, a NopCoercingRewriter tries to cast this TBool
into an int
, and fails.
I'm not sure what the solution here is. I think if we simply allow coercing TBool
to int
, then this would also enable the coercion in non-C cases, which we probably don't want. But how do we recognise for a specific case that we are working in C and should allow this coercion?
Another option is to have _Bool
be a TCInt
rather than a TBool
. Given that PR #1170 allows coercion from int to boolean, this should not cause too many problems, right? It would be closer to the C semantics, but probably further from the user's intentions.
this should not cause too many problems, right?
So I tried it, and the CI fails in a few cases, e.g. https://github.com/utwente-fmt/vercors/actions/runs/8803794962/job/24163164935. It seems that coercing the boolean expression of the return
statement into _Bool
fails. I think it's because this
TCInt
into TInt
, preventing any further coercion to/from TBool
. I'm not sure why this coercion is done, maybe @sakehl can explain it. For now, I'm not sure whether having _Bool
be a TCInt
is worth it, or whether it breaks more than it fixes 😕A few thought
But how do we recognise for a specific case that we are working in C and should allow this coercion?
This is exactly why I introduced TCInt. So we recognize when we come from a C program, and we want C like coercions between types.
So you could make the type TCBool if you want.
The file CFloatIntCoercion.scala
removes all 'C' types here, and adds the specific cast needed (only cast between integer types and floats here).
So if you want to coerce from TCInt to TBool, that is fine. But then you need to add the explicit cast. Probably with
CoerceCIntBool()? Or something?
Does that help?