Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open more actions menu

Repository files navigation

Note (unrelated to Psyche-C)
C language draft proposal: Enabling Generic Functions and Parametric Types in C (prototype).


Psyche-C

Psyche-C is a platform for implementing static analysis of C programs. At its core, it includes a C compiler frontend that performs both syntactic and semantic analysis. Yet, as opposed to actual C compilers, to provide accurate syntax (through disambiguation) analysis and partial semantic analysis in zero setup or broken build environments, Psyche-C doesn't rely on a symbol table during parsing. Despite this, it nevertheless provides full syntax and semantic analysis for complete source code.

Bellow are the main characteristics of Psyche-C:

  • Clean separation between the syntactic and semantic compiler phases.
  • Algorithmic and heuristic syntax disambiguation.
  • Optional type inference as a recovery mechanism from #include failures (not yet in master).
  • API inspired by that of the Roslyn .NET compiler and LLVM's Clang.

Driver

Psyche-C is written as a C++ library, but it comes with a builtin driver: cnippet. You can use it by passing to it either the typical command line arguments of an actual compiler or the actual compiler's whole invocation as a subcommand.

Example with cnippet only:

cnip -analysis /path/to/analysis.dylib -I/path/to/whatever file.c

Example with compiler's invocation as a subcommand:

cnip -analysis /path/to/analysis.dylib -- gcc -I/path/to/whatever file.c

See psychec-analysis for a trivial example of how to implement an analysis.

Type Inference

Psyche-C began as a type inference tool for C, aimed at enabling static analysis of incomplete programs. However, the compiler frontend at its core wasn't good enough, so I decided to rewrite it pretty much from scratch. I used this rewrite also as an opportunity to extend Psyche-C into a platform for static analysis in general. The result of this work is what exists today in the master branch, but that doesn't yet include a port of the type inference from the original branch. In that branch, if you "compile" the snippet below with cnippet, Psyche-C will infer T and synthesize a declaration for it as follows.

void f()
{
    T v = 0;
    v->value = 42;
    v->next = v;
}

Synthesized declaration for T.

typedef struct TYPE_2__ TYPE_1__;
struct TYPE_2__ 
{
    int value;
    struct TYPE_2__* next;
} ;
typedef TYPE_1__* T;

You might want to use this functionality to:

  • Enable, on incomplete programs, analyses that depend on complete programs.
  • Generate test-input/mocks to validate functions in isolation.
  • Prototype an algorithm while only sketching its data-structures
  • Compile a snippet for inspection of static properties of its object code.

Documentation and Resources

Building and Testing

To build:

cmake CMakeLists.txt && make -j 4

To run the tests:

./test-suite

Related Publications

Of Psyche-C itself:

That use Psyche-C:

Morty Proxy This is a proxified and sanitized view of the page, visit original site.