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

[CN] require closed enums / expose enum validity as a predicate (feature request) #796

Open
septract opened this issue Dec 27, 2024 · 0 comments
Labels
cn enhancement New feature or request

Comments

@septract
Copy link
Collaborator

In C, enums are not closed - an enum is more or less just an alias for an integer type large enough to hold all enumerated values. However, in most cases I would guess we want to enforce closedness. It'd be nice for CN to either:

  1. Implicitly enforce closedness, or
  2. Add a predicate which enforces this property.

Current State

The function enum_test() is not statically safe in arbitrary calling contexts, and CN correctly complains if we try to verify it:

#include <stdbool.h>

enum my_enum {
  CASE1, 
  CASE2, 
}; 

void enum_test(enum my_enum in)
{
  switch (in) {
    case CASE1: 
      return;
    case CASE2: 
      return; 
    default: 
      assert(false); // Reachable, generates an error
  }
}

To solve this in CN as it is today, we need to write a predicate that enforces the enumeration is in bounds, and then thread this predicate wherever we need it in the program. This generates boilerplate and honestly is a bit confusing given this property seems 'obvious'. For example, here is one I wrote for the MKM code:

/*@ 
function (boolean) ValidState (u32 state) {
   ((state == (u32) CS_RECV_KEY_ID) || 
    (state == (u32) CS_SEND_CHALLENGE) || 
    (state == (u32) CS_RECV_RESPONSE) || 
    (state == (u32) CS_SEND_KEY) || 
    (state == (u32) CS_DONE) )
}
@*/ 

Proposal

Since this predicate is totally schematic, it might be nice to just define it automatically. We could either make it available to the programmer, or enforce it implicitly (with an escape hatch for when we want to break the enum discipline).

... 
void enum_test(enum my_enum in)
/*@
requires 
  enum_valid(in); 
@*/
{
  switch (in) {
    case CASE1: 
...
@septract septract added enhancement New feature or request cn labels Dec 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cn enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant