Skip to content
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

Bool/Int coercion for C is incomplete #1187

Open
ArmborstL opened this issue Apr 18, 2024 · 3 comments
Open

Bool/Int coercion for C is incomplete #1187

ArmborstL opened this issue Apr 18, 2024 · 3 comments
Labels
A-Enh Enhancement F-C Frontend: C

Comments

@ArmborstL
Copy link
Contributor

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?

@ArmborstL ArmborstL added the F-C Frontend: C label Apr 18, 2024
@ArmborstL
Copy link
Contributor Author

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.

@ArmborstL
Copy link
Contributor Author

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

turns the 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 😕

@sakehl
Copy link
Contributor

sakehl commented Apr 25, 2024

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?

@pieter-bos pieter-bos added the A-Enh Enhancement label Jul 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Enh Enhancement F-C Frontend: C
Projects
None yet
Development

No branches or pull requests

3 participants