Skip to content

builtin type vs user type conflict #3081

Open
@xbauch

Description

@xbauch
//--------------------------------------------------------------------------------
//test.c
//--------------------------------------------------------------------------------
struct _IO_FILE;
struct _IO_marker;

struct _IO_FILE{
  int  Id_MCDC_2;
  char * Id_MCDC_3;
  char * Id_MCDC_4;
  char * Id_MCDC_5;
  char * Id_MCDC_6;
  char * Id_MCDC_7;
  char * Id_MCDC_8;
  char * Id_MCDC_9;
  char * Id_MCDC_10;
  char * Id_MCDC_11;
  char * Id_MCDC_12;
  char * Id_MCDC_13;
  struct _IO_marker* Id_MCDC_14;
  struct _IO_FILE* Id_MCDC_15;
  int  Id_MCDC_16;
  int  Id_MCDC_17;
  long Id_MCDC_18;
  unsigned short  Id_MCDC_19;
  signed char  Id_MCDC_20;
  char  Id_MCDC_21 [1];
  void* Id_MCDC_22;
  long long Id_MCDC_23;
  void * Id_MCDC_24;
  void * Id_MCDC_25;
  void * Id_MCDC_26;
  void * Id_MCDC_27;
  unsigned long int Id_MCDC_28;
   int  Id_MCDC_29;
  char  Id_MCDC_30 [20];
} ;

typedef struct _IO_FILE FILE;

extern FILE* fopen(char  const* filename, char const*mode);

int main()
{
  if (fopen("in.eds", "r") == ((void *)0));
  for (int i = 0; i < 2; i++);
}

CBMC version: cbmc-5.10-836-g273f375aa-dirty
Operating system: Ubuntu 18.04
Exact command line resulting in the issue: cbmc --unwinding-assertions --unwind 2 test.c
What behaviour did you expect: not to see invariant violation
What happened instead: invariants were violated

Problem analysis

  • The input code implements it's own version of fopen and FILE.
  • CBMC warns about redefining a symbol during linking, but does not stop
  • during flattening, CBMC converts the equality between return_value_fopen and fopen#return_value to bit-vectors
  • an invariant of this conversion is that both sides of the equation are of the same type
  • the lhs has the user-defined type FILE but the rhs has the builtin-defined type FILE
  • the two types (both structs) differ in the names of their components (not types)

Proposed solutions

  1. fail, by means of an exception, when user tries to redefine a builtin symbol
  2. accept user defined symbol and give it precedence over builtin
  3. override user defined symbol
  4. change base_type_eq check to ignore struct component's names

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions