Frama C User Manual
Frama C User Manual
Loïc Correnson, Pascal Cuoq, Florent Kirchner, André Maroneze, Virgile Prevosto,
Armand Puccetti, Julien Signoles and Boris Yakobowski
Foreword 6
1 Introduction 7
1.1 About this document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2 Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2 Overview 9
2.1 What is Frama-C? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Frama-C as a Code Analysis Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.1 Frama-C as a Lightweight Semantic-Extractor Tool . . . . . . . . . . . 10
2.2.2 Frama-C for Formal Verification of Critical Software . . . . . . . . . . . 10
2.3 Frama-C as a Tool for C programs . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4 Frama-C as an Extensible Platform . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5 Frama-C as a Collaborative Platform . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6 Frama-C as a Development Platform . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.7 Frama-C as an Educational Platform . . . . . . . . . . . . . . . . . . . . . . . . . 12
3 Getting Started 13
3.1 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2 One Framework, Several Executables . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3 Frama-C Command Line and General Options . . . . . . . . . . . . . . . . . . . . 14
3.3.1 Getting Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3.2 Frama-C Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3.3 Options Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3.4 Autocompletion for Options . . . . . . . . . . . . . . . . . . . . . . . . 16
3.3.5 Splitting a Frama-C Execution into Several Steps . . . . . . . . . . . . 16
3.3.6 Verbosity and Debugging Levels . . . . . . . . . . . . . . . . . . . . . . 17
3.3.7 Copying Output to Files . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3.8 Terminal Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3.9 Getting time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3.10 Inputs and Outputs of Source Code . . . . . . . . . . . . . . . . . . . . 18
2
CONTENTS
4 Setting Up Plug-ins 20
4.1 The Plug-in Taxonomy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.2 Installing External Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.3 Loading Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
6 ACSL extensions 31
6.1 Handling indirect calls with calls . . . . . . . . . . . . . . . . . . . . . . . . . . 31
8 Property Statuses 36
8.1 A Short Detour through Annotations . . . . . . . . . . . . . . . . . . . . . . . . . 36
8.2 Properties, and the Statuses Thereof . . . . . . . . . . . . . . . . . . . . . . . . . 36
8.3 Consolidating Property Statuses . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3
CONTENTS
11 Reports 45
11.1 Reporting on Property Statuses . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
11.2 Exporting to CSV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
11.3 Classification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
11.3.1 Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
11.3.2 Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
11.3.3 Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
11.3.4 Reformulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
11.3.5 JSON Output Format . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
11.3.6 Classification Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
11.4 SARIF Output via the Markdown Report Plug-in . . . . . . . . . . . . . . . . . . 49
11.4.1 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
11.4.2 Generating a SARIF Report . . . . . . . . . . . . . . . . . . . . . . . . 49
12 Variadic Plug-in 50
12.1 Translating variadic function calls . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
12.2 Automatic generation of specifications for libc functions . . . . . . . . . . . . . . 51
12.3 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
12.3.1 Main options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
12.3.2 Similar diagnostics by other tools . . . . . . . . . . . . . . . . . . . . . 51
12.3.3 Common causes of warnings in formatted input/output functions . . . 52
12.3.4 Pretty-printing translated code . . . . . . . . . . . . . . . . . . . . . . 52
13 Analysis Scripts 53
13.1 Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
13.2 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
13.2.1 General Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
13.2.2 Necessary Build Information . . . . . . . . . . . . . . . . . . . . . . . . 54
13.2.3 Possible Workflows in the Absence of Build Information . . . . . . . . 54
13.2.4 Using a JSON Compilation Database (JCDB) . . . . . . . . . . . . . . 55
13.3 Using the generated Makefile, via fcmake . . . . . . . . . . . . . . . . . . . . . . 55
13.3.1 Important Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
13.3.2 Predefined targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
13.3.3 Adding new analyses and stages . . . . . . . . . . . . . . . . . . . . . . 58
4
CONTENTS
14 Compliance 61
14.1 Unsupported C99 and C11 Features . . . . . . . . . . . . . . . . . . . . . . . . . 61
14.2 Frama-C Options Related to C Undefined Behaviors . . . . . . . . . . . . . . . . 62
14.3 RTE categories and C Undefined Behaviors . . . . . . . . . . . . . . . . . . . . . 63
14.4 C Undefined Behaviors not handled by Frama-C . . . . . . . . . . . . . . . . . . . 64
14.5 Common Weakness Enumerations (CWEs) Reported and not Reported by Frama-C 64
15 Reporting Errors 71
A Changes 74
Bibliography 79
List of Figures 81
Index 82
5
Foreword
This is the user manual of Frama-C1 . The content of this document corresponds to the version 28.1
(Nickel), released on March 1, 2024, of Frama-C.
Acknowledgements
We gratefully thank all the people who contributed to this document: Patrick Baudin, Mickaël Delahaye,
Philippe Hermann, Benjamin Monate and Dillon Pariente.
This project has received funding from the French ANR projects CAT (ANR-05-RNTL-00301)
and U3CAT (08-SEGI-021-01) .
This project has received funding from the European Union’s Seventh Framework Programme
(FP7/2007-2013) under grant agreement N◦ 317753 (STANCE).
It has also received funding from the Horizon 2020 research and innovation programme, under
grant agreements N◦ 731453 (VESSEDIA), N◦ 824231 (DECODER), N◦ 830892 (SPARTA),
and N◦ 883242 (ENSURESEC) .
1 http://frama-c.com
6
Introduction 1
This is Frama-C’s user manual. Frama-C is an open-source platform dedicated to the analysis of source
code written in the C programming language. The Frama-C platform gathers several analysis techniques
into a single collaborative framework.
This manual gives an overview of Frama-C for newcomers, and serves as a reference for expert users.
It only describes those platform features that are common to all analyzers. Thus it does not cover
the use of the analyzers provided in the Frama-C distribution (Eva, WP, E-ACSL, . . . ). Each of these
analyses has its own specific documentation [7, 10, 16]. Furthermore, research papers [9, 12] give a
synthetic view of the platform, its main and composite analyses, and some of its industrial achievements,
while the development of new analyzers is described in the Plug-in Development Guide [15].
Appendix A references all the changes made to this document between successive Frama-C releases.
In the index, page numbers written in bold italics (e.g. 1 ) reference the defining sections for the
corresponding entries while other numbers (e.g. 1) are less important references.
The most important paragraphs are displayed inside orange boxes like this one. A plug-in developer
must follow them very carefully.
1.2 Outline
Chapter 3 describes the basic elements for starting the tool, in terms of installation and commands.
Chapter 4 explains the basics of plug-in categories, installation, and usage.
Chapter 5 presents the options of the source code preprocessor.
Chapter 7 gives some general options for parameterizing analyzers.
Chapter 8 touches on the topic of code properties, and their validation by the platform.
Chapter 9 introduces the general services offered by the platform.
Chapter 10 gives a detailed description of the graphical user interface of Frama-C.
7
1.2. OUTLINE
Chapter 11 describes the Report plug-in, used for textual consolidation and export of warnings,
errors and properties.
Chapter 12 presents the Variadic plug-in, used to help other plug-ins handle code containing variadic
functions, such as printf and scanf.
Chapter 13 details several scripts used to help setup and run analyses on large code bases.
Chapter 14 contains information related to compliance to standards and coding guidelines (ISO C,
CERT, CWEs, etc).
Chapter 15 explains how to report errors via Frama-C’s public Gitlab repository.
8
Overview 2
2.1 What is Frama-C?
Frama-C is a platform dedicated to the analysis of source code written in C. The Frama-C platform
gathers several analysis techniques into a single collaborative extensible framework. The collaborative
approach of Frama-C allows analyzers to build upon the results already computed by other analyzers in
the framework. Thanks to this approach, Frama-C can provide a number of sophisticated tools such as a
concurrency safety analysis (Mthread [17]), an enforcer of secure information flow (SecureFlow [1, 2]), or
a set of tools for various test coverage criteria (LTest [13]), among many others.
Static analysis of source code is the science of computing synthetic information about the source code
without executing it.
To most programmers, static analysis means measuring the source code with respect to various metrics
(examples are the number of comments per line of code and the depth of nested control structures). This
kind of syntactic analysis can be implemented in Frama-C but it is not the focus of the project.
Others may be familiar with heuristic bug-finding tools. These tools take more of an in-depth look at
the source code and try to pinpoint dangerous constructions and likely bugs (locations in the code where
an error might happen at run-time). These heuristic tools do not find all such bugs, and sometimes they
alert the user for constructions which are in fact not bugs.
Frama-C is closer to these heuristic tools than it is to software metrics tools, but it has two important
differences with them: it aims at being correct, that is, never to remain silent for a location in the
source code where an error can happen at run-time. And it allows its user to manipulate functional
specifications, and to prove that the source code satisfies these specifications.
Frama-C is not the only correct code analyzer out there, but analyzers of the correct family are less
widely known and used. Software metrics tools do not guarantee anything about the behavior of the
program, only about the way it is written. Heuristic bug-finding tools can be very useful, but because
they do not find all bugs, they can not be used to prove the absence of bugs in a program. Frama-C
on the other hand can guarantee that there are no bugs in a program ("no bugs" meaning either no
possibility of a run-time error, or even no deviation from the functional specification the program is
supposed to adhere to). This of course requires more work from the user than heuristic bug-finding
tools usually do, but some of the analyses provided by Frama-C require comparatively little intervention
from the user, and the collaborative approach proposed in Frama-C allows the user to get results about
complex semantic properties.
Frama-C also provides some dynamic analysis, via plug-ins such as E-ACSL [16], which performs
runtime verification. It is often used as a complement to static analysis: when some properties cannot
be proven statically, E-ACSL instruments the code so that, during execution, such properties are verified
9
2.3. FRAMA-C AS A TOOL FOR C PROGRAMS
and enforced: violations lead to alerts or immediate termination, preventing silent program corruption
or malicious infiltration, and helping pinpoint the exact cause of a problem, instead of an indirect
consequence much later.
For both static and dynamic analyses, Frama-C focuses on the source code. Plug-ins can help translate
higher-level properties and specifications, or even provide front-ends to other languages; but, in the end,
the strength of the platform is centered around the code and its properties.
The C source code analyzed by Frama-C is assumed to follow the C99 ISO standard1 . C comments may
contain ACSL annotations [3] used as specifications to be interpreted by Frama-C. The subset of ACSL
currently interpreted in Frama-C is described in [4].
Each analyzer may define the subsets of C and ACSL that it understands, as well as introduce specific
limitations and hypotheses. Please refer to each plug-in’s documentation.
Frama-C is organized into a modular architecture (comparable to that of the Eclipse IDE): each analyzer
comes in the form of a plug-in and is connected to the platform itself, or kernel, which provides common
functionalities and collaborative data structures.
Several ready-to-use analyses are included in the Frama-C distribution. This manual covers the set
of features common to all plug-ins, plus some plug-ins which are used by several others, such as the
1 Some parts of the C11 standard, as well as some common GCC extensions, are also supported.
10
2.5. FRAMA-C AS A COLLABORATIVE PLATFORM
graphical user interface (GUI) and reporting tools (Report). It does not cover use of the plug-ins that
come in the Frama-C distribution: value analysis (Eva), functional verification (WP), runtime verification
(E-ACSL), etc. Each of these analyses has its own specific documentation [10, 7, 16].
Additional plug-ins can be provided by third-party developers and installed separately from the
kernel. Frama-C is thus not limited to the set of analyses initially installed. For instance, it may be
extended with the Frama-Clang plug-in [6], which provides an experimental front-end for C++ code; or
MetAcsl [14], which allows specifying higher-level meta-properties; among others.
Frama-C’s analyzers collaborate with each other. Each plug-in may interact with other plug-ins of his
choosing. The kernel centralizes information and conducts the analysis. This makes for robustness in the
development of Frama-C while allowing a wide functionality spectrum. For instance, the Slicing plug-in
uses the results of the Eva (value analysis) plug-in and of the From (functional dependencies) plug-in.
Analyzers may also exchange information through ACSL annotations [3]. A plug-in that needs to
make an assumption about the behavior of the program may express this assumption as an ACSL
property. Because ACSL is the lingua franca of all plug-ins, another plug-in can later be used to establish
the property.
With Frama-C, it is possible to take advantage of the complementarity of existing analysis approaches.
It is possible to apply the most sophisticated techniques only on those parts of the analyzed program that
require them. The low-level constructs can for instance effectively be hidden from them by high-level
specifications, verified by other, adapted plug-ins. Note that the sound collaboration of plug-ins on
different parts of a same program that require different modelizations of C is a work in progress. At this
time, a safe restriction for using plug-in collaboration is to limit the analyzed program and annotations
to those C and ACSL constructs that are understood by all involved plug-ins.
Frama-C may be used for developing new analyses. The collaborative and extensible approach of Frama-C
allows powerful plug-ins to be written with relatively little effort.
There are a number of reasons for a user of Frama-C to be also interested in writing their own plug-in:
– a custom plug-in can emit very specific queries for the existing plug-ins, and in this way obtain
information which is not easily available through the normal user interface;
– a custom plug-in has more flexibility for finely tuning the behavior of the existing analyses;
– some analyses may offer specific opportunities for extension.
If you are a researcher in the field of program analysis, using Frama-C as a testbed for your ideas is a
choice to consider. You may benefit from the ready-made parser for C programs with ACSL annotations.
The results of existing analyses may simplify the problems that are orthogonal to those you want
to consider (in particular, the value analysis provides sets of possible targets of every pointer in the
analyzed C program). And lastly, being available as a Frama-C plug-in increases your work’s visibility
among existing industrial users of Frama-C. The development of new plug-ins is described in the Plug-in
Development Guide [15].
11
2.7. FRAMA-C AS AN EDUCATIONAL PLATFORM
Frama-C is being used as part of courses on formal verification, program specification, testing, static anal-
ysis, and abstract interpretation, with audiences ranging from Master’s students to active professionals,
in institutions world-wide. Frama-C is part of the curriculum at several universities in France, England,
Germany, Portugal, Russia and in the US; at schools such as Ecole Polytechnique, ENSIIE, ENSMA, or
ENSI Bourges; and as part of continuing education units at CNAM, or at Fraunhofer FOKUS.
If you are a teacher in the extended field of software safety, using Frama-C as a support for your
course and lab work is a choice to consider. You may benefit from a clean, focused interface, a choice of
techniques to illustrate, and a in-tool pedagogical presentation of their abstract values at all program
points. A number of course materials are also available on the web, or upon simple inquiry to the
Frama-C team.
12
Getting Started 3
This chapter describes how to install Frama-C and what this installation provides.
3.1 Installation
The Frama-C platform is distributed as source code, including the Frama-C kernel and a base set of
open-source plug-ins.
The recommended way to install Frama-C is by using the opam 1 package manager to install the
frama-c package, which should always point to the latest release compatible with the configured
OCaml compiler. opam is able to handle the dependencies required by the Frama-C kernel.
Frama-C can also be installed via pre-compiled binaries, which include many of the required libraries
and other dependencies, although there is a delay between each new Frama-C release and the availability
of a binary package for the considered platform.
Finally, Frama-C can be compiled and installed from the source distribution, as long as its dependencies
have already been installed. The exact set of dependencies varies from release to release. They are listed
as constraints in the opam file of the source distribution.
A reference configuration, guaranteed to be a working set of dependencies for Frama-C
kernel and the open-source plug-ins included in the source distribution, is available in the
reference-configuration.md file of the source distribution.
For more installation instructions, consider reading the INSTALL.md file of the source distribution.
The main components necessary for compiling and running Frama-C are described below.
A C preprocessor is required for using Frama-C on C files. If you do not have any C preprocessor,
you can only run Frama-C on already preprocessed .i files.
A C compiler is required to compile the Frama-C kernel.
A Unix-like compilation environment with at least the tool GNU make2 ≥ 4.0, as well as various
POSIX commands, libraries and header files, is necessary for compiling Frama-C and its plug-ins.
The OCaml compiler 3 is required both for compiling Frama-C from source and for compiling additional
plug-ins. Compatible OCaml versions are listed as constraints in the opam file.
Other components, such as OcamlGraph, Zarith, Gtk-related packages for the GUI, etc., are listed
in the INSTALL.md and opam files.
1 http://opam.ocaml.org
2 http://www.gnu.org/software/make
3 http://ocaml.org
13
3.2. ONE FRAMEWORK, SEVERAL EXECUTABLES
Batch version The frama-c binary can be used to perform most Frama-C analyses: from parsing the
sources to running complex analyses, on-demand or as part of a continuous integration pipeline.
Many analyses can display their output in simple text form, but some structured results (HTML,
CSV or JSON) are also available. For instance, a SARIF (see Section 11.4) output based on JSON
is can be produced by the Markdown Report plug-in. While the batch version is very powerful, it
does not offer the visualization features of the interactive version.
Interactive version The interactive version is a GUI that can be used to select the set of files to
analyze, specify options, launch analyses, browse the code and observe analysis results at one’s
convenience (see Chapter 10 for details). For instance, you can hover over an expression in the
code and obtain immediate syntactic and semantic information about it; or use context menus for
easy code navigation. However, the initial analysis setup (especially parsing) can be complex for
some projects, and the batch version is better suited for providing error messages at this stage.
Both versions are complementary: the batch version is recommended for initial setup and analysis,
while the interactive version is recommended for results visualization and interactive proofs.
Besides these two executables, Frama-C also provides a few other command line binaries:
– frama-c-config: auxiliary batch version for quickly retrieving configuration information (e.g.
installation paths); it is only useful for scripting and running a large amount of analyses;
– frama-c-script: contains several utilities related to source preparation, results visualization
and analysis automation. Run it without arguments to obtain more details.
Finally, note that the two main binaries (frama-c and frama-c-gui are also provided in bytecode
version, as frama-c.byte and frama-c-gui.byte. The bytecode is sometimes able to provide
better debugging information; but since the native-compiled version is usually much faster (10x), use
the latter unless you have a specific reason to use the bytecode one.
14
3.3. FRAMA-C COMMAND LINE AND GENERAL OPTIONS
There are many aliases for these options, but for backward compatibility purposes only. Those listed
above should be used for scripting. Note that, for all of these options except -plugins, you can use
frama-c-config (instead of frama-c), which offers faster loading times. This is unnecessary for
occasional usage, but when running hundreds of instances of short analyses on Frama-C, the difference is
significant.
For a more thorough display of configuration-related data, in JSON format, use option
-print-config-json. Note that the data output by this option is likely to change in future releases.
Parameterless Options Most parameterless options have an opposite option, often written by
prefixing the option name with no-. For instance, the option -unicode for using the Unicode character
set in messages has an opposite option for limiting the messages to ASCII. Plug-in options with a name
of the form -<plug-in name>-<option name> have their opposite option named -<plug-in
name>-no-<option name>. For instance, the opposite of option -wp-print is -wp-no-print.
Use the options -kernel-help and -<plug-in name>-help to get the opposite option name of
each parameterless option.
String Options If the option’s argument is a string (that is, neither an integer nor a float, etc), the
following format is also possible:
-option_name=value
This format must be used when value starts with a minus sign.
Set Options Some options (e.g. option -cpp-extra-args) accept a set of comma-separated values
as argument. Each value may be prefix by + (resp. -) to indicate that this value must be added to (resp.
deleted from) the set. When neither is specified, + is added by default.
As for string options, the extended format is also possible:
-option_name=values
15
3.3. FRAMA-C COMMAND LINE AND GENERAL OPTIONS
For instance, you can ask the C preprocessor to search for header files in directory src by setting:
-cpp-extra-args="-I src"
Categories are specific values which describe a subset of values. Their names begin with an @.
Available categories are option-dependent, but most set options accept the category @all which defines
the set of all acceptable values.
For instance, you can ask the Eva plug-in to use the ACSL specification of each function but main
instead of their definitions by setting:
-eva-use-spec="@all, -main"
Map Options Map options are set options whose values are of the form key:value. For instance,
you can override the default Eva’s slevel [10] for functions f and g by setting:
-slevel-function="f:16, g:42"
There is also an autocompletion script for zsh, _frama-c, also in the shared resources directory.
Look inside for installation instructions.
The kernel option -autocomplete provides a text output listing all Frama-C options, so that
autocompletion scripts may use it to provide completion. The Frama-C team welcomes improved and
additional autocompletion scripts.
16
3.3. FRAMA-C COMMAND LINE AND GENERAL OPTIONS
17
3.3. FRAMA-C COMMAND LINE AND GENERAL OPTIONS
r: result
u: user error
w: warning
If kinds is empty (e.g. :file1), it defaults to erw, that is, copy all but debug and feedback messages.
file1, file2, etc. are the names of the files where each set of messages will be copied to. Each
file will be overwritten if existing, or created otherwise. Note that multiple entries can be directed to a
single file (e.g. -kernel-log w:warn.txt -wp-log w:warn.txt).
Here is an example of a sophisticated use case for this option:
frama-c -kernel-log ew:warn.log -wp-log ew:warn.log
-metrics-log :../metrics.log [...] file.c
The command above will run some unspecified analyses ([...]), copying the error and warning messages
produced by both the kernel and the wp plug-in into file warn.log, and copying all non-debug, non-
feedback output from the metrics plug-in into file ../metrics.log (note that there is a separator
(:) before the file path).
This option does not suppress the standard Frama-C output, but only copies it to a file. Also, only
messages which are effectively printed (according to the defined verbosity and debugging levels) will be
copied.
18
3.4. ENVIRONMENT VARIABLES
3 Frama-C exits because the user tries to use an unimplemented feature. Please report a “feature request”
on the Bug Tracking System (see Chapter 15);
4,5,6 Frama-C exits on an internal error. Please report a “bug report” on the Bug Tracking System (see
Chapter 15);
125 Frama-C exits abnormally on an unknown error. Please report a “bug report” on the Bug Tracking
System (see Chapter 15).
19
Setting Up Plug-ins 4
The Frama-C platform has been designed to support third-party plug-ins. In the present chapter, we
present how to configure, compile, install, run and update such extensions. This chapter does not deal
with the development of new plug-ins (see the Plug-in Development Guide [15]). Nor does it deal with
usage of plug-ins, which is the purpose of individual plug-in documentation (see e.g. [10, 7, 5]).
There are two kinds of plug-ins: internal and external plug-ins. Internal plug-ins are those distributed
within the Frama-C kernel while external plug-ins are those distributed independently of the Frama-C
kernel. They only differ in the way they are installed: internal plug-ins are automatically installed with
the Frama-C kernel, while external plug-ins must be installed separately.
To install an external plug-in, Frama-C itself must be properly installed first. In particular,
frama-c -print-share-path must return the share directory of Frama-C, while frama-c
-print-lib-path must return the directory where the Frama-C compiled library is installed.
The standard way for installing an external plug-in from source is to run the sequence of commands
make && make install. Please refer to each plug-in’s documentation for installation instructions.
At launch, Frama-C loads all plug-ins in the directories indicated by frama-c -print-plugin-path.
These directories contain META files which are used by Dune to automatically load these plug-ins.
Like other OCaml libraries, Frama-C plug-ins can be located via the environment variable OCAMLPATH.
It does not need to be set by default, but if you install Frama-C in a non-standard directory (e.g.
<PREFIX>), you may need to add directory <PREFIX>/lib to OCAMLPATH.
To prevent Frama-C from automatically loading any plug-ins, you can use option
-no-autoload-plugins. Then the plugin to load can be selected using -load-plugin
<plugin-name> (e.g. aorai). Since Frama-C plugins are also OCaml libraries it is possible to use
-load-library <library-name> (e.g. frama-c-aorai). Both options accept comma-separated
lists of names.
20
4.3. LOADING PLUG-INS
In general, plug-ins must be compiled with the very same OCaml compiler than Frama-C was, and
against a consistent Frama-C installation. Loading will fail and a warning will be emitted at launch if
this is not the case.
21
Preparing the Sources 5
This chapter explains how to specify the source files that form the basis of an analysis project, and
describes options that influence parsing.
For small projects and tests, processing the sources in Frama-C is as simple as running frama-c *.c.
For more complex projects, however, some problems may arise when using this command, and the user
must be aware of the several steps involved in Frama-C source processing to fix them.
The diagram in Figure 5.1 presents an overview of the steps described in this chapter. For comparison
purposes, we add the equivalent process performed by a compiler such as GCC.
Figure 5.1: Overview of source preparation steps: as performed by GCC (top) and as performed by
Frama-C (bottom).
The following sections describe various options related to the steps shown in the figure. Note that
some plug-ins, such as Variadic (described in chapter 12), perform further AST transformations before
22
5.2. PREPROCESSING THE SOURCE FILES
The list of files to analyze must be provided on the command line, or chosen interactively in the GUI.
Files with the suffix .i are assumed to be already preprocessed C files. Frama-C preprocesses .c and
.h files with the following basic command:
$ gcc -C -E -I .
Plus some architecture-dependent flags. The exact preprocessing command line can be obtained via
options -kernel-msg-key pp and -print-cpp-commands (the latter exits Frama-C after printing).
Option -cpp-extra-args can be used to add arguments to the default preprocessing com-
mand, typically via the inclusion of defines (-D switches) and header directories (-I switches), as
in -cpp-extra-args="-DDEBUG -DARCH=ia32 -I./headers". You can also add arguments on
a per-file basis, using option -cpp-extra-args-per-file.
If you need to, you can also replace the preprocessing command entirely with option -cpp-command.
Placeholders (see below) can be used for advanced commands. If no placeholders are used, the preprocessor
is invoked in the following way.
<cmd> <args> <input file> -o <output file>
In this command, <output file> is a temporary filename chosen by Frama-C while <input
file> is one of the filenames provided by the user.
For commands which do not follow this pattern, it is also possible to use the following placeholders:
%input, %i or %1 Input file
%output, %o or %2 Output file
%args Additional arguments (see -cpp-extra-args below)
Here are some examples for using this option.
$ frama-c -cpp-command ’gcc -C -E -I. -x c’ file1.src file2.i
$ frama-c -cpp-command ’gcc -C -E -I. %args -o %o %i’ file1.c file2.i
$ frama-c -cpp-command ’cp %i %o’ file1.c file2.i
$ frama-c -cpp-command ’cat %i > %o’ file1.c file2.i
$ frama-c -cpp-command ’CL.exe /C /E %args %i > %o’ file1.c file2.i
When using -cpp-command, you may add -cpp-frama-c-compliant to indicate that the
custom preprocessor accepts the same set of options as GNU cpp. -cpp-frama-c-compliant also
implies some extra constraints, such as accepting architecture-specific flags, e.g. -m32.
If you have a JSON compilation database file1 , you can use it to retrieve preprocessing macros such as
-D and -I for each file in the database, via option -json-compilation-database <path>, where
<path> is the path to the JSON file or to a directory containing a file named compile_commands.json.
With this option set, Frama-C will parse the compilation database and include associated preprocess-
ing flags, as if they had been manually added via -cpp-extra-args-per-file. Note: if both
-cpp-extra-args-per-file and the JSON compilation database specify options for a given file,
the former are used and the latter are ignored. Also note that the use of the database simply adds flags
for the files specified on the command-line, but these files must still be specified by the user.
In all of the above cases, ACSL annotations are preprocessed by default (option -pp-annot is set
by default). Unless a custom preprocessor is specified (via -cpp-frama-c-compliant), Frama-C
considers that Gcc is installed and uses it as preprocessor. If you do not want annotations to be
preprocessed, you need to pass option -no-pp-annot to Frama-C. Note that some headers in the
standard C library provided with Frama-C (described in Section 5.9) use such annotations, therefore it
might be necessary to disable inclusion of such headers.
1 http://clang.llvm.org/docs/JSONCompilationDatabase.html
23
5.3. MERGING THE SOURCE CODE FILES
Also note that ACSL annotations are preprocessed separately from the C code in a second pass, and
that arguments given as -cpp-extra-args are not given to the second pass of preprocessing. Instead,
-pp-annot relies on the ability of Gcc to output all macro definitions (including those given with -D)
in the preprocessed file. In particular, -cpp-extra-args must be used if you are including header
files who behave differently depending on the number of times they are included.
In addition, files having the suffix .ci will be considered as needing preprocessing for ACSL
annotations only. Those files may contain #define directives and annotations are preprocessed as
explained in the previous paragraph. This allows to have macros in ACSL annotations while using a
non-GNU-like preprocessor.
After preprocessing, Frama-C parses, type-checks and links the source code. It also performs these
operations for the ACSL annotations optionally present in the program. Together, these steps form the
merging phase of the creation of an analysis project.
Frama-C aborts whenever any error occurs during one of these steps. However users can use the
option -kernel-warn-key annot-error=active2 in order to continue after emitting a warning
when an ACSL annotation fails to type-check.
After merging the project files, Frama-C performs a number of local code transformations in the
normalization phase. These transformations aim at making further work easier for the analyzers.
Analyses usually take place on the normalized version of the source code. The normalized version may
be printed by using the option -print (see Section 3.3.10).
The following options allow to customize the normalization process.
-aggressive-merging forces some function definitions to be merged into a single function if they
are equal modulo renaming. Note that this option may merge two functions even if their original
source code is different but their normalized version coincides. This option is mostly useful to
share function definitions that stem from headers included by several source files.
-allow-duplication allows the duplication of small blocks of code during normalization of
loops and tests. This is set by default and the option is mainly found in its opposite form,
-no-allow-duplication which forces Frama-C to use labels and gotos instead. Note that
bigger blocks and blocks with a non-trivial control flow are never duplicated. Option -ulevel
(see below) is not affected by this option and always duplicates the loop body.
-annot forces Frama-C to interpret ACSL annotations. This option is set by default, and is only found
in its opposite form -no-annot, which prevents interpretation of ACSL annotations.
-asm-contracts tells Frama-C to generate assigns clauses for inline asm statements using extended
GNU notation with output and input operands. This option is set by default, and opposite form
-no-asm-contracts prevents the generation of such clauses. If the assembly block already has
a statement contract which is not guarded by a for b: clause assigns clauses are generated
only for behaviors which do not already have one.
2 See section 7.2 for more information on warning statuses.
24
5.4. NORMALIZING THE SOURCE CODE
-constfold performs a syntactic folding of constant expressions. For instance, the expression 1+2 is
replaced by 3.
-continue-annot-error Deprecated option. Just emits a warning and discards the annotation
when it fails to type-check, instead of generating an error (errors in C are still fatal). This
behavior is now managed by warning category (Section 7.2) annot-error, whose default status is
“abort”. Behavior of -continue-annot-error can thus be obtained with -kernel-warn-key
annot-error=active, or even -kernel-warn-key annot-error=inactive to silently
ignore any ill-formed annotations.
-enums <repr name> specifies which representation should be used for a given enumerated type.
Namely, the C standard allows the use of any integral type in which all the corresponding tags can
be represented. Default is gcc-enums. A list of supported options can be obtained by typing:
$ frama-c -enums help
This includes:
– int: treat everything as int (including enumerated types with packed attribute).
– gcc-enums: use an unsigned integer type when no tag has a negative value, and choose the
smallest rank possible starting from int (default Gcc’s behavior)
– gcc-short-enums: use an unsigned integer type when no tag has a negative value, and
choose the smallest rank possible starting from char (Gcc’s -fshortenums option)
-keep-switch preserves switch statements in the source code. Without this option, they are
transformed into if statements. An experimental plug-in may require this option to be unset to
avoid having to handle the switch construct. Other plug-ins may prefer this option to be used
because it better preserves the structure of the original program.
-keep-unused-specified-functions does not remove from the AST uncalled function proto-
types that have ACSL contracts. This option is set by default. So you mostly use the opposite
form, namely -remove-unused-specified-functions.
-keep-unused-types does not remove unused types and enum/struct/union declarations. By
default, such types are removed, that is, its opposite option -remove-unused-types is set.
25
5.5. NORMALIZING CONTRACTS
-machdep <machine architecture name> defines the target platform. The default value is a
x86_64 bits platform. Analyzers may take into account the endianness of the target, the size
and alignment of elementary data types, and other architecture/compilation parameters. The
-machdep option provides a way to define all these parameters consistently in a single step. Note
that multiarch preprocessors such as GCC’s may require special flags to ensure compatibility with
the chosen machdep, e.g. -m32 for a x86_64 GCC compiling 32-bit code. In most cases this is
handled automatically, but otherwise option -cpp-command can be used.
The list of supported platforms can be obtained by typing:
$ frama-c -machdep help
Apart from these default platforms, it is possible to give as argument to -machdep option the
path of a YAML file containing the information needed by Frama-C. The Plug-in Development
Guide [15] describes this format in more detail, as well as the use of the make_machdep.py script
to automatically generate it.
-simplify-cfg allows Frama-C to remove break, continue and switch statements. This option is
automatically set by some plug-ins that cannot handle these kinds of statements. This option is
off by default.
-simplify-trivial-loops simplifies trivial loops such as do ... while(0). This option is
set by default.
-ulevel <n> unrolls all loops n times. This is a purely syntactic operation. Loops can be unrolled
individually, by inserting the UNROLL pragma just before the loop statement. Do not confuse this
option with plug-in-specific options that may also be called “unrolling” [10]. Below is a typical
example of use.
/*@ loop pragma UNROLL 10; */
for(i = 0; i < 9; i++) ...
The transformation introduces an UNROLL pragma indicating that the unrolling process has been
done:
... // loop unrolled 10 times
/*@ loop pragma UNROLL 10;
loop pragma UNROLL "done", 10; */
... // remaining loop
That allows to disable unrolling transformation on such a loop when reusing Frama-C with a code
obtained by a previous use of Frama-C tool. To ignore this disabling UNROLL pragma and force
unrolling, the option -ulevel-force has to be set.
Passing a negative argument to -ulevel will disable unrolling, even in case of UNROLL pragma.
Normalization gives a program which is semantically equivalent to the original one, but there is an
exception for function contracts. By default, function contracts are left as is, but Frama-C and plug-ins
can require the presence of some specification to improve their performances. When they do, they can
ask Frama-C’s kernel to generate specifications.
For example, let us say we have a function f that is only declared and has no ACSL assigns clause,
but these assigns are required by Eva. Eva asks the kernel to generate assigns before resuming the
analysis. Indeed, as mentioned in the ACSL manual [3], assuming that f can write to any location in the
26
5.5. NORMALIZING CONTRACTS
memory would amount to stop any semantical analysis at the first call to f, since nothing would be
known on the memory state afterwards.
The generation is done either by combining existing specifications or according to a mode which can
be selected via Frama-C’s options. A plug-in developer has also the possibility to create their own mode
using Frama-C’s API. The Plug-in Development Guide [15] describes all steps required to create and use
a custom mode. All available modes are detailed in table 5.1. Additionally, a status is emitted for each
generated clause. A summary can be found in table 5.2.
By default, Frama-C selects the mode Frama_C and the following options allow selecting mode(s)
for the specification generation:
Here every clause is generated using the default mode Frama_C except for exits which are not
generated and requires which are generated using the mode Safe.
As mentioned, the generation can also be done by combining existing clauses from other behaviors
following this algorithm:
1. If the function contract has some clauses C in unguarded (without assumes clauses) behaviors,
we combine them in the default behavior.
2. Else, if it has some clauses C in complete behaviors, we combine them in the default behavior.
3. Else, if it has some clauses C anywhere, we combine them in the default behavior.
4. Else we use the selected mode to generate these clauses (see mode’s table).
Note: There is an exception with the mode ACSL for which we never try to combine existing clauses
from other behavior, and jump directly to the step of our algorithm to use the selected mode.
When a clause is generated for a function, Frama-C’s kernel can emit a warning if this function is a
prototype and if it is not part of Frama-C’s builtins. The message emitted depends on the generated
clauses, their origins (if we combined some clauses from existing ones, or generated them from nothing,
or both) as well as if the function contract was empty before the generation or incomplete.
27
5.6. INCREMENTAL PARSING
Table 5.2: Status emitted during the specification generation according to the selected mode
(experimental)
Parsing large code bases takes a non-negligible amount of time. More importantly, non-modular
analyses need to be recomputed in their entirety even for minuscule AST changes.
In order to help deal with these issues, and to help support for future incremental analyses (which
recompute results only for the modified AST parts and their dependencies), you can use option
-ast-diff. It enables computing the difference between a previous AST (loaded via option -load
(Section 9.1.3) and the AST computed from the current sources. This difference is stored by the Frama-C
kernel and can be used by plug-ins which support it. Note however that since -load implies that files
given on the command line are ignored, -load and -ast-diff with the list of C files to consider must
be properly sequenced through the use of -then or one of its variants (Section 3.3.5), as in:
$ frama-c -load previous.sav -then -ast-diff file1.c file2.c [...]
Note: currently, parsing and type-checking are systematically performed even with this option, and
-ast-diff compares the normalized ASTs. In the future, though, these steps should be refactored to
allow saving further time.
Frama-C, like several compilers and code analysis tools, predefines and uses a certain number of C macros.
They are summarized below.
__FRAMAC__: defined to 1 during preprocessing by Frama-C, as if the user had added -D__FRAMAC__
to the command line. Useful for conditional compilation and detection of an execution by Frama-C.
28
5.8. COMPILER AND LANGUAGE EXTENSIONS
Furthermore, some macros are undefined in the standard library, and can be defined (e.g. through
-cpp-extra-args) to customize the Frama-C standard library. They are described below.
Frama-C’s default behavior is to be fairly strict concerning language features. By default, most C99 and
C11 features are accepted3 , but most non-ISO C compiler extensions are not accepted, similarly to when
compiling a program with gcc -std=c11 -pedantic -pedantic-errors.
However, depending on the machine architecture (see option -machdep, in Section 5.4), Frama-C
accepts some compiler extensions, namely for GCC and MSVC machdeps. For instance, trying to parse
a program containing an empty initializer, such as int c[10] = {}; will result in the following error
message:
[kernel] user error: empty initializers only allowed for GCC/MSVC; see option
-machdep or run ’frama-c -machdep help’ for the list of available machdeps
This means that using a GCC or MSVC machdep (e.g., -machdep gcc_x86_32) will allow the
language extension to be accepted by Frama-C.
Frama-C bundles a C standard library in order to help parse and analyze code that relies on the functions
specified in the ISO C standard. Furthermore, In order to simplify parsing of code using common
open-source libraries, Frama-C’s standard library also includes some POSIX and non-POSIX headers
which are not part of ISO C. Such libraries are provided on a best-effort basis, and they are part of the
trusted computing base: to ensure its correctness, the specifications must be ultimately proofread by the
user.
This library, while incomplete, is constantly being improved and extended. It is installed in the
sub-directory libc of the directory printed by frama-c -print-share-path. It contains standard
C headers, some ACSL specifications, and definitions for a few library functions.
By default, Frama-C’s preprocessing will include the headers of its own standard li-
brary, instead of those installed in the user’s machine. This avoids issues with non-
portable, compiler-specific features. Option -frama-c-stdlib (set by default) adds
-I$(frama-c-config -print-share-path)/libc to the preprocessor command, as well
as GCC-specific option -nostdinc. If the latter is not recognized by your preprocessor,
-no-cpp-frama-c-compliant can be given to Frama-C (see section 5.2).
The use of Frama-C’s standard library contains a few caveats:
– definitions which are not present in Frama-C’s standard library may cause parsing errors, e.g.
missing type definitions, or missing fields in structs;
3 For more details about C99/C11 feature support, see Section 14.1.
29
5.10. WARNINGS DURING NORMALIZATION
– if a header is included which is not available in Frama-C’s library, preprocessing will fail by
default (due to the -nostdinc option); if the user manually includes the system’s library, e.g. by
adding -cpp-extra-args=’-I/usr/include’, the preprocessor will end up mixing headers
from Frama-C’s library with those from the system, often leading to incompatible definitions and
unexpected parsing errors. In this case, the best approach is usually to include only the missing
definitions, for instance by copying them to a separate header file, included manually or via the
GCC-compatible option -include <header.h> (see GCC’s Preprocessor Options for more
details). Alternatively, consider filing an issue (see Chapter 15) to ask for the inclusion of such
headers and/or definitions in Frama-C’s standard library.
Note that, while Frama-C’s library intends to offer maximum portability, some definitions such as
numeric constants require actual values to be defined. For pragmatic reasons, such definitions are most
often based on the values defined in GNU/Linux’s libc, and may differ from those in your system. As
stated before, if you want to ensure the code analyzed by Frama-C is strictly equivalent to the one from
the target system, you must either proofread the definitions, or provide your own library files.
Note: the options below are deprecated, replaced by the more general and flexible mechanism of warning
categories, described in Section 7.2.
Some options can be used to influence the warnings that are emitted by Frama-C during the
normalization phase.
If the steps up to normalization succeed, the project is then ready for analysis by any Frama-C plug-in.
It is possible to test that the source code preparation itself succeeds, by running Frama-C without any
option.
$ frama-c <input files>
If you need to use other options for preprocessing or normalizing the source code, you can use the
option -typecheck for the same purpose. For instance:
$ frama-c -cpp-command ’gcc -C -E -I. -x c’ -typecheck file1.src file2.i
30
ACSL extensions 6
6.1 Handling indirect calls with calls
In order to help plug-ins support indirect calls (i.e. calls through a function pointer), an ACSL extension
is provided. It is introduced by keyword calls and can be placed before a statement with an indirect
call to give the list of functions that may be the target of the call. As an example,
/*@ calls f1, f2, ... , fn */
*f(args);
indicates that the pointer f can point to any one of f1, f2, ..., fn.
It is in particular used by the WP plug-in (see [7] for more information).
31
Platform-wide Analysis Options 7
The options described in this chapter provide each analysis with common hypotheses that influence
directly their behavior. For this reason, the user must understand them and the interpretation the
relevant plug-ins have of them. Please refer to individual plug-in documentations (e.g. [10, 5, 7]) for
specific options.
The following options define the entry point of the program and related initial conditions.
-main <function_name> specifies that all analyzers should treat function function_name as the
entry point of the program.
-lib-entry indicates that analyzers should not assume globals to have their initial values at the
beginning of the analysis. This option, together with the specification of an entry point f, can be
used to analyze the function f outside of a calling context, even if it is not the actual entry point
of the analyzed code.
32
7.3. CUSTOMIZING ANALYZERS
all its subcategories. An enabled category cat can be disabled by using -cat in the list of keys.
Several occurrences of the option may appear on the command line and will be processed in order.
The =<status> part might be omitted, which is equivalent to asking for active status. The
new status will be propagated to subcategories, with one exception: statuses “abort”, “error” and
“err-once” will only be propagated to subcategories whose current status is not “inactive”.
Finally, as for debug categories, passing help (without status) in the list of keys will list the
available categories, together with their current status. Passing * in the list of keys will change
the status of all warning categories, and affect warnings that do not have a category. Hence,
-kernel-warn-key *=abort will stop Frama-C’s execution at the first warning triggered by
the kernel.
The two following options modify the behavior of output messages:
-add-symbolic-path takes a list of the form path1 : name1 , . . . , pathn : namen in argument and
replaces each pathi with namei when displaying file locations in messages.
-permissive performs less verification on validity of command-line options.
The descriptions of the analysis options follow. For the first two, the description comes from the Eva
manual [10]. Note that these options are very likely to be modified in future versions of Frama-C.
-absolute-valid-range m-M specifies that the only valid absolute addresses (for reading or writing)
are those comprised between m and M inclusive. This option currently allows to specify only a
single interval, although it could be improved to allow several intervals in a future version. m and
M can be written either in decimal or hexadecimal notation.
-unsafe-arrays can be used when the source code manipulates n-dimensional arrays, or arrays
within structures, in a non-standard way. With this option, accessing indexes that are out of
bounds will instead access the remainder of the struct. For example, the code below will overwrite
the fields a and c of v.
33
7.3. CUSTOMIZING ANALYZERS
struct s {
int a;
int b[2];
int c;
};
void main(struct s v) {
v.b[-1] = 1;
v.b[2] = 4;
}
The opposite option, called -safe-arrays, is set by default. With -safe-arrays, the two
accesses to v are considered invalid. (Accessing v.b[-2] or v.b[3] remains incorrect, regardless
of the value of the option.)
-warn-invalid-pointer may be used to check that the code does not perform illegal pointer
arithmetics, creating pointers that do not point inside an object or one past an object. This option
is disabled by default, allowing the creation of such invalid pointers without alarm — but the
dereferencing of an invalid pointer always generates an alarm.
For instance, no error is detected by default in the following example, as the dereferencing is
correct. However, if option -warn-invalid-pointer is enabled, an error is detected at line 4.
int x;
int *p = &x;
p++; // valid
p++; // undefined behavior
*(p-2) = 1;
Currently, the option is disabled by default. The rationale for this is the fact that it creates a lot
of redundancies with pointer access alarms and that most of the time even when a pointer reaches
such an invalid value, it is never read again, or if it is, the memory access will trigger an alarm.
-unspecified-access may be used to check when the evaluation of an expression depends on the
order in which its sub-expressions are evaluated. For instance, this occurs with the following piece
of code.
int i, j, *p;
i = 1;
p = &i;
j = i++ + (*p)++;
In this code, it is unclear in which order the elements of the right-hand side of the last as-
signment are evaluated. Indeed, the variable j can get any value as i and p are aliased.
The -unspecified-access option warns against such ambiguous situations. More precisely,
-unspecified-access detects potential concurrent write accesses (or a write access and a read
access) over the same location that are not separated by a sequence point. Note however that this
option does not warn against such accesses if they occur in an inner function call, such as in the
following example:
int x;
int f() { return x++; }
int g() { return f() + x++; }
Here, the x might be incremented by g before or after the call to f, but since the two write accesses
occur in different functions, -unspecified-access does not detect that.
34
7.3. CUSTOMIZING ANALYZERS
-warn-pointer-downcast may be used to check that the code does not downcast a pointer to an
integer type. This option is set by default. In the following example, analyzers report by default
an error on the third line. Disabling the option removes this verification.
int x;
uintptr_t addr = &x;
int a = &x;
-warn-signed-downcast may be used to check that the analyzed code does not downcast an integer
to a signed integer type. This option is not set by default. Without it, the analyzers do not
perform such a verification. For instance consider the following function.
short truncate(int n) {
return (short) n;
}
By default, analyzers detect an error on -x since this operation overflows when MININT is the
argument of the function. But, with the -no-warn-signed-overflow option, no error is
detected.
-warn-unsigned-overflow is the same as -warn-signed-overflow for operations over un-
signed integers. This option is not set by default.
-warn-left-shift-negative can be used to check that the code does not perform signed left
shifts on negative values, i.e., x << n with x having signed type and negative value. This is set
by default, and can be disabled with option -no-warn-left-shift-negative.
-warn-right-shift-negative, as its left-shift counterpart, can be used to check for negative
right shifts, i.e., x >> n with x having signed type and negative value. This is not set by default.
-no-warn-right-shift-negative can be used to disable the option if previously enabled.
-warn-special-float <type> may be used to allow or forbid special floating-point values, gener-
ating alarms when they are produced. <type> can be one of the following values:
non-finite : warn on infinite floats or NaN
nan : warn on NaN only
none : no warnings
-warn-invalid-bool may be used to check that the code does not use invalid _Bool values by
reading trap representations from lvalues of _Bool types. A trap representation does not represent
a valid value of the _Bool type, which can only be 0 or 1. This option is set by default, and can
be disabled with -no-warn-invalid-bool.
35
Property Statuses 8
This chapter touches on the topic of program properties, and their validation by either standalone or
cooperating Frama-C plug-ins. The theoretical foundation of this chapter is described in a research
paper [8].
Frama-C supports writing code annotations with the ACSL language [3]. The purpose of annotations is
to formally specify the properties of C code: Frama-C plug-ins can rely on them to demonstrate that an
implementation respects its specification.
Annotations can originate from a number of different sources:
the user who writes his own annotations: an engineer writing code specifications is the prevalent
scenario here;
some plug-ins may generate code annotations. These annotations can, for instance, indicate that a
variable needs to be within a safe range to guarantee no runtime errors are triggered (cf the RTE
plug-in [11]).
the kernel of Frama-C, that attempts to generate as precise an annotation as it can, when none is
present.
Of particular interest is the case of unannotated function prototypesa : the ACSL specification states
that a construct of that kind “potentially modifies everything” [3, Sec. 2.3.5]. For the sake of precision
and conciseness, the Frama-C kernel breaks this specification, and generates a function contract with
clauses that relate its formal parameters to its resultsb . This behavior might be incorrect – for instance
because it does not consider functions that can modify globals. While convenient in a wide range of
cases, this can be averted by writing a custom function contract for the contentious prototypes.
a A function prototype is a function declaration that provides argument types and return type, but lacks a body.
b Results here include the return value, and the formal modifiable parameters.
The rest of this chapter will examine how plug-ins can deal with code annotations, and in particular
what kind of information can be attached to them.
A property is a logical statement bound to a precise code location. A property might originate from:
36
8.3. CONSOLIDATING PROPERTY STATUSES
– an ACSL code annotation – e.g. assert p[i] * p[i] <= INT_MAX. Recall from the previous
section that annotations can either be written by the user, or generated by the Frama-C plug-ins
or kernel;
– a plugin-dependent meta-information – such as the memory model assumptions.
Consider a program point i, and call T the set of traces that run through i. More precisely, we only
consider the traces that are coming from the program entry point1 (see option -main in chapter 7). A
logical property P is valid at i if it is valid on all t ∈ T . Conversely, any trace u that does not validate
P , stops at i: properties are blocking.
As an example, a property might consist in a statement p[j] × p[j] ≤ 2147483647 at a program point
i. A trace where p[j] = 46341 at i will invalidate this property, and will stop short of reaching any
instruction succeeding i.
An important part of the interactions between Frama-C components (the plug-ins/the kernel) rely
on their capacity to emit a judgment on the validity of a property P at program point i. In Frama-C
nomenclature, this judgment is called a local property status. The first part of a local status ranges over
the following values:
– True when the property is true for all traces;
– False when there exists a trace that falsifies the property;
– Maybe when the emitter e cannot decide the status of P .
As a second part of a local property status, an emitter can add a list of dependencies, which is the
set of properties whose validity may be necessary to establish the judgment. For instance, when the
WP plug-in [7] provides a demonstration of a Hoare triple {A} c {B}, it starts by setting the status
of B to “True”, and then adds to this status a dependency on property A. In more formal terms, it
corresponds to the judgment ⊢ A ⇒ B: “for a trace to be valid in B, it may be necessary for A to hold”.
This information on the conditional validity of B is provided as a guide for validation engineers, and
should not be mistaken for the formal proof of B, which only holds when all program properties are
verified – hence the local status.
Recall our previous example, where the WP plug-in sets the local status of a property B to “True”,
with a dependency on a property A. This might help another plug-in decide that the validity of a third
property C, that hinges upon B, now depends on A. When at last A is proven by, say, the value analysis
plug-in, the cooperative proofs of A, B, and C are marked as completed. In formal terms, Frama-C
has combined the judgments: ⊢ A ⇒ B, ⊢ B ⇒ C, and ⊢ A into proofs of ⊢ B and ⊢ C, by using the
equivalent of a modus ponens inference:
⊢A ⊢A⇒B
⊢B
Notice how, without the final ⊢ A judgment, both proofs would be incomplete.
This short example illustrates how incremental the construction of program property proofs can be.
By consolidating property statuses into an easily readable display, Frama-C aims at informing its users
of the progress of this process, allowing them to track unresolved dependencies, and selectively validate
subsets of the program’s properties.
As a result, a consolidated property status can either be a simple status:
37
8.3. CONSOLIDATING PROPERTY STATUSES
– surely_valid: when the status is True, and dependencies have the consolidated status
surely_valid or considered_valid.
– surely_invalid: when the status is False, and all dependencies have the consolidated status
surely_valid.
– inconsistent: when there exist two conflicting consolidated statuses for the same property, for
instance with values surely_valid and surely_invalid. This case may also arise when an
invalid cyclic proof is detected. This is symptomatic of an incoherent axiomatization.
or an incomplete status:
– considered_valid: when there is no possible way to prove the property (e.g., the post-condition
of an external function). We assume this property will be validated by external means.
– valid_under_hyp: when the local status is True but at least one of the dependencies has
consolidated status unknown. This is typical of proofs in progress.
– invalid_under_hyp: when the local status is False, but at least one of the dependencies has
status unknown. This is a telltale sign of a dead code property, or of an erroneous annotation.
and finally:
– unknown_but_dead: when the status is locally Maybe, but in a dead or incoherent branch.
– valid_but_dead: when the status is locally True, but in a dead or incoherent branch.
– invalid_but_dead: when the status is locally False, but in a dead or incoherent branch.
The dependencies are meant as a guide to safety engineers. They are neither correct, nor complete,
and should not be relied on for formal assessment purposes. In particular, as long as partial proofs
exist (there are unknown or never_tried), there is no certainty with regards to any other status
(including surely_valid properties).
These consolidated statuses are displayed in the GUI (see section 10 for details), or in batch mode
by the report plug-in.
38
General Kernel Services 9
This chapter presents some important services offered by the Frama-C platform.
9.1 Projects
A Frama-C project groups together one source code with the states (parameters, results, etc) of the
Frama-C kernel and analyzers.
In one Frama-C session, several projects may exist at the same time, while there is always one and
only one so-called current project in which analyses are performed. Thus projects help to structure a
code analysis session into well-defined entities. For instance, it is possible to perform an analysis on the
same code with different parameters and to compare the obtained results. It is also possible to extract a
program p′ from an initial program p and to compare the results of an analysis run separately on p and
p′ .
39
9.2. DEPENDENCIES BETWEEN ANALYSES
may have been corrupted. In other error cases, no saving is done. The same operations are available
through the GUI.
When saving, all existing projects are dumped into an unique non-human-readable file.
When loading, the following actions are done in sequence:
1. all the existing projects of the current session are deleted;
2. all the projects stored in the file are loaded;
3. the saved current project is restored;
4. Frama-C is replayed with the parameters of the saved current project, except for those parameters
explicitly set in the current session.
Consider for instance the following command.
$ frama-c -load foo.sav -eva
It loads all projects saved in the file foo.sav. Then, it runs the value analysis in the new current
project if and only if it was not already computed at save time.
Recommendation 9.1 Saving the result of a time-consuming analysis before trying to use it in different
settings is usually a good idea.
Beware that all the existing projects are deleted, even if an error occurs when reading the file. We
strongly recommend you to save the existing projects before loading another project file.
Special Cases Options -help, -verbose, -debug (and their corresponding plugin-specific coun-
terpart) as well as -explain, -quiet and -unicode are not saved on disk.
Usually analyses do have parameters (see Chapter 7). Whenever the values of these parameters change,
the results of the analyses may also change. In order to avoid displaying results that are inconsistent
with the current value of parameters, Frama-C automatically discards results of an analysis when one of
the analysis parameters changes.
Consider the two following commands.
$ frama-c -save foo.sav -ulevel 5 -absolute-valid-range 0-0x1000 -eva foo.c
$ frama-c -load foo.sav
Frama-C runs the value analysis plug-in on the file foo.c where loops are unrolled 5 times (option
-ulevel, see Section 5.4). To compute its result, the value analysis assumes the memory range 0:0x1000
is addressable (option -absolute-valid-range, see Section 7.3). Just after, Frama-C saves the
results on file foo.sav and exits.
At loading time, Frama-C knows that it is not necessary to redo the value analysis since the parameters
have not been changed.
Consider now the two following commands.
$ frama-c -save foo.sav -ulevel 5 -absolute-valid-range 0-0x1000 -eva foo.c
$ frama-c -load foo.sav -absolute-valid-range 0-0x2000
The first command produces the very same result than above. However, in the second (load) com-
mand, Frama-C knows that one parameter has changed. Thus it discards the saved results of the
value analysis and recomputes it on the same source code by using the parameters -ulevel 5
-absolute-valid-range 0-0x2000 (and the default value of each other parameter).
In the same fashion, results from an analysis A1 may well depend on results from another analysis
A2 . Whenever the results from A2 change, Frama-C automatically discards results from A1 . For instance,
slicing results depend on value analysis results; thus the slicing results are discarded whenever the value
analysis ones are.
40
Graphical User Interface 10
Running frama-c-gui or frama-c-gui.byte displays the Frama-C Graphical User Interface (GUI).
Upon launching Frama-C in graphical mode on some C files, the following main window is displayed
(figure 10.1):
41
10.2. MENU BAR
The menu bar organizes the highest-level functions of the tool into structured categories. Plug-ins
may also add their own entries in the “Analyses” menu.
The toolbar gives access to the main functions of the tool. They are usually present in one menu of
the menu bar. Plug-ins may also add their own entries here.
The file tree provides a tree-like structure of the source files involved in the current analysis. This
tree lists all the global variables and functions each file contains. Within a file, entries are sorted
alphabetically, without taking capitalization into account. Functions are underlined, to separate
them from variables. Plug-ins may also display specific information for each file and/or function.
Finally, the “Source file” button offers some options to filter the elements of the file tree:
– The “Hide variables” and “Hide functions” options offer the possibility to hide the non-desired
entries from the tree.
– The “Flat mode” option flattens the tree, by removing the filename level. Instead, functions
and globals are displayed together, as if they were in a big namespace. This makes it easier
to find a function whose only the name is known.
The normalized and original source code views display the source code of the current selected
element of the file tree and its normalized code (see Section 5.4). Left-clicking on an object
(statement, left-value, etc) in the normalized source code view displays information about it in the
“Information” page of the Messages View and displays the corresponding object of the original
source view, while right-clicking on them opens a contextual menu. Items of this menu depend on
the kind of the selected object and on plug-in availability.
Only the normalized source view is interactive: the original one is not.
The plug-ins view shows specific plug-in interfaces. The interface of each plug-in can be collapsed.
The messages view contains by default six different pages, namely:
Information: provides brief details on the currently selected object, or informative messages from
the plugins.
Messages: shows important messages generated by the Frama-C kernel and plug-ins, in particular
all alarms. Please refer to the specific documentation of each plug-in in order to get the exact
form of alarms. Alarms that have a location in the original source can be double-clicked; this
location will then be shown in the original and normalized source code viewers.1
Console: displays messages to users in a textual way. This is the very same output than the one
shown in batch mode.
Properties: displays the local and consolidated statuses of properties.
Values: displays information relative to the Value Analysis plug-in.
WP Goals: displays information relative to the WP plug-in.
42
10.2. MENU BAR
– Analyses: opens the dialog box shown in Figure 10.2, that allows setting Frama-C parameters
and re-running analyses.
– Load and run an OCaml module: allows you to load a compiled OCaml module as a
plug-in (see Section 4.3).
– Other items are plug-in specific.
The debug menu is only visible in debugging mode and provides access to tools for helping to debug
Frama-C and their plug-ins.
The help menu provides help items.
43
10.3. TOOL BAR
The tool bar offers a more accessible access to some frequently used functions of the menu bar. Currently,
the available buttons are, from left to right:
– The Exit button, that exits Frama-C.
– Four buttons Source files, Reparse, Load Session and Save session, equivalent to
the corresponding entries in the File menu.
– Two navigation buttons, Back and Forward. They can be used to move within the history of the
functions that have been viewed.
– The Analyses button, equivalent to the one in the Analyses menu.
– A Stop button, which halts the running analyses and restores Frama-C to its last known valid
configuration.
44
Reports 11
An execution of Frama-C outputs many messages, warnings and various property statuses in textual
form. The Graphical User Interface (see Chapter 10) is a very good place to visualize all these results,
but there are no synthetic results and integration with development environments can be difficult.
The report plug-in, provided by default with the Frama-C platform, is designed for this purpose. It
provides the following features, which we detail in turn:
– Printing a summary of property consolidated statuses;
– Exporting a CSV file of property consolidated statuses;
– Filtering and classifying warnings, errors and property consolidated statuses, based on user-defined
rules in JSON format;
– Output the above classification in JSON format;
– Make Frama-C exit with a non-null status code on some classified warning or error.
Frama-C has recently earned the ability to output data in the SARIF1 format. This is performed by
the Markdown Report plug-in, described in section 11.4.
The following options of the report plug-in are available for reporting on consolidated property statuses:
-report Displays a summary of property statuses in textual form. The output is structured by
functions and behaviors. The details of which plug-ins participate into the consolidation of each
property status is also provided. This report is designed to be human-readable, although it can be
verbose, subject to changes, and not suitable for integration with other tools.
-report-print-properties Also print the properties definition (in ACSL form) within the report.
-report-(no)-proven If not set, filter out the proven properties from the report.
-report-(no)-specialized If not set, filter out the properties that are auxiliary instances of other
properties, like the preconditions of a function at its call sites.
-report-untried If set, also include in the report the properties that have not been tried.
1 Static Analysis Results Interchange Format, https://www.oasis-open.org/committees/tc_home.php?wg_
abbrev=sarif
45
11.2. EXPORTING TO CSV
The consolidated property status database can be exported to a CSV file, eg. for an easy import into
Excel. To use this feature, simply use the following option of the report plug-in:
-report-csv <file>.csv Output the report in CSV format into the specified file.
Notice than it is not necessary to set -report option to use this feature. It is highly recommended
to use this option in combination with the following other standard Frama-C options:
> frama-c ... -then -no-unicode -report-csv <file>.csv
The format of the output CSV file is a collection of property consolidated statuses, with one property
per line. Each line consists of a collection of TAB (ascii 0x0A) separated columns. The first line of the
report contains the title of the columns, as follows:
> head -1 <file>.csv
directory file line function property kind status property
11.3 Classification
We denote by event any warning, error and (finally consolidated) property status emitted by any plug-in
during the execution of Frama-C. We introduce the notion of event classification as follows:
– An event can be assigned a class, identified by a name;
– The event is associated to a location (file,line) when available;
– It can be reformulated with a title and an extended description;
– An event may trigger an action when it is detected.
The classification of events is defined by the user through classification rules which are provided
to the report plug-in via configuration files in JSON format. A typical invocation of Frama-C with
classification has the following structure:
> frama-c -report-rules <file>.json ...other plugins... -then -report-classify
The collection of events starts once the classification rules have been loaded. Finally, a classification
report is build. There are various options to tune the classification process and the reporting output.
See section 11.3.6 for details.
Remark: it is possible to emit different classification reports successively from the command line. At
each -report-classify, the pool of collected events is flushed and will not be included in subsequent
reports.
11.3.1 Action
Classified events can trigger one of the following actions:
SKIP the event is filtered out and not included in the final report;
INFO the event is kept for user information;
REVIEW the event shall be carefully read by the user, it contains verifications to be performed by hand
to guarantee the soundness of the provided results;
ERROR all the results shall be considered wrong due to improper use of the tool.
By default, Frama-C warnings shall trigger a REVIEW action and errors an ERROR one. However, it
is possible to modify actions with classification rules.
46
11.3. CLASSIFICATION
11.3.2 Rules
Each classification rule is a JSON record following the structure of Figure 11.1. A file of classification
rules shall contain one rule or an array of rules. Several files can be loaded. The first rule that applies
to an event takes priority over subsequent ones.
An individual rule consists of one mandatory pattern field, and other optional fields. All the details
are provided in the figure.
{
// Optional Fields
Plug-ins are identified by their short name, typically "rte" for the Rtegen plug-in, see
frama-c -plugins for details.
Category filters apply to active warning categories2 or warning categories promoted to errors. Use
option frama-c -[plugin]-warn-key help to display the list of available warning categories
for a given plugin. Category filters use the same syntax and meaning than warning control options:
category a:b applies to all messages with category a:b[:...], but not to messages with category a
or c[:...].
When using a category filter, the pattern field can be omitted to match all warning messages of this
category.
47
11.3. CLASSIFICATION
11.3.4 Reformulation
The optional fields title and descr of a classification rule allow for a reformulation of the event.
Reformulations are plain text enriched by references to sub-parts of the matching regular expression
of the event. Hence, \* stands for the entire event message, \0 is the matched prefix, \1..\9 refers
to the corresponding sub-group of the OCaml regular expression. You can use \n to insert a new-line
character and \<c> to escape character <c>.
{
"classid": "<ident>" ;
"action": "<INFO|REVIEW|ERROR>" ;
"title": "<free text>" ;
"descr": "<free text>" ;
[ "file": "<path>" ; "line": "<number>" ; ]
}
48
11.4. SARIF OUTPUT VIA THE MARKDOWN REPORT PLUG-IN
SARIF is a JSON-based standard output format for static analysis results. It is currently supported
by Frama-C in its version 2.1.0. Some IDEs, such as Visual Code, contain plug-ins which allow
importing SARIF reports. A few Microsoft tools and libraries related to SARIF are available at https:
//sarifweb.azurewebsites.net/. Microsoft also publishes command-line tools for SARIF, made
available via NPM packages and .Net Core applications.
11.4.1 Prerequisites
SARIF output is produced by the Markdown Report (MdR) plug-in. The plug-in is distributed with
Frama-C, but it depends on optional features, namely the opam package ppx_deriving_yojson, so
it may not be available in every Frama-C installation.
When installing Frama-C via opam, include the optional dependency ppx_deriving_yojson to
ensure MdR will be available. Note that MdR has other features and output formats, which are not
described here.
49
Variadic Plug-in 12
This chapter briefly presents the Variadic plug-in, which performs the translation of calls to variadic
functions into calls to semantically equivalent, but non-variadic functions.
Variadic functions
Variadic functions accept a variable number of arguments, indicated in their prototype by an ellipsis
(. . . ) after a set of fixed arguments.
Some functions in the C standard library are variadic, in particular formatted input/output functions,
such as printf/scanf. Due to the dynamic nature of their arguments, such functions present additional
challenges to code analysis. The Variadic helps dealing with some of these challenges, reducing or
eliminating the need for plug-ins to have to deal with these special cases.
ACSL does not allow the direct specification of variadic functions: variadic arguments have no name
and no statically known type. The Variadic plug-in performs a semantically-preserving translation of
calls to such functions, replacing them with non-variadic calls.
For instance, consider the following user-defined variadic function sum, whose first argument n is the
number of elements to be added, and the remaining n arguments are the values themselves:
#include <stdarg.h> // for va_* macros
int sum(unsigned n, ...) {
int ret = 0;
va_list list;
va_start(list, n);
for(int i = 0; i < n; i++){
ret += va_arg(list, int);
}
va_end(list);
return ret;
}
int main(){
return sum(5, 6, 9, 14, 12, 1);
}
Since Variadic is enabled by default, running Frama-C on this code will activate the variadic
translation. The main differences in the translated code are:
– the prototype of sum becomes int sum(unsigned n, void * const *__va_params);
50
12.2. AUTOMATIC GENERATION OF SPECIFICATIONS FOR LIBC FUNCTIONS
This translation is similar to the relation between functions such as printf and vprintf, where
the former accepts a variable number of arguments, while the latter accepts a single va_list argument.
The most common use case of variadic functions are the ubiquitous printf/scanf, but a few other
functions in the standard C library are variadic, such as open and fcntl. The former are entirely
dependent on the format string, which can have any shape, while the latter are limited to a fixed set of
possible argument numbers and types. In both cases, it is possible to specialize the function call and
generate an ACSL specification that (1) performs some checks for undefined behaviors (e.g. that the
argument given to a %d format is a signed int), and (2) ensures postconditions about the return
value and modified arguments (namely for scanf). The Variadic plug-in generates such specifications
whenever possible.
Note that not all calls have their specification automatically generated; in particular, calls to formatted
input/output functions using non-static format strings are not handled, such as the following one:
printf(n != 1 ? "%d errors" : "%d error", n_errors);
In this case, the variadic translation is performed, but the function call is not specialized, and no
specification is automatically generated.
12.3 Usage
51
12.3. USAGE
Clang’s option -Wformat-pedantic (available at least since Clang 4.0, possibly earlier) also
enables some extra diagnostics:
printf("%p", "string");
warning: format specifies type ’void *’ but the argument has type ’char *’.
Note that no single tool is currently able to emit all diagnostics emitted by the other two.
If a conversion specification is invalid, the behavior is undefined. If any argument is not the
correct type for the corresponding conversion specification, the behavior is undefined.
Usage of %u or %x for values of type unsigned char and unsigned short. The warning
emitted by Variadic in this case will mention a signed type being cast to unsigned. Albeit counter-
intuitive, this is a consequence of the fact that default argument promotions take place for variadic
arguments, and thus unsigned char and unsigned short arguments are promoted to (signed)
int, which is incompatible with %u and %x.
To avoid the warning, use the appropriate length modifiers: hh for char and h for short.
Usage of %o, %x and %X to print signed values. The standard specifies that all of these modifiers
expect unsigned arguments. A cast to the corresponding unsigned type must therefore be present.
52
Analysis Scripts 13
This chapter describes some tools and scripts shipped with Frama-C to help users setup and run analyses
on large code bases. These scripts can also help dealing with unfamiliar code and automating analyses.
13.1 Requirements
Python : most scripts are written using Python 3. Some scripts require features from specific Python
versions, and perform version checks when starting.
GNU Make : the main workflow for analysis scripts consists in using GNU Make (4.0 or newer) to
compute dependencies and cache intermediate results.
Bash : some scripts are written in Bash.
Besides those, a few tools are occasionally required by the scripts, such as Perl and GNU Parallel.
13.2 Usage
Most scripts are accessible via the frama-c-script command, installed along with Frama-C. Running
this command without any arguments prints the list of commands, with a brief description of each
of them. Some extra scripts are available by directly running them; in both cases, the actual scripts
themselves are installed in Frama-C’s lib directory, underneath analysis-scripts.
53
13.2. USAGE
2. The user configures the initial analysis (see Section 13.2.2 below);
3. The user edits and runs the generated Makefile, adjusting the analysis as needed and re-running
fcmake1 .
Ideally, after modifying the source code or re-parametrizing the analysis, re-running fcmake should
be enough to obtain a new result.
Section 13.3 details usage of the Makefile and presents an illustrative diagram.
One at a time
In this workflow, the user starts from the entry point of the analysis: typically the main function
of a program or a test case. Only the file defining that function is included at first. Then, using
make-wrapper (described in section 13.4), the user iteratively adds new sources as needed, so that all
function definitions are included.
1 fcmake is described in Section 13.3.
2 See Section 3.4 for details about FRAMAC_LIB.
54
13.3. USING THE GENERATED MAKEFILE, VIA FCMAKE
– Advantages: higher code coverage; faster preprocessing/parsing; and avoids including possibly
unrelated files (e.g. for an alternative OS/architecture).
– Drawbacks: the iterative approach recomputes the analysis several times; also, it may miss files
containing global initializers, which are not flagged as missing.
All-in
In this workflow, the user adds all source files to the analysis, and if necessary removes some of them,
e.g. when there are conflicting definitions, such as when multiple test files define a main function.
– Advantages: optimistic approach; may not require any extra iterations, if everything is defined,
and only once. Does not miss global initializers, and may find issues in code which is not reachable
(e.g. syntax-related warnings).
– Drawbacks: preprocesses and parses several files which may end up never being used; smaller
code coverage; if parsing fails, it may be harder to find the cause (especially if due to unnecessary
sources).
The generated Makefile can be used to run one or several analyses. Its basic usage involving the fcmake
alias (equivalent to make -C .frama-c) is the following:
– fcmake <target>.parse: parse the sources
– fcmake <target>.eva: run Eva
– fcmake <target>.eva.gui: open the results in the GUI
This section details how to produce the Makefile, how to define the fcmake alias, and lists other
useful targets and settings.
55
13.3. USING THE GENERATED MAKEFILE, VIA FCMAKE
Figure 13.1: Overview of the analysis-scripts workflow: the inputs on the left produce a GNUmakefile
which is then used for parsing, analyzing and visualizing results.
56
13.3. USING THE GENERATED MAKEFILE, VIA FCMAKE
Target names can contain hyphens and underscores, but neither slashes nor dots. See also the Technical
Notes section about some current limitations.
Then, for each .parse target, a corresponding .eva target needs to be added to the TARGETS
variable in the Makefile. This will run Eva on the test case.
Each .eva target depends on its corresponding .parse target; if the sources change, the analysis
must take into account the new AST.
TARGETS : as mentioned before, must contain the list of targets, suffixed with .eva.
CPPFLAGS : preprocessing options, passed to Frama-C inside option -cpp-extra-args, when
parsing the sources.
FCFLAGS : extra command-line options given to Frama-C when parsing the sources and when running
analyses. Typically, the options given to the Frama-C kernel.
EVAFLAGS : extra command-line options given to Eva when running its analyses.
These variables are defined globally, but they can also be customized for each target; for instance, if
a given target t1 has a main function test1 and requires a global macro -DTEST1, but target t2’s
main function is test2 and it requires -DTEST2, you can locally modify FCFLAGS and CPPFLAGS as
follows:
t1.parse: FCFLAGS += -main test1
t1.parse: CPPFLAGS += -DTEST1
t2.parse: FCFLAGS += -main test2
t2.parse: CPPFLAGS += -DTEST2
-I flags referencing relative paths must take into account the fact that Frama-C will be run from the
.frama-c directory, and therefore must include an initial “../”.
all (default target) : the default target simply calls <target>.eva, for each <target> added to
variable TARGETS. Does nothing once the analysis is finished and saved.
<target>.parse : runs Frama-C on the specified target, preprocessing and parsing its source files.
Produces a directory <target>.parse containing several logs, a pretty-printed version of the
parsed code, and a Frama-C session file (framac.sav) to be loaded in the GUI or by other
analyses. Does nothing if parsing already happened.
57
13.4. SCRIPT DESCRIPTIONS
<target>.eva : loads the parsed result (from the .parse target) and runs the Eva plug-in, with the
options given in EVAFLAGS. If the analysis succeeds, produces a directory <target>.eva with
the analysis results and a saved session file. If the analysis fails, tries to save a partial result in
<target>.eva.error (when possible).
<target>.eva.gui : loads the result of the corresponding <target>.eva session and opens it in the
GUI. This allows inspecting the results of Eva. This target always opens the GUI, even when no
changes have happened.
clean : removes all results produced by the .parse and .eva targets.
The most useful commands are described below. Run frama-c-script help for more details and
optional arguments.
make-wrapper <target> <args> : calls make <target> <args> with a special wrapper: when
running Eva, upon encountering one of a few known error messages, suggests some actions on how
to proceed. For instance, if a missing function definition is encountered when analyzing the code
with Eva, the wrapper will look for its definition and, if found, suggest that its source code be
added to the analysis. This script is meant to be used with the one at a time workflow described
in section 13.2.3.
find-fun <fun> : looks for possible declarations and definitions of function <fun>. Uses a heuristic
that does not depend on Frama-C being able to parse the sources. Useful to find entry points and
missing includes.
58
13.5. PRACTICAL EXAMPLES: OPEN SOURCE CASE STUDIES
configure <machdep> : runs a configure script (based on Autoconf) with some settings to
emulate a more portable system, removing optional code features that could prevent Frama-C from
parsing the sources. Currently, it still depends partially on the host system, so many features are
not disabled.
flamegraph : opens a flamegraph3 to visualize which functions take most of the time during analysis
with Eva.
summary : for monitoring the progression of multiple analyses defined in a single Makefile. Presents a
summary of the analyses when done. Mostly useful for benchmarking or when dealing with several
test cases.
normalize-jcdb : converts absolute paths inside a compile_commands.json file into relative paths
(w.r.t. PWD) when possible. Used to allow moving/versioning the directory containing the JCDB
file.
Finally, there is the following script, which is not available as a command in frama-c-script,
since its usage scenario is very different. It is available at
$FRAMAC_LIB/analysis-scripts/creduce.sh.
creduce.sh : A script to help running the C-Reduce4 tool to minify C programs causing crashes
in Frama-C; useful e.g. when submitting a bug report to Frama-C, without needing to submit
potentially confidential data. The script contains extensive comments about its usage. It is also
described in a post5 from the Frama-C blog.
To use the creduce.sh script, you need to have the C-Reduce tool installed in your path or in
environment variable CREDUCE.
59
13.6. TECHNICAL NOTES
This section lists known issues and technical details which may help users understand some unintuitive
behaviors.
Changes to header files do not trigger a new parsing/analysis. Currently, changes to included
files (e.g. headers) are not tracked by the generated Makefile and may require running fcmake with -B
(to force recomputation of dependencies), or running fcmake clean before re-running fcmake.
Most commands are experimental. These analysis scripts are a recent addition and subject to
changes. They are provided on a best-effort basis.
60
Compliance 14
Frama-C provides sound analyses for several kinds of code defects. Given the large amount of covered
defects and command-line options which toggle their reporting, we provide in this chapter information
about standards compliance, coding guidelines and related documents, such as the ISO C standard,
CWEs, CERT C, etc.
This chapter is not exhaustive; in particular, some defects are implicitly checked without any
controlling options; others may be affected by a combination of several options which is hard to precisely
express.
Please contact the Frama-C team if you require a thorough evaluation of the standards cited here, or
of different ones. This reference is provided on a best-effort basis.
The table below lists features of the C99 standard (ISO/IEC 9899:1999) which are currently unsupported
by Frama-C. Please contact the Frama-C team if you would like them be to supported.
Feature Details
_Complex/_Imaginary types are not natively supported in OCaml.
Complex/Imaginary types Lack of user demand led to the absence of their implementation in
Frama-C.
Nested variable-length arrays (VLAs), that is, int t[a][a] where a is
Nested VLAs not a compile-time constant, are currently unsupported. VLAs with a
single variable dimension are supported.
Some prototypes and stubs are available in the fenv.h and fenv.c
Floating-point environ-
files provided in Frama-C’s standard library (Section 5.9), but they are
ment
incomplete.
The table below lists features of the C11 standard (ISO/IEC 9899:2011) which are currently
unsupported by Frama-C. Please contact the Frama-C team if you would like them be to supported.
Feature Details
Currently not supported by the Frama-C kernel. Also, ACSL does not
_Alignas / _Alignof
currently include alignment-related predicates.
_Atomic Currently unsupported (ignored) by the Frama-C kernel.
61
14.2. FRAMA-C OPTIONS RELATED TO C UNDEFINED BEHAVIORS
Feature Details
u/U character constants, u8/u/U string literals, and \u escape sequences
are currently unsupported by the lexer. Note: in a few cases, such as
Unicode
ACSL specifications, some \u escape sequences are allowed (e.g. for
ACSL symbols such as ∈, Z, etc).
As in C99 (see Table 14.1). Note that C11 made complex types optional
Complex/Imaginary types
(they were required in C99).
As in C99 (see Table 14.1). Note that C11 made variable-length types
Nested VLAs
optional (they were required in C99).
This section lists several Frama-C options affecting (either enabling or disabling) the detection of
unspecified and undefined behaviors listed in Annexes J.1 and J.2 of the C11 standard (ISO/IEC
9899:2011).
Note: the ISO C standard does not provide an identifier for each behavior; therefore, we use the
numbers listed in SEI CERT C Coding Standard’s Back Matter, sections CC. Undefined Behavior and
DD. Unspecified Behavior, whenever possible. These tables can be found at https://wiki.sei.cmu.
edu/confluence/display/c. Note that SEI CERT does not list implementation-defined behaviors;
in such cases, we simply refer to the related section in the ISO C standard.
Table 14.3: Impact of some Frama-C options on a few unspecified and undefined behaviors.
62
14.3. RTE CATEGORIES AND C UNDEFINED BEHAVIORS
This section presents the correspondence between runtime execution (RTE) alarms emitted by the Eva
plugin and C undefined behaviors.
Table 14.4: Correspondence between Frama-C’s runtime error categories and C’s undefined behaviors.
Note that some undefined behaviors, such as CC.100, CC.191, CC.192 and others, are not handled
by specific categories of RTEs, but instead by ACSL specifications in Frama-C’s libc. These specifications
are used by some analyzers and result in warnings and errors when violated.
Note about ptrdiff_t CC.50 deals with pointer subtractions, related to type ptrdiff_t. Frama-
C does not perform specific handling for this type, but in all standard machdeps defined in Frama-C,
its definition is such that pointer subtraction will lead to a signed overflow if the difference can-
not be represented in ptrdiff_t, thus preventing the undefined behavior. However, if option
-no-warn-signed-overflow is used, or in a custom machdep, this may not hold.
63
14.4. C UNDEFINED BEHAVIORS NOT HANDLED BY FRAMA-C
This section lists some of the C undefined behaviors which are currently not directly covered by the
open-source version of Frama-C.
The list includes UBs which are delegated to other tools, such as the preprocessor or the compiler.
Frama-C does not preprocess the sources, relying on external preprocessors such as GCC’s or Clang;
therefore, related UBs are out of the scope of Frama-C and listed below, even though in practice they
are verified by the underlying preprocessor in all but the most exotic architectures.
For a few UBs of syntactic nature, which are always detected during compilation, Frama-C delegates
the task to the compiler. This implies that, when running Frama-C directly on the code, it may not
complain about them; but the code will generate an error during compilation anyway, without requiring
specific compilation flags.
This list is not exhaustive; in particular, some UBs not listed here are partially handled by Frama-C.
Please contact the Frama-C team if you would like more information about whether a specific set of UBs
is handled by the platform.
UB Notes
CC.2 Syntactic; out of the scope of Frama-C’s analyzers.
CC.3 Out of scope (lexing/preprocessing-related).
CC.5 Requires concurrency analysis; the Mthread plugin can provide some guarantees.
Only applies to implementations not following IEEE-754. Frama-C’s machdeps assume they
CC.14
do.
Only applies to implementations not following IEEE-754. Frama-C’s machdeps assume they
CC.18
do.
CC.27 Out of scope (lexing/preprocessing-related).
CC.28 Out of scope (lexing/preprocessing-related).
CC.30 Out of scope (lexing/preprocessing-related).
CC.31 Out of scope (lexing/preprocessing-related).
CC.34 Out of scope (lexing/preprocessing-related).
CC.58 Syntactic; delegated to the compiler.
CC.59 Syntactic; delegated to the compiler.
CC.90 Out of scope (lexing/preprocessing-related).
CC.91 Out of scope (lexing/preprocessing-related).
CC.92 Out of scope (lexing/preprocessing-related).
CC.93 Out of scope (lexing/preprocessing-related).
CC.94 Out of scope (lexing/preprocessing-related).
CC.95 Out of scope (lexing/preprocessing-related).
CC.96 Out of scope (lexing/preprocessing-related).
This section lists some CWEs handled by Frama-C, as well as some which are currently out of the scope
of Frama-C’s default plugins. The latter may be handled by specialized analyses, such as plugins not
currently distributed with the open-source release of Frama-C, or in future evolutions of the Frama-C
platform.
Note that, due to the large amount of existing CWEs, and the fact that mapping them to undefined
64
14.5. COMMON WEAKNESS ENUMERATIONS (CWES) REPORTED AND NOT REPORTED BY
FRAMA-C
behaviors is not always straightforward, there are likely several other CWEs which are already handled by
Frama-C, at least in some contexts. Please contact the Frama-C team if you would like more information
about whether a specific set of CWEs is handled by some analysis in the platform.
Remark: this section is partially based on work related to NIST’s Software Assurance Metrics and
Tool Evaluation (SAMATE1 ), namely its Static Analysis Tool Expositions (SATE), which allowed us to
identify some of the CWEs which Frama-C already can or cannot handle. The CWEs listed here are
mostly those present in Juliet’s 1.3 C/C++ test suite, available at NIST SAMATE’s website. Several
caveats apply; for instance, some Juliet tests marked as bad (that is, exhibiting a weakness) only do so
for specific architectural configurations, e.g. 32-bit pointers. If Frama-C is run with a different machdep,
the test may not exhibit any undefined behavior, as the weakeness is not actually present for such
architectures. A rigorous assessment of such situations is necessary for strong claims of soundness.
In Table 14.6, the Status column summarizes the current handling of the CWE by Frama-C, as one
of the following:
Handled means Frama-C already handles the CWE; in some cases, its detection may be controlled by
command-line options;
Partially Handled means the CWE is handled only in some specific cases; Frama-C can thus help
detect occurrences of this CWE, but not prove their absence;
Annotations means the CWE could be handled by Frama-C, but some development is required; in
practice, this often means user annotations will be required, e.g. for specifying the source of
tainted data; this often implies adding a new abstract domain to Eva, or modifying the analyzer
to propagate the data provided by the annotations;
Syntactic means the CWE is of a syntactic nature, while Frama-C specializes in semantic analyses; it
is currently not handled by Frama-C and could probably be so, if a user required it; but it is not
the primary concern of the platform developers.
Too Vague means the CWE is either too vague or too broad to be formally matched to a given set of
properties that Frama-C can verify.
Table 14.6: CWEs handled and not currently handled by Frama-C’s open-source plugins. The Notes
column may contain references to the command-line options table (14.3). The descriptions in the Status
column are detailed above.
65
14.5. COMMON WEAKNESS ENUMERATIONS (CWES) REPORTED AND NOT REPORTED BY
FRAMA-C
Table 14.6: CWEs handled and not currently handled by Frama-C’s open-source plugins. The Notes
column may contain references to the command-line options table (14.3). The descriptions in the Status
column are detailed above.
66
14.5. COMMON WEAKNESS ENUMERATIONS (CWES) REPORTED AND NOT REPORTED BY
FRAMA-C
Table 14.6: CWEs handled and not currently handled by Frama-C’s open-source plugins. The Notes
column may contain references to the command-line options table (14.3). The descriptions in the Status
column are detailed above.
67
14.5. COMMON WEAKNESS ENUMERATIONS (CWES) REPORTED AND NOT REPORTED BY
FRAMA-C
Table 14.6: CWEs handled and not currently handled by Frama-C’s open-source plugins. The Notes
column may contain references to the command-line options table (14.3). The descriptions in the Status
column are detailed above.
68
14.5. COMMON WEAKNESS ENUMERATIONS (CWES) REPORTED AND NOT REPORTED BY
FRAMA-C
Table 14.6: CWEs handled and not currently handled by Frama-C’s open-source plugins. The Notes
column may contain references to the command-line options table (14.3). The descriptions in the Status
column are detailed above.
Note about Numerical Conversions A few CWEs (CWE-194, CWE-195, CWE-196 and CWE-197)
related to numerical conversion issues do not map directly to undefined behaviors (except, in some cases,
to CC.36); some of them are related to unspecified and implementation-defined behaviors. Frama-C
has a set of command-line options to enable warnings related to these conversions, when they can
overflow or generate unexpected values: -warn-signed-overflow, -warn-unsigned-overflow,
-warn-signed-downcast, and -warn-unsigned-downcast.
See Section 7.3 for more details and some examples related to these options.
Also note that conversion from a floating-point value to an integer may overflow; in this case, an
69
14.5. COMMON WEAKNESS ENUMERATIONS (CWES) REPORTED AND NOT REPORTED BY
FRAMA-C
70
Reporting Errors 15
If Frama-C crashes or behaves abnormally, you are invited to report an issue via the Frama-C Gitlab
repository, located at https://git.frama-c.com. The New Issue page (https://git.frama-c.
com/pub/frama-c/issues/new) allows creating a new report, but you will need an account.
Unless you have an account provided by the Frama-C team, you need to sign in using a Github account,
as shown in Figure 15.1.
Figure 15.1: The Frama-C Gitlab login page. Note that no direct account creation is possible; you need
to sign in via Github unless the Frama-C team provided you an account.
When creating a new issue, choose the bug_report template next to Title, then enter the title and
fill the template.
Bug reports can be marked as public or confidential. Public bug reports can be read by anyone and
may be indexed by search engines. Confidential bug reports are only shown to Frama-C developers.
Reporting a new issue opens a webpage similar to the one shown in Figure 15.2.
Please fill the template as precisely as possible, in English 1 , which helps the Frama-C team more
71
Figure 15.2: The Gitlab new issue page, with the bug_report template. The checkbox at the bottom
enables marking the issue as private, so that only Frama-C developers can see it.
72
quickly understand, reproduce and respond to the issue. The form uses Markdown syntax and you can
attach source files and screenshots to the issue.
Replies and updates concerning your issue are sent by e-mail by Gitlab.
73
Changes A
This chapter summarizes the changes in this documentation between each Frama-C release. First we list
changes of the last release.
27.0 (Cobalt)
26.0 (Iron)
– Removed Journalisation
– Preparing the Sources: added option -ast-diff.
– Setting Up Plug-ins: removed options -add-path and -load-script, and added option
-load-library.
24.0 (Chromium)
23.0 (Vanadium)
22.0 (Titanium)
74
– Reports: add section about SARIF output (via Markdown Report).
21.0 (Scandium)
20.0 (Calcium)
– Normalizing the Source Code: added options -keep-unused-types and its opposite,
-remove-unused-types.
18.0 (Argon)
Chlorine-20180501
Sulfur-20171101
75
– Normalizing the Source Code: removed option -custom-annot-char.
Phosphorus-20170501
Silicon-20161101
Aluminium-20160501
Magnesium-20151001
– Getting Started: support is not guaranteed for OCaml versions below 4.x.
– Getting Started: the recommended installation method now consists in using the Frama-C
OPAM package.
– Normalizing the Source Code: option -pp-annot is now active by default.
– Normalizing the Source Code: added section about macros predefined by Frama-C (Section 5.7).
– Normalizing the Source Code: document new option -custom-annot-char (Section 5.4)
– Normalizing the Source Code: document handling of new file suffix .ci (Section 5.2)
– Preparing the Sources: option -warn-undefined-callee changed to
-implicit-function-declaration warn.
– Setting Up Plug-ins: removed option -dynlink.
Sodium-20150201
76
– Preprocessing the Source Files: new options -cpp-gnu-like and -frama-c-stdlib.
– Customizing Analyzers: new options -add-symbolic-path and -permissive.
– Getting Started: document options containing several values (aka set and map).
– Getting Started: improve documentation of options.
– Getting Started: document new option -then-last.
– Getting Started: document new option -tty.
Neon-20140*01
Fluorine-20130*01
Oxygen-20120901
Nitrogen-20111001
77
– Getting Started: update options for controlling display of floating-point numbers
– Preparing the sources: document generation of assigns clause for function prototypes without
body and proper specification
– Property Statuses: new chapter to document property statuses.
– GUI: document new interface elements.
Carbon-20110201
– Getting Started: exit status 5 is now 127; new exit status 5 and 6.
– GUI: document new options -collect-messages.
Carbon-20101201
Boron-20100401
– Preparing the Sources: document usage of the C standard library delivered with Frama-C
– Graphical User Interface: simplified and updated according to the new implementation
– Getting Started: document environment variables altogether
– Getting Started: document all the ways to getting help
– Getting Started: OcamlGraph 1.4 instead 1.3 will be used if previously installed
– Getting Started: GtkSourceView 2.x instead of 1.x is now required for building the GUI
– Getting Started: documentation of the option -float-digits
– Preparing the Sources: documentation of the option -continue-annot-error
– Using plug-ins: new option -dynlink
– Journalisation: a journal is generated only whenever Frama-C crashes on the GUI
– Configure: new option --with-no-plugin
– Configure: option --with-all-static set by default when native dynamic loading is not
available
Beryllium-20090902
78
Bibliography
[1] Mounir Assaf. From Qualitative to Quantitative Program Analysis: Permissive Enforcement of
Secure Information Flow. PhD thesis, Université Rennes 1, May 2015.
[2] Gergö Barany and Julien Signoles. Hybrid Information Flow Analysis for Real-World C Code. In
International Conference on Tests and Proofs (TAP’17), July 2017.
[3] Patrick Baudin, Pascal Cuoq, Jean-Christophe Filliâtre, Claude Marché, Benjamin Monate, Yannick
Moy, and Virgile Prevosto. ACSL: ANSI/ISO C Specification Language. Version 1.16, November
2020.
[4] Patrick Baudin, Pascal Cuoq, Jean-Christophe Filliâtre, Claude Marché, Benjamin Monate, Yan-
nick Moy, and Virgile Prevosto. ACSL: ANSI/ISO C Specification Language. Version 1.16 – as
implemented in Frama-C 22.0, November 2020.
[5] Patrick Baudin and Anne Pacalet. Slicing plug-in. http://frama-c.com/slicing.html.
[6] David Cok. Frama-C’s Frama-Clang plug-in, 2021. https://www.frama-c.com/download/
frama-clang-manual.pdf.
[7] Loïc Correnson, Zaynah Dargaye, and Anne Pacalet. Frama-C’s WP plug-in, February 2015.
http://frama-c.com/download/frama-c-wp-manual.pdf.
[8] Loïc Correnson and Julien Signoles. Combining Analysis for C Program Verification. In Formal
Methods for Industrial Critical Systems (FMICS), August 2012.
[9] Pascal Cuoq, Florent Kirchner, Nikolai Kosmatov, Virgile Prevosto, Julien Signoles, and Boris
Yakobowski. Frama-C, A software Analysis Perspective. In Software Engineering and Formal
Methods (SEFM), October 2012.
[10] Pascal Cuoq, Boris Yakobowski, and Virgile Prevosto. Frama-C’s value analysis plug-in, February
2015. http://frama-c.com/download/frama-c-eva-manual.pdf.
[11] Philippe Herrmann and Julien Signoles. Annotation Generation: Frama-C’s RTE plug-in, April
2013. http://frama-c.com/download/frama-c-rte-manual.pdf.
[12] Florent Kirchner, Nikolai Kosmatov, Virgile Prevosto, Julien Signoles, and Boris Yakobowski. Frama-
C: A software analysis perspective. Formal Aspects of Computing, pages 1–37, 2015. Extended
version of [9].
[13] Michaël Marcozzi, Sébastien Bardin, Mickaël Delahaye, Nikolai Kosmatov, and Virgile Prevosto.
Taming coverage criteria heterogeneity with ltest. In 2017 IEEE International Conference on
Software Testing, Verification and Validation, ICST 2017, Tokyo, Japan, March 13-17, 2017, pages
500–507, 2017.
[14] Virgile Robles, Nikolai Kosmatov, Virgile Prévosto, Louis Rilling, and Pascale Le Gall. MetAcsl:
Specification and Verification of High-Level Properties. In TACAS 2019, volume 11427 of LNCS,
Prague, Czech Republic, April 2019.
79
BIBLIOGRAPHY
[15] Julien Signoles, Thibaud Antignac, Loïc Correnson, Matthieu Lemerre, and Virgile Prevosto. Frama-
C Plug-in Development Guide, February 2015.
http://frama-c.com/download/frama-c-plugin-development-guide.pdf.
[16] Julien Signoles, Basile Desloges, and Kostyantyn Vorobyov. Frama-C’s E-ACSL Plug-in. https:
//frama-c.com/fc-plugins/e-acsl.html.
[17] Boris Yakobowski and Richard Bonichon. Frama-C’s Mthread plug-in, 2012.
http://frama-c.com/download/frama-c-mthread-manual.pdf.
80
List of Figures
5.1 Overview of source preparation steps: as performed by GCC (top) and as performed by
Frama-C (bottom). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
13.1 Overview of the analysis-scripts workflow: the inputs on the left produce a GNUmakefile
which is then used for parsing, analyzing and visualizing results. . . . . . . . . . . . . . 56
15.1 The Frama-C Gitlab login page. Note that no direct account creation is possible; you
need to sign in via Github unless the Frama-C team provided you an account. . . . . . . 71
15.2 The Gitlab new issue page, with the bug_report template. The checkbox at the bottom
enables marking the issue as private, so that only Frama-C developers can see it. . . . . 72
81
Index
82
INDEX
-lib-entry, 32 -then, 16
-load, 39, 40 -then-last, 17, 17, 39
-load-library, 20 -then-on, 16, 39
-load-plugin, 20 -then-replace, 17, 39
-time, 18
-machdep, 26, 28, 29 -tty, 18
-main, 32 -typecheck, 30
Native-compiled, 14 -ulevel, 16, 24, 26, 40
-no-autoload-plugins, 20 -ulevel-force, 26
-no-cpp-frama-c-compliant, 29 -unicode, 18, 40
-no-unicode, 15 -unsafe-arrays, 33
-unspecified-access, 34
OCaml compiler, 13
OCAMLPATH, 20 Variadic, 50, 50–52
-ocode, 18 -variadic-no-strict, 51
opam, 13 -variadic-no-translation, 51
Options, 14 -verbose, 17, 40
-version, 14
-permissive, 33
Plug-in -warn-decimal-float Deprecated option, 30
External, 20, 20 -warn-invalid-bool, 35
Internal, 20 -warn-invalid-pointer, 34
-plugins, 14, 15 -warn-left-shift-negative, 35
-pp-annot, 23 -warn-pointer-downcast, 35
Pragma -warn-right-shift-negative, 35
UNROLL, 26 -warn-signed-downcast, 35
-print, 18, 24 -warn-signed-overflow, 35
-print-config, 15 -warn-special-float, 35
-print-config-json, 15 -warn-unsigned-downcast, 35
-print-cpp-commands, 23 -warn-unsigned-overflow, 35
-print-lib-path, 15, 20 warning status, 33
-print-libc, 18 -wp-no-print, 15
-print-plugin-path, 15, 20 -wp-print, 15
-print-share-path, 15, 20
-print-version, 15
Project, 39
-quiet, 17, 40
-remove-inlined, 25
-remove-projects, 39
-remove-unused-specified-functions, 25
-remove-unused-types, 25
report, 45
-safe-arrays, 34
-save, 39, 40
-semantic-const-fold, 17
-session, 19
-set-project-as-default, 17
-simplify-cfg, 26
-simplify-trivial-loops, 26
-slevel-function, 16
83