CPROVER Manual TOC

## The CPROVER Source Code Reference

The following sections provide an introduction for anybody who wishes to modify CBMC or build new tools on top of the APIs used by CBMC. They summarize key components, data structures and APIs that are used to build the CPROVER tools.

### Source Code Availability and Compilation

The most recent source code of CBMC and the CPROVER infrastructure can be obtained via git at https://github.com/diffblue/cbmc.git. Tar balls for releases are available at https://github.com/diffblue/cbmc/releases.

Detailed instructions on how to build CBMC from source are given in the file COMPILING.

### Components

From C source code file to CPROVER's IR

The sources of the C frontend are located in the "src/ansi-c" directory. It uses a standard Flex/Bison setup for scanning and parsing the files. The Flex scanner produces a token sequence, which is turned into a tree representation of the input program using the Bison grammar. The typechecker subsequently annotates this parse tree with types and generates a symbol table. The symbol table is a map from identifiers (functions, variables and types) to their definitions.

The following example illustrates how to use the frontend for parsing files and for translating them into a symbol table. A call to parse generates the parse tree of the program. The conversion into the symbol table is performed during type checking, which is done by a call to the typecheck method. The symbol table is a map from identifiers to the symbolt data structure.

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>

    #include <ansi-c/ansi_c_language.h>
    #include <util/cmdline.h>
    #include <util/config.h>

    int main(int argc, const char* argv[])
    {
       // Command line: parse  -I incl_dir file1 ...
       cmdlinet cmdl;
       cmdl.parse(argc, argv, "I:");

       config.init();

       if(cmdl.isset('I'))
         config.ansi_c.include_paths=cmdl.get_values('I');

       // Set language to C
       std::auto_ptr<languaget> clang=new_ansi_c_language();

       // Symbol table
       symbol_tablet my_symbol_table;

       for(const auto & arg : cmdl.args)
       {
         // Source code stream
         std::ifstream in(arg.c_str());

         // Parse
         clang->parse(in, "", std::cerr);

         // Typecheck
         clang->typecheck(my_symbol_table, arg, std::cerr);
      }

      // Do some final adjustements
      clang->final(my_symbol_table, std::cerr);

      my_symbol_table.show(std::cout);

      return 0;
    }

The parse trees are implemented using a class called irept. Its declaration and definiton can be found in the files "src/util/irep.h" and "src/util/irep.cpp", respectively.

The excerpt below gives some details of the class irept:

    class irept
    {
    public:
      typedef std::vector subt;
      typedef std::map named_subt;
      ...

    public:
      class dt
      {
      public:
        unsigned ref_count;
        dstring data;
        named_subt named_sub;
        named_subt comments;
        subt sub;
        ...
      };

    protected:
      dt *data;
      ...
    };

Every node of any tree is an object of class irept. Each node has a pointer to an object of class dt. The dt objects are used for storing the actual content of nodes. Objects of class dt are dynamically allocated and can be shared between nodes. A reference-counter mechanism is implemented to automatically free unreachable dt objects. A shallow copy of a tree is an O(1) operation.

The field data of class dt is a (hashed) string representing the label of the nodes. The fields named_sub, comments and sub are links to childs. Edges are either labeled with a string or ordered. The string-labeled edges are stored in the map comments if their first character is '#'. Otherwise, they are stored in the map named_sub. The labels of edges are unique for a given node; however, their ordering is not preserved. The field sub is a vector of nodes that is used for storing the ordered children. The order of edges of this kind is preserved during copy.

Tree for the expression a+b with int a; char b;.

#### Interface of Class irept

##### id

    const irep_idt &id();
    void id(const irep_idt &_data);

The first method returns a constant reference to the label of the node. The second method sets the label of the node.

##### is_nil and is_not_nil

    virtual bool is_nil() const;
    virtual bool is_not_nil() const;

The first method returns true if the label of the node is equal to "nil". The second method returns false if the label of the node is equal to "nil".

##### find, add and get

    const irept &find(const irep_namet &name) const;
    irept &add(const irep_namet &name);
    const irep_idt &get(const irep_namet &name) const;

1. The first method looks for an edge with label name and returns the corresponding child. If no edge with label name is found, then nil_rep is returned.
2. The second method does the same as the first except that if no edge with label name if found, then a new child is created and returned.
3. The third method does the same as the first except that the label of the child is returned (instead of a reference). If no edge with label name is found, then an empty string is returned.

##### set

    void set(const irep_namet &name,
             const irep_idt &value);
    void set(const irep_namet &name, const long value);
    void set(const irep_namet &name, const irept &irep);

These methods create a new edge with label name.

If the second argument is an object of class irept, then it is assigned to the new child.

If the second argument is a string, then it is set as node-label of the new child.

If the second argument is a number, then it is converted to a string and set as node-label of the new child.

##### remove

    void remove(const irep_namet &name);

This method looks for an edge with label name and removes it.

##### move_to_sub and move_to_named_sub

    void move_to_sub(irept &irep);
    void move_to_named_sub(const irep_namet &name, irept &irep);

The first method creates a new ordered edge with a child equal to irep. Then it sets irep to nil. The index of the edge is equal to the size of vector sub before the call.

The second method does the same but for labeled edges.

##### swap

    void swap(irept &irep);

Exchange the content of the invoked node with the one of irep.

##### make_nil

    void make_nil();

Set the label of the node to "nil" and remove all outgoing edges.

##### get_sub and get_named_sub and get_comments

    const subt &get_sub();
    const named_subt &get_named_sub();
    const named_subt &get_comments();

Return a constant reference to sub, named_sub, and comments, respectively.

### Types

The class typet inherits from irept. Types may have subtypes. This is modeled with two edges named "subtype" and "subtypes". The class typet only add specialized methods for accessing the subtype information to the interface of irept.

#### Interface of class typet

##### has_subtype and has_subtypes

    bool has_subtype() const;
    bool has_subtypes() const;

The first method returns true if the a subtype node exists. is not nil. The second method returns true is a subtypes node exists.

##### subtype and subtypes

    typet &subtype();
    typest &subtypes();

The first method returns a reference to the 'subtype' node. The second method returns a reference to the vector of subtypes.

#### Subtypes of typet

A number of subtypes of `typet` exist which allow convenient creation and manipulation of `typet` objects for special types.

Class | Description
--- | ---
`bool_typet` | Boolean type
`symbol_typet` | Symbol type. Has edge "identifier" to a string value, which can be accessed with `get_identifier` and `set_identifier`.
`struct_typet`, `union_typet` | Represent a struct, resp. union types. Convenience functions to access components `components()`.
`code_typet` | The type of a function/procedure. Convenience functions to access `arguments()` and `return_type()`.
`array_typet` | Convenience function `size()` to access size of the array.
`pointer_typet` | Pointer type, subtype stores the type of the object pointed to.
`reference_typet` | Represents a reference type, subtype stores the type of the object referenced to.
`bv_typet` | Represents a bit vector type with variable width.
`fixed_bv_typet` | Represents a bit vector that encodes a fixed-point number.
`floatbv_typet` | Represents a bit vector that encodes a floating-point number.
`string_typet` | Represents a string type.

### Source Locations

The class source_locationt inherits from the class irept. It is used to store locations in text files. It adds specialized methods to manipulate the edges named "file", "line", "column", "function".

### Expressions

The class exprt inherits from class irept. Expressions have operands and a type. This is modeled with ordered edges for the operands and an edge labeled"type", respectively. The class exprt only adds specialized methods for accessing operands and type information to the interface of irept.

Representation of a binary expression

#### Interface of class exprt

##### constructors

    explicit exprt(const irep_idt &id);

Creates an exprt object with a given label and no type.

    exprt(const irep_idt &id, const typet &type);

Creates an exprt object with a given label and type.

##### type

    const typet &type() const;
    typet &type();

Return a reference to the 'type' node

##### has_operands

    bool has_operands() const;

Return true if the expression has at least one operand.

##### operands

    const operandst &operands() const;

Return a reference to the vector of operands.

    const exprt &op0();
    const exprt &op1();
    const exprt &op2();
    const exprt &op3();
    exprt &op0();
    exprt &op1();
    exprt &op2();
    exprt &op3();

Return a reference to a specific operand. Avoid calling if the operand does not exist.

##### Constructing common expressions

    void make_true();
    void make_false();
    void make_bool(bool value);

Turn the current exprt instance into a expression of type "bool" with label "constant" and a single edge labeled "value", which points to a new node with label either "true" or "false".

    void make_typecast(const typet &_type);

Turns the current exprt instance into a typecast. The old value of the instance is appended as the single operand of the typecast, i.e., the result is a typecast-expression of the old expression to the indicated type.

    void make_not();

Turns the current exprt instance into an expression with label "not" of the same type as the original expression. The old value of the instance is appended as the operand of the "not"-node. If the original expression is of type "bool", the result represents the negation of the original expression with the following simplifications possibly applied:

- ¬ ¬ f = f
- ¬ true = false
- ¬ false = true

    void negate();

Turns the current exprt instance into a negation of itself, depending on its type:

- For boolean expressions, `make_not` is called.
- For integers, the current instance is turned into a numeric negation expression "unary-" of its old value. Chains of "unary-" nodes and negations of integer constants are simplified.
- For all other types, `irept::make_nil` is called.

    bool sum(const exprt &expr);
    bool mul(const exprt &expr);
    bool subtract(const exprt &expr);

Expect the "this" object and the function argument to be constants of the same numeric type. Turn the current `exprt` instance into a constant expression of the same type, whose "value" edge points to the result of the sum, product, or difference of the two expressions. If the operation fails for some reason (e.g., the types are different), `true` is returned.

##### Testing common expressions

    bool is_constant() const;

Returns true if the expression label is "constant".

    bool is_boolean() const;

Returns true if the label of the type is "bool".

    bool is_false() const;
    bool is_true() const;

The first function returns true if the expression is a boolean constant with value "false". The second function returns true for any boolean constant that is not of value "false".

    bool is_zero() const;
    bool is_one() const;

The first function returns true if the expression represents a zero numeric constant, or if the expression represents a null pointer. The second function returns true if the expression represents a numeric constant with value "1".

#### Subtypes of exprt

A number of subtypes of `exprt` provide further convenience functions for edge access or other specialized behaviour:

Class | Description
--- | ---
`transt` | Represents an SMV-style transition system with invariants `invar()`, initial state `init()` and transition function `trans()`.
`true_exprt` | Boolean constant true expression.
`false_exprt` | Boolean constant false expression.
`symbol_exprt` | Represents a symbol (e.g., a variable occurrence), convenience function for manipulating "identifier"-edge `set_identifier` and `get_identifier`
`predicate_exprt` | Convenience constructors to create expressions of type "bool".
`binary_relation_exprt : predicate_exprt` | Convenience functions to create and manipulate binary expressions of type "bool".
`equality_exprt : binary_relation_exprt` | Convenience functions to create and manipulate equality expressions such as "a == b".
`ieee_float_equal_exprt : binary_relation_exprt` | Convenience functions to create and manipulate equality expressions between floating-point numbers.
`index_exprt` | Represents an array access expression such as "a[i]". Convenience functions `array()` and `index()` for accessing the array expressions and indexing expression.
`typecast_exprt` | Represents a cast to the type of the expression.
`and_exprt`, `implies_exprt`, `or_exprt`, `not_exprt` | Representations of logical operators with convenience constructors.
`address_of_exprt` | Representation of a C-style `&a` address-of operation. Convenience function `object()` for accessing operand.
`dereference_exprt` | Representation of a C-style `*a` pointer-dereference operation. Convenience function `object()` for accessing operand.
`if_exprt` | Representation of a conditional expresion, with convenience functions `cond()`, `true_case()` and `false_case()` for accessing operands.
`member_exprt` | Represents a `some_struct.some_field` member access.
`codet` | Represents a segment of code.

### Symbols and the Symbol Table

#### Symbol

A symbol is an object of class `symbolt`. This class is declared in "util/symbol.h". The code below shows a partial declaration of the interface:

    class symbolt
    {
    public:
      typet type;
      exprt value;
      std::string name;
      std::string base_name;
      ...
    };

Symbol names are unique. Scopes are handled by adding prefixes to symbols:

    int main(int argc, char* argv[]) {

    	               // Symbol name: c::main::0::alice
       char alice = 0;     // Symbol base: alice

       {
    	               // Symbol name: c::main::1::alice
           int alice = 0;  // Symbol base: alice
       }
    }

#### Symbol Table

A symbol table is an object of class `contextt`. This class is declared in "util/context.h". The code below shows a partial declaration of the interface:

    class symbol_tablett
    {
    public:
                                     // Insert the symbol
      bool add(const symbolt &symb);
                                     // Insert symb into the
                                     // table and erase it.
                                     // New_symbol points to the
                                     // newly inserted element.
      bool move(symbolt &symbol, symbolt *&new_symbol);

                                     // Insert symb into the
                                     // table. Then symb is erased.
      bool move(symbolt &symb);

                                     // Return the entry of the
                                     // symbol with given name.
      const irept &value(const std::string &name) const;
    };

## Goto Programs

Goto programs are a representation of the control flow graph of a program that uses only guarded goto and assume statements to model non-sequential flow. The main definition can be found in "src/goto-programs/goto_program_template.h", which is a template class. The concrete instantiation of the template that is used in the framework can be found in "src/goto-programs/goto_program.h". A single instruction in a goto program is represented by the class goto_programt::instructiont whose definition can be found again in "goto-programs/goto_program_template.h".

In the class `goto_programt`, the control flow graph is represented as a mixture of sequential transitions between nodes, and non-sequential transitions at goto-nodes. The sequential flow of the program is captured by the list `instructions` that is a field of the class `goto_programt`. Transitions via goto statements are represented in the list `targets`, which is a field of the class `goto_programt::instructiont`, i.e., each goto-instruction carries a list of possible jump destinations. The latter list `targets` is a list of iterators which point to elements of the list `instructions`. An illustration is given in the figure below.

Representation of program flow in goto_programt

Instructions can have a number of different types as represented by `enum goto_program_instruction_typet` and can be accessed via the field `type` in `instructiont`. These include:

`GOTO` | Represents a non-deterministic branch to the instructions given in the list `targets`. Goto statements are guarded, i.e., the non-deterministic branch is only taken if the expression in `guard` evaluates to true, otherwise the program continues sequentially. Guarded gotos can be used, for example, to model if statements. The guard is then set to the negated condition of the statement, and goto target is set to bypass the conditionally executed code if this guard evaluates to true.
`ASSUME` | An assumption statement that restricts viable paths reaching the instruction location to the ones that make the expression `guard` evaluate to true.
`ASSERT` | An assertion whose `guard` is checked for validity when the instruction is reached.
`RETURN` | A return statement in a function.
`END_FUNCTION` | Denotes the end of a function.
`ASSIGN` | A variable assignment.
`SKIP` | No operation.
`OTHER` | Any operation not covered by `enum goto_program_instruction_typet`.

A number of convenience functions in `instructiont`, such as `is_goto()`, `is_assume()`, etc., simplify type queries. The following code segment gives a partial interface declaration of `goto_program_template` and `instructiont`.

    template <class codeT, class guardT>
    class goto_program_templatet
    {
    public:
      //list of instruction type
      typedef std::list<class instructiont> instructionst;

      //a reference to an instruction in the list
      typedef typename
        std::list::iterator targett;

      //Sequential list of instructions,
      //representing sequential program flow
      instructionst instructions;

      typedef typename
        std::map target_numberst;

      //A map containing the unique number of each target
      target_numberst target_numbers;

      //Get the successors of a given instruction
      void get_successors(targett target, targetst &successors);

      ...

      class instructiont
      {
      public:
        codeT code;

        //identifier of enclosing function
        irep_idt function;

        //location in the source file
        locationt location;

        //type of instruction?
        goto_program_instruction_typet type;

        //Guard statement for gotos, assume, assert
        guardT guard;

        //targets for gotos
        targetst targets;

        //set of all predecessors (sequential, and gotos)
        std::set<targett> incoming_edges;

        // a globally unique number to identify a
        // program location. It is guaranteed to be
        // ordered in program order within one
        // goto_program
        unsigned location_number;

        // a globally unique number to identify loops
        unsigned loop_number;

        // true if this is a goto jumping back to an
        // earlier instruction in the sequential program
        // flow
        bool is_backwards_goto() const;
      };

    }