3. Project Setup
GNAT SAS requires a GNAT project file (a.k.a. GPR project file) to run. If you are using a third party compiler, this chapter starts with a quick walk-through for the creation of an initial gpr file, as well as common configuration for this setup. If you already have a project file that you use to compile with gprbuild, you should look at the second section to ensure that it works well with GNAT SAS.
Finally, the last section explains how to configure the GNAT SAS analysis and goes on with describing specific configurations of integrated engines.
See also
Refer to the GNAT Project Manager section of the GPR Tool's User Guide for general documentation about projects.
3.1. Configuration for Third Party Compilers
This section guides you through the typical steps to setup your project in order to use GNAT SAS when you do not use GNAT to compile your sources.
First, you need to create a GPR project file. In order to do so we recommend using codepeer-gprname as described here. Indeed, while the resulting project file needs to be updated each time you modify the sources included in the project, codepeer-gprname will highlight early problems that the analysis would eventually encounter.
At this stage, the project file should contain enough information to identify all the sources of the project (if you used codeper-gprname, they are listed in the
prj_source_list.txt
file). By default, GNAT SAS will analyze all of them. However, if there are files that you do not wish to analyze, these should be excluded from the analysis in a second stage (see this section). Indeed, the project should be as "compilable" as possible for the analysis to perform correctly.Warning
Your project should not include the sources of your run-time.
You should set your target to "gnatsas" with the Target attribute:
project <project_name> is for Target use "gnatsas"; […]
You should not use the Runtime attribute, in particular Section Using the GNAT Target Runtime Directory does not apply since it only works with a runtime from GNAT.
You may want to specify a Target Configuration File in order to provide target dependent values, such as endianness, type sizes, etc.
If you use supported compiler-specific packages, you need to set your project file to use them.
Once done, you should be able to confirm that the project is properly set up by running a first analysis with the command:
gnatsas analyze -P <project_name>.gpr
You can then look at how to run the tool in this section, and complete your project file by Configuring the Analysis.
3.2. Creating a Project File
In this section, we present different ways to create a project file if your project does not yet contain one:
Create a project file interactively using the Project Wizard in GNAT Studio;
Create a project file manually;
Use codepeer-gprname to automatically generate it.
We recommend taking the time to follow either option 1 or 2, as the generated project files in option 3 may be hard to understand, modify and hence maintain.
3.2.1. Creating a Project File with GNAT Studio
Please refer to GNAT Studio's documentation to discover how to generate project files from GNAT Studio using the Project Wizard.
3.2.2. Creating a Project File Manually
If your source code follows the default naming scheme (.ads
/
.adb
), then you can create a project file that will look like:
project My_Project is
for Source_Dirs use ("./**");
for Target use "gnatsas";
end My_Project;
saved in a file called my_project.gpr
located in the root of the project
tree. Note that you can specify as many source directories as needed as part of
the Source_Dirs
setting. The special syntax dir/**
represents the
directory dir
and all its subdirectories recursively (in the above
example, the current directory represented by .
and all its
subdirectories). Specifying gnatsas
for the target will allow the
analysis engines to find the Ada runtime bundled with GNAT SAS.
3.2.3. Generating a Project File
A project file can be generated from an existing directory structure using the
codepeer-gprname
utility. Whenever a new source file is added to the
project or an existing source file is removed, codepeer-gprname
needs to
be re-run to update the project.
Here is the typical usage of codepeer-gprname
:
codepeer-gprname -Pmy_project "-d./**" "*.ad?" "*.spc" "*.bdy"
It will create or update a project file called my_project.gpr
listing
all the Ada source files found under the current directory and all its
subdirectories, whose name follow the given patterns (all files ending with
.ad<any character>
, all files ending with .spc
and all files ending with
.bdy
).
Note that codepeer-gprname
requires a writable temporary directory. If the
project file generated is empty, you might need to set the environment variable
TMPDIR
to a writable directory.
See the gprname documentation in the GNAT User's Guide for more details on
how to use gprname
.
3.3. Ensuring compatibility with GNAT SAS
Note
This section assumes that a project file has been defined for the codebase to analyse. If that is not the case, refer to the instructions in Creating a Project File.
This section describes how to configure the project file so that:
specificities of the code to analyze and of the target are taken into account;
general aspects related to the analysis of Ada packages are considered;
specific aspects related to GNAT SAS analysis engines that rely on the GNAT compiler are taken into account;
ultimately, it can be correctly understood by GNAT SAS.
Warning
This section does not describe the configuration of the GNAT SAS analysis. That is described in Configuring the Analysis.
3.3.1. Using GNAT SAS-Specific Project Settings
If you are using project files also to build with GNAT and need to use e.g.
different builder switches between GNAT builds and GNAT SAS analysis, you can
then use the predefined GPR_TOOL
variable to differentiate the two modes in
your project file:
Tool := External ("GPR_TOOL", "");
package Builder is
case Tool is
when "gnatsas" =>
for Global_Compilation_Switches ("Ada") use ("-gnatI");
-- -gnatI is only relevant for GNAT SAS
when others =>
for Global_Compilation_Switches ("Ada") use ("-O", "-g");
-- Switches only relevant when building
end case;
end Builder;
In GNAT SAS 24, GPR_TOOL
is set automatically by GNAT SAS to
gnatsas
, so you do not need any extra configuration or command line
switches to use the above.
3.3.2. Support for UTF-8 encoding
GNAT SAS is able to analyze source files that have UTF-8 encoding.
Simply add the GNAT switch -gnatW8
to the Compiler package as below.
GNAT SAS will report messages from Infer, GNAT Warnings and GNATcheck
with UTF-8 encoding. See the
Wide_Character Encodings
section in the GNAT User's Guide for more details.
package Compiler is
for Switches ("Ada") use ("-gnatW8");
end Compiler;
Warning
Concatenation of -gnatW8
with other switches is not supported.
Please specify -gnatW8
independently from other switches.
E.g. use -gnatiw -gnatW8
instead of -gnatiwW8
.
Note
For Inspector messages, UTF-8 encoding is not fully supported. UTF-8 characters are converted to a different representation and the GNAT SAS output may become hard to read.
To be able to use identifiers with characters outside of the Latin-1
character set, typically UTF-8 characters, one may also use the -gnatiw
switch as described below. See the
Character Set Control
section in the GNAT User's Guide for more details.
package Compiler is
for Switches ("Ada") use ("-gnatW8", "-gnatiw");
end Compiler;
3.3.3. Use of Libraries Installed with GNAT
If your project uses some of the libraries installed with GNAT (e.g. GNATcoll, XML/Ada, AWS...) and, when launching GNAT SAS, you encounter a message similar to:
gnatcoll.gpr (4 items)
unknown project file: "gpr"
Then add the following section to your project file to use the "gnatsas"
runtime packaged with the GNAT SAS installation:
for Target use "gnatsas";
3.3.4. Use of Predefined Ada Packages
The predefined Ada packages (in particular, children of Ada, System, and Interfaces) come packaged with GNAT SAS. Make sure your project file does not include alternative predefined Ada source packages that may be provided by some Ada compilers, since these predefined packages may contain non-portable constructs that GNAT SAS may not recognize.
For compiler-specific packages, see Use of Compiler-Specific Packages for accessing some of these. If this isn't sufficient, you will need to include at least the package specs from your target compiler as part of your project file as for any other source file.
3.3.5. Use of Compiler-Specific Packages
If your Ada code base uses compiler-specific packages, GNAT SAS provides some of
these packages pre-installed under install/share/gpr
and accessible as
pre-configured project files.
In particular you will find the following project files:
aa.gpr
: ApexAda specific packages.am.gpr
: AdaMulti and AdaMagic specific packages.oa.gpr
: ObjectAda specific packages.vads.gpr
: VADS specific packages.xgc.gpr
: XGC specific packages.
To use these project files, add for example the following line to your project file (adjust the name of the imported project as needed):
with "am";
project My_Project is
-- other declarations...
end My_Project;
If some compiler-specific packages are missing, do not hesitate to contact your GNAT SAS support.
3.3.6. Using Preprocessing
In order to enable preprocessing, you can use the -gnateD
and -gnatep
switches, e.g.:
package Compiler is
for Switches ("Ada") use ("-gnateDVAR1=xxx", "-gnateDVAR2=yyy");
end Compiler;
Note the use of the package Compiler here. The -gnateD
switches in the
Analyzer package are ignored. All the -gnateD
switches are accumulated
to find the defined symbols. If -gnatep
is used, it should appear only once
and the given file is used to specify the preprocessing data file. See also the
section Form of Input Text for gnatprep in chapter Preprocessing with
gnatprep for more details on the syntax supported by the preprocessor.
3.3.7. Arbitrary Naming Scheme
If you are using a different naming scheme than the default .ads
/
.adb
for your source files, you can define the naming scheme adding a
package Naming
if a single and consistent naming scheme is used for all your
source files.
For instance:
project My_Project is
...
package Naming is
for Spec_Suffix ("Ada") use ".1.ada";
for Body_Suffix ("Ada") use ".2.ada";
for Separate_Suffix use ".2.ada";
for Dot_Replacement use ".";
end Naming;
end My_Project;
or:
project My_Project is
...
package Naming is
for Spec_Suffix ("ada") use "_.ada";
for Body_Suffix ("ada") use ".ada";
for Separate_Suffix use ".ada";
for Dot_Replacement use "__";
end Naming;
end My_Project;
If more complex naming schemes are used (e.g. files with mixed casing, no automatic mapping between unit names and file names, use of multiple units in a single file, etc...) then you have three options:
In GNAT Studio: use the
menu and follow the dialog. This will call the underlying command line toolcodepeer-gprname
and modify the project file for you. See the GNAT Studio documentation for more details.Use the
codepeer-gprname
tool to generate the custom naming scheme automatically. See the section Generating a Project File for more details.Use the
codepeer-gnatchop
tool:Your sources can be preprocessed to generate
.ads/.adb
files by runningcodepeer-gnatchop
on all your Ada sources and use a simple project file on the generated sources, for instance under Linux:cd <root source directory> mkdir sources find . -name sources -prune -o -name '*.ad?' -exec codepeer-gnatchop {} sources \;
This command will take all files ending with
.ad<any character>
under the current source tree, and generate a corresponding.ads/.adb
file under a new directory calledsources
. You can then use in your project file:for Source_Dirs use ("sources");
3.3.8. Ada Language Version
Note
This section only impacts GNAT-based engines (i.e. Inspector and GNAT Warnings), and has no impact on other engines.
By default, GNAT Warnings and Inspector assume that sources use the Ada 2012 language. If your sources use an older version of Ada, then you will need to add the following to your project file:
package Builder is
for Global_Compilation_Switches ("Ada") use ("-gnat95");
end Builder;
The switches corresponding to the various Ada versions are: -gnat83
,
-gnat95
, -gnat2005
, -gnat2012
, -gnat2022
.
Note that some Ada 95 compilers support the overriding keyword but no other
Ada 2005 features. In order to analyze such code, you need to add the
-gnatd.D
switch in your project file, in addition to the -gnat95
switch:
package Builder is
for Global_Compilation_Switches ("Ada") use ("-gnat95", "-gnatd.D");
end Builder;
Note
Using Global_Compilation_Switches
in the Builder
package should be
preferred over defining the switches in the Compiler
package, since
the former applies to the whole project hierarchy, while the latter only
applies to the current project and not to subprojects.
3.3.9. Representation Clauses
Note
This section only impacts GNAT-based engines (i.e. Inspector and GNAT Warnings), and has no impact on other engines.
If GNAT Warnings or Inspector generate errors related to Ada representation
clauses, a simple way to address these errors is to add the -gnatI
compiler
switch to your project file:
package Compiler is
for Switches ("Ada") use ("-gnatI");
end Compiler;
-gnatI
instructs GNAT Warnings and Inspector to ignore representation
clauses, as if they had been stripped from the source code.
3.3.10. Target Configuration File
Note
This section only impacts GNAT-based engines (i.e. Inspector and GNAT Warnings), and has no impact on other engines.
Usually, using either the default GNAT SAS settings, the GNAT SAS --bits=32
switch (see 32-bits mode) or the Compiler package Ada's -gnatI
switch (see Representation Clauses), is sufficient to analyze code for
most targets.
If you need to configure GNAT Warnings and Inspector so that they have a deeper knowledge and understanding of the target compiler, and in particular setting target dependent values such as endianness or sizes and alignments of standard types, then you might need to add the following to your project file:
package Compiler is
for Switches ("Ada") use ("-gnateT=" & project'Project_Dir & "/target.atp");
end Compiler;
where target.atp
is a file stored here in the same directory as
the project file my_project.gpr
, which contains the target
parametrization. This file can be generated by calling the GNAT compiler
for your target with the switch -gnatet=target.atp
. The format of
this file is described in the GNAT User's Guide as part of the -gnateT
switch description.
Here is an example of a configuration file for a bare board PowerPC 750 processor configured as big-endian:
Bits_BE 1
Bits_Per_Unit 8
Bits_Per_Word 32
Bytes_BE 1
Char_Size 8
Double_Float_Alignment 0
Double_Scalar_Alignment 0
Double_Size 64
Float_Size 32
Float_Words_BE 1
Int_Size 32
Long_Double_Size 64
Long_Long_Long_Size 64
Long_Long_Size 64
Long_Size 32
Maximum_Alignment 16
Max_Unaligned_Field 64
Pointer_Size 32
Short_Enums 0
Short_Size 16
Strict_Alignment 1
System_Allocator_Alignment 8
Wchar_T_Size 32
Words_BE 1
float 6 I 32 32
double 15 I 64 64
long double 15 I 64 64
If your target compiler is not GNAT, or an old version of GNAT, then you
can also build and run the small utility called generate_target
which
can be found under <gnatsas install>/share/gnatsas/target
.
See comments inside this file for instructions on how to use it.
Note that, depending on the Ada constructs you are using and the values
specified in the target configuration file, some combinations will not be
properly supported and will lead to errors. In this case, consider using
the -gnatI
switch instead, or contact GNAT SAS support for
alternatives.
3.3.11. Using the GNAT Target Runtime Directory
Note
This section only impacts GNAT-based engines (i.e. Inspector and GNAT Warnings), and has no impact on other engines.
As a general rule, we strongly recommend using for Target use "gnatsas";
in
your project file (see Use of Libraries Installed with GNAT). If however you want to use a
specific GNAT runtime, you can do so by following the explanations given in this
section.
Warning
The runtime you intend to use must come from a version of GNAT identical to
GNATSAS' one. A runtime coming from GNAT 22.2 will not be compatible
with GNAT SAS 24.2. In such a case you will be forced to specify
for Target use "gnatsas";
Let's assume you are using GNAT as your target compiler, and explicitly specify a runtime and target to use in your project:
for Target use "arm-eabi";
for Runtime ("Ada") use "ravenscar-sfp-stm32f4";
Inspector and GNAT Warnings will take such setting into account and will use the GNAT runtime directory, as long as your target compiler is found in your PATH environment variable. As mentioned above, you will need to use a matching version of GNAT and GNAT SAS (e.g. GNAT 24.0 and GNAT SAS 24.0).
The handling of runtimes of Inspector and GNAT Warnings is in fact unified with that of the GNAT compiler. For details, see "GNAT User's Guide Supplement for Cross Platforms", Section 3. If you specify a target, note that Inspector may use additional configuration, see the section Target Configuration File.
If for some reason you do not have access to the GNAT compiler on the same
machine as GNAT SAS (e.g. the GNAT cross compiler is installed on a different
host than GNAT SAS) you will first need to copy the GNAT runtime directory in
the GNAT SAS installation, under
<gnatsas-install-dir>/libexec/codepeer/lib/gcc/<gnatsas-platform>/<gnatsas-toolchain-version>/
where <gnatsas-platform> is either x86_64-pc-linux-gnu or x86_64-w64-mingw32 and
<gnatsas-toolchain-version> is the version of GNAT SAS toolchain.
Note
This does not wave aside the requirement of having matching versions of GNAT SAS and GNAT.
For example, assuming you want to use a runtime called
ravenscar-sfp-stm32f4
, then first locate this runtime on the machine
with the GNAT installation, e.g.:
$ arm-eabi-gnatls -v --RTS=ravenscar-sfp-stm32f4 | grep adalib
This command gives the path to <ravenscar-sfp-stm32f4 runtime>/adalib
.
You then need to copy/transfer the <ravenscar-sfp-stm32f4 runtime>
directory
to the GNAT SAS installation, under
<gnatsas-install-dir>/libexec/codepeer/lib/gcc/<gnatsas-platform>/<gnatsas-toolchain-version>/
,
for example using bash
syntax:
$ scp -pr $(dirname $(arm-eabi-gnatls -v --RTS=ravenscar-sfp-stm32f4 | grep adalib)) \
<gnat-sas-machine>:<gnatsas-install-dir>/libexec/codepeer/lib/gcc/<gnatsas-platform>/<gnatsas-toolchain-version>
Note
If you don't have access to the GNAT compiler and you copied the
GNAT runtime directory in the GNAT SAS installation, you need to use
for Target use "gnatsas";
. You can then take the specificities of your
target into account separately as described in Target Configuration File.
3.3.11.1. Working with target-specific configurations
Even when a specific target is used for compilation, we recommend using gnatsas as a target for the analysis when possible. To achieve this, you can either create a dedicated project file for the analysis or use a scenario variable to set different targets for compilation and analysis:
case Enable_GNATSAS is
when "True" =>
for Target use "gnatsas";
when "False" =>
for Target use "x86_64-pc-linux-gnu";
end case;
If a target other than gnatsas is necessary for the analysis, be aware that
GNAT SAS takes such a target into account, however, the project's Target
attribute will still be interpreted as having the value "gnatsas"
when
processing the project file in the context of GNAT SAS. This means that the
project's 'Target
attribute should not be directly referenced in other
attributes (e.g. for Object_Dir use Project'Target
) in parts of the project
file that apply to GNAT SAS.
If the set of sources to analyze depends on the target, you can use a scenario variable to specify the set of sources for GNAT SAS:
Tool := External ("GPR_TOOL", "");
Target := project'Target;
Sources := (".");
case Tool is
when "gnatsas" =>
Sources := Sources & ("src/common/" & "x86_64-pc-linux-gnu");
when others =>
Sources := Sources & ("src/common/" & Target);
end case;
for Source_Dirs use Sources;
If you want to analyze a codebase with different targets and each target has
specific sources, you can define a scenario variable defining such targets and
use it instead of using Target
directly. In this case, --subdirs
or
for Subdirs
should be used to separate each target-specific analysis by
creating a separate gnatsas directory for it. For example:
Tool := External ("GPR_TOOL", "");
type Gnatsas_Target_Type is ("x86_64-pc-linux-gnu", "aarch64-linux-gnu");
Gnatsas_Target : Gnatsas_Target_Type :=
external("GNATSAS_TARGET", "x86_64-pc-linux-gnu");
Target := project'Target;
Sources := (".");
case Tool is
when "gnatsas" =>
Sources := Sources & ("src/common/" & Gnatsas_Target);
when others =>
Sources := Sources & ("src/common/" & Target);
end case;
for Source_Dirs use Sources;
package Analyzer is
for Subdirs use Gnatsas_Target; -- will result in a gnatsas directory
-- located in
-- "<obj_dir>/<Gnatsas_Target>/gnatsas"
end Analyzer;
3.3.12. Configuration of System Package (system.ads)
Note
This section only impacts GNAT-based engines (i.e. Inspector and GNAT Warnings), and has no impact on other engines.
Some Ada compilers provide additional, non-portable definitions in the
predefined package System
which might lead to errors when running Inspector
and GNAT Warnings analyses.
A solution to address this issue automatically is to use the
pragma Extend_System
in a pragma configuration file, either using
one of the predefined GNAT extensions (e.g. Aux_Dec
for the DEC Ada
compiler or VADS
for the VADS compiler, available via the project
file vads.gpr
as described in Use of Compiler-Specific Packages),
or by providing a customized s-auxcom.ads
file.
For example, you can create a file called gnatsas.adc
located
under the same directory where your project file is, which will contain:
pragma Extend_System (Aux_Dec);
or alternatively:
pragma Extend_System (Aux_VADS);
And configure your project file to take this file into account:
package Builder is
for Global_Configuration_Pragmas use "gnatsas.adc";
end Builder;
or if using Aux_VADS
:
with "vads";
project My_Project is
package Builder is
for Global_Configuration_Pragmas use "gnatsas.adc";
end Builder;
end My_Project;
Similarly, if your target compiler provides additional definitions, you
can manually create a s-auxcom.ads
file containing these additional
definitions, e.g.:
package System.Aux_Compiler is
pragma Preelaborate;
function To_Integer (Addr : Address) return Integer;
function To_Address (Int : Integer) return Address;
No_Addr : constant Address := Null_Address;
Address_Zero : constant Address := Null_Address;
Assertion_Error : exception;
...
end System.Aux_Compiler;
and then specify:
pragma Extend_System (Aux_Compiler);
in gnatsas.adc
.
See the GNAT Reference Manual
for more details on Pragma Extend_System
.
Also note that you should never include the compiler System package in
your project file (either in your source file list or even in your source
directories), as Inspector needs to use its own version of system.ads
.
3.3.13. Ignoring Pragmas
Note
This section only impacts GNAT-based engines (i.e. Inspector and GNAT Warnings), and has no impact on other engines.
In some cases, non-portable pragmas are used across Ada technologies in an
incompatible way, generating some spurious error messages when Inspector
or GNAT Warnings analyze these files. In order to address these issues, you can
configure your project file to ignore a set of pragmas via the
Ignore_Pragma
pragma that you should place in a gnatsas.adc
file
as explained in Configuration of System Package (system.ads). For example, if you want to
ignore pragmas called Import_Procedure
and Import_Function
you can put
in your gnatsas.adc
:
pragma Ignore_Pragma (Import_Procedure);
pragma Ignore_Pragma (Import_Function);
Similarly if you want to ignore pragma Global
:
pragma Ignore_Pragma (Global);
If not already done, you need to configure your project file to take this file into account:
package Builder is
for Global_Configuration_Pragmas use "gnatsas.adc";
end Builder;
3.3.14. Providing Stubs for Missing Generic Bodies
Note
This section only impacts GNAT-based engines (i.e. Inspector and GNAT Warnings), and has no impact on other engines.
GNAT Warnings and Inspector will ignore missing bodies and will make reasonable presumptions about calls to such unknown subprograms (see Inspector Presumptions).
However they will generate an error when they encounter a generic package
whose body is missing at instantiation time. In order to work around this
error, you can provide a skeleton for the generic package via the
codepeer-gnatstub
utility, e.g.:
codepeer-gnatstub -Pmy_project generic_package.ads
will generate a file generic_package.adb
which can be used by
GNAT Warnings and Inspector.
3.4. Configuring the Analysis
Note
This section assumes that a project file has been defined for the codebase to analyse and configured to be compatible with GNAT SAS. If that is not the case, refer to the instructions in Creating a Project File and Ensuring compatibility with GNAT SAS.
This section describes how the GNAT SAS analysis can be configured by users to adjust the scope of the analysis, its precision, control where files are generated, etc. It also explains the available configuration for each integrated analysis engine.
All analysis engines are enabled by default. It is possible to individually enable or disable any engine (see gnatsas analyze switches).
3.4.1. Analyzer package attributes
In addition to the project attributes described in the GPRbuild and GPR
Companion Tools User's Guide and described in Project Setup (e.g.
Source_Dirs
, Object_Dir
attributes, Naming and IDE packages, ...),
the following optional project attributes are available in the Analyzer
package:
Subdirs
Relative path from the object directory (
<object_dir>
specified withObject_Dir
, or project directory otherwise) to thegnatsas
directory where results and intermediate files will be output. The path to the gnatsas directory will be[<object_dir>/]<subdirs>/gnatsas
. Note that if theOutput_Dir
attribute is set, analysis results will be stored in that directory instead, whereas the location of intermediate files will remain as specified by theSubdirs
attribute.Output_Dir
GNAT SAS output directory to use for this project. By default, the output directory is
[<object_dir>/][<subdirs>/]gnatsas/<project>.outputs
(or hereafter,<output_dir>
), where<object_dir>
is the directory specified by theObject_Dir
project attribute, and<subdirs>
is the relative path specified withSubdirs
(see above). If you specify a relative directory, this directory is relative to the directory that contains the project file.Review_File
Review file to use for this project. By default, the review file is
<output_dir>/<project>.sar
. If you specify a relative path, this path is relative to the directory that contains the project file.Excluded_Source_Files
List of project source files (as base names) which should be excluded from GNAT SAS' analyses. See Excluding Files from Analysis for more info.
Excluded_Source_Dirs
List of project source directories which should be excluded from GNAT SAS' analyses. See Excluding Directories from Analysis for more info.
Switches
An associative array representing the additional switches that should be used for each GNAT SAS subcommand and analysis engines. Possible keys are:
"analyze"
"inspector"
,"infer"
, (and discouraged"gnat"
and"gnatcheck"
, see below)"report X"
, where X can be any format supported by thegnatsas report
command (e.g."report text"
or"report csv"
). Note that switches specified for a given format will not apply to other formats."baseline"
Warning
Using the
Switches
attribute in the Analyzer package is not recommended for configuring the analysis of GNATcheck and GNAT Warnings. Indeed, such configuration is not recognized by the corresponding tool when it is run standalone (i.e., not through GNAT SAS).The preferred workflow is to always configure GNATcheck through the Check package, and GNAT Warnings through the Compiler or Builder packages. Refer to Configuring GNATcheck and Configuring GNAT Warnings for more details about the configuration of those tools.
project Prj is package Analyzer is for Switches ("analyze") use ("--mode=deep"); -- This is NOT recommended: -- for Switches ("gnatcheck") use ("-rules", "+RLocal_Packages"); end Analyzer; -- Use the Check package instead: package Check is for Default_Switches ("ada") use ("-rules", "+RLocal_Packages"); end Check; end Prj;
Pending_Status
,Not_A_Bug_Status
,Bug_Status
Lists of custom review status definitions, see Custom Review Status.
See also
Refer to the GNAT SAS CLI Reference for more information on supported switches.
3.4.1.1. 32-bits mode
By default GNAT SAS assumes that the compilation target is the same as the host
on which it is run. This is often a sufficient default, although one typical
case where this is not sufficient is when using GNAT SAS in 64-bits mode and
analyzing code designed for 32-bits architectures. In this case, you can run
GNAT SAS with the --bits=32
switch so that GNAT SAS will analyze the code
assuming the same architecture, but in 32-bits mode instead of 64-bits. You can
use this switch either from the command line, or specify it in the project
file:
package Analyzer is
for Switches ("analyze") use ("--bits=32");
end Analyzer;
See also Target Configuration File for advanced configuration of the target.
Warning
This is currently not supported for Infer and GNATcheck.
3.4.2. Partial Analysis
This section describes how to perform a partial analysis, and in particular, how to exclude entities (projects, directories, files, packages, subprograms) from analysis.
3.4.2.1. Selecting the Analysis Scope
GNAT SAS provides several switches allowing users to control the analysis scope,
by passing them to the gnatsas analyze
command line or specifying them in
the project file:
The default behavior when none of the switches below are specified is to analyze the closure of the main units specified in the project file for the full project tree, except externally built units.
-U
: analyze all files in the full project tree, except externally built ones.-U FILE
: analyze files contained in the closure of the FILE unit.--no-subprojects
: analyze all files in the root project only, ignoring all subprojects and also ignoring main units defined in the root project.--file FILE
: analyze a single file FILE.--files-from FILE
: analyze files listed in FILE.
See also
Refer to GNAT SAS CLI Reference for more information about GNAT SAS command-line usage.
In addition, it is possible to exclude entities from the analysis as explained in the following sections.
3.4.2.2. Excluding Subprograms or Packages from Analysis
Note
This section only applies to Infer and Inspector engines.
To selectively disable the analysis of a particular subprogram or set of subprograms for Infer and Inspector, you can add in your Ada source code a pragma Annotate of the form:
pragma Annotate (GNATSAS, Skip_Analysis);
When used in this way, an Annotate pragma takes exactly these two arguments. The pragma may be placed at the beginning (possibly preceded only by different Annotate pragmas) of the declaration list of a subprogram body, a package body, or package visible part.
In the case of a subprogram body, Infer and Inspector's analysis of that subprogram body (and anything declared therein, including nested subprograms) will not be performed. In the case of a package body, Infer and Inspector's analysis of any subprogram body occurring (directly or indirectly) within the package body will not be performed. In the case of a package visible part, analysis of subprogram bodies occurring in the package specification (as well as the package body) will not be performed; note that a subprogram body can occur in a package specification as part of an instantiation of a generic unit.
The subprogram or package in question may be a generic unit or may occur within a generic unit; in this case, the pragma will be replicated (as described in Ada RM 12.3(13)) when an instance of the generic unit is declared and will affect Inspector's analysis of the instance as described in this section.
When an Annotate pragma is used in this way to prevent Inspector and Infer's analysis of a subprogram body, the analysis of clients of the subprogram will be affected in the same way as if the body of the subprogram were unavailable for some other reason (e.g. a missing .adb file).
Here is an example of usage to disable analysis of a specific subprogram:
procedure Complex_Subprogram (...) is
pragma Annotate (GNATSAS, Skip_Analysis);
begin
...
end Complex_Subprogram;
And similarly for a package:
package Complex_Package is
pragma Annotate (GNATSAS, Skip_Analysis);
...
end Complex_Package;
3.4.2.3. Excluding Files from Analysis
If you want to exclude some files from the analysis (because e.g. GNAT SAS is
taking lots of time analyzing them, and these files do not contain useful
subprograms for GNAT SAS to analyze), you can use the Excluded_Source_Files
project attribute in the Analyzer package, for example:
package Analyzer is
for Excluded_Source_Files use ("xxx.adb");
-- Analysis of xxx.adb generates lots of timeouts, skip it for now
end Analyzer;
For the values, ensure to always specify the basename of the excluded files, with no path information. The path information is computed automatically by GNAT SAS based on other project properties.
Warning
Project attributes in the Analyzer package (in particular
Excluded_Source_Dirs
and Excluded_Source_Files
) are ignored when
executing GNATcheck or GNAT Warnings as standalone tools.
Note
Note that excluding a specification file from the analysis also excludes the corresponding body file, if present. On the contrary, excluding a body file does not exclude the corresponding specification file.
3.4.2.3.1. Inspector-specific handling
The Inspector engine has some limitations when it comes to excluding files from the analysis. In the general case, exclusion can be done using the Analyzer package as previously described. However, in some specific cases file exclusion needs to be done differently. This section describes such cases and their impact.
Excluding a file containing a generic
When a file excluded from the analysis contains a generic, the generic will still be analyzed by Inspector if it is instantiated in at least one file that is not excluded. This is because Inspector doesn't analyze generics per se, but analyzes each instantiation of the generic as explained in Handling of Generic Units.
In such case, it is possible to exclude all instantiations of a generic package from the analysis as described in Excluding Subprograms or Packages from Analysis. Inspector will no longer attempt to analyze the excluded file (note, however, that it will still compile it and generate a SCIL for it; if that is not desirable, see the next paragraph).
Excluding a file from compilation and SCIL generation
If you want to not only exclude files from the analysis, but go further and also
exclude it from compilation and SCIL generation; and if these files are not in
the transitive closure of other files (e.g. a body file, as opposed to a
specification file used by other Ada units); then the project-level
Excluded_Source_Files
attribute can be used instead of the Analyzer
attribute:
project My_Project is
for Excluded_Source_Files use ("xxx.adb");
end My_Project;
Warning
Unlike excluding a body file, excluding a specification file at the project level may cause compilation errors on the files depending on this spec and as a result prevent the analysis of those files.
If a specification or a body file of a module is excluded at the project level, Inspector will not be able to perform an incremental analysis of the modules depending on that module. This means that those modules will be fully re-analyzed by Inspector (even in fast mode).
Those effects do not occur if files are excluded using the Analyzer package.
See also
This mechanism may also be used to address some compilation errors as explained in Compilation Errors.
3.4.2.4. Excluding Directories from Analysis
If you want to exclude from analysis all source files from a given set of
directories, you can use the Excluded_Source_Dirs
project attribute in the
Analyzer package, for example:
package Analyzer is
for Excluded_Source_Dirs use ("directory1", "directory2");
end Analyzer;
Warning
Project attributes in the Analyzer package (in particular
Excluded_Source_Dirs
and Excluded_Source_Files
) are ignored when
executing GNATcheck or GNAT Warnings as standalone tools.
You can specify absolute directories or directories relative to the location of the project file (same as for source directories).
As explained in the section Excluding Files from Analysis, generic instantiations made in files not excluded from the analysis will be still analyzed. Note that it is possible to exclude all instantiations of a generic package from the analysis as described in Excluding Subprograms or Packages from Analysis.
3.4.2.5. Excluding Projects from Analysis
If you have a tree of project files (.gpr
) and want to exclude some
entire projects (aka subsystems) from GNAT SAS analysis, you can do it by
adding the following project attributes to each of the projects involved:
for Externally_Built use "True";
This attribute tells GNAT SAS to disable analysis on all source files for this project.
Projects using files (e.g. spec) from this project will still be analyzed, as well as generic instantiations made in other projects.
3.4.3. Configuring GNATcheck
GNAT SAS uses a small selection of GNATcheck rules by default as listed in
GNATcheck Messages. GNATcheck is enabled by default and can be disabled
with the --no-gnatcheck
switch. More rules can be checked by configuring the
Check package of the project file.
See also
For more detailed information about configuring GNATcheck, see the GNATcheck Reference Manual.
The recommended workflow when using the GNATcheck engine in GNAT SAS is to configure the Check package of the project file. This ensures that the GNATcheck configuration defined for the project is consistently taken into account both by GNAT SAS and by GNATcheck when used as a standalone tool.
Some examples of configuration are provided below.
3.4.3.1. Differences with standalone GNATcheck tool
There exist noteworthy differences between using GNATcheck integrated in GNAT SAS and using GNATcheck as a standalone tool.
Note
In GNAT Studio, GNAT SAS with GNATcheck is available from the top-menu GNAT SAS menu), while GNATcheck standalone is available from the menu .
(seeIn particular:
GNAT SAS runs five GNATcheck rules by default (see GNATcheck Messages), while standalone GNATcheck runs none.
The output of both tools is not stored and displayed in the same manner:
Standalone GNATcheck's default output directory is the directory specified by the
Object_Dir
of the project, or the current directory if noObject_Dir
is specified. GNATcheck will generate a text reportgnatcheck.out
and other files under that directory. This behavior can be overridden with multiple switches defined in the Check package, such as--subdirs
or-o
. See the GNATcheck Reference Manual. for more details.However, the results of the GNATcheck analysis integrated in GNAT SAS will be generated in the same format as messages from other engines (Message Files) and can be displayed in multiple ways (see Viewing Results). The default output directory is
./gnatsas/<PROJECT_NAME>.outputs
if noObject_Dir
is specified, and<OBJECT_DIR>/gnatsas/<PROJECT_NAME>.outputs
otherwise. Internal GNATcheck output is also available under the<PROJECT_NAME>.gnatcheck
directory at the same level. Other settings from the Check package will be ignored.
The set of sources analyzed by GNATcheck may differ (specified as
"analyze"
key switches in the Analyzer package or GNAT SAS command-line:-U
,--file
,--files-from
,--no-subprojects``or ``for Source_Files
; and specified as values offor Default_Switches ("ada")
:-U
,-files=
,--no-subprojects
in the Check package).When running standalone GNATcheck, above settings from the Analyzer package will be ignored.
When running GNATcheck integrated in GNAT SAS, above settings from the Check package will be ignored.
Projects marked as externally built with the
Externally_Built
project attribute will not be analyzed when GNATcheck is ran through GNAT SAS.The
Annotate
pragmas for GNAT SAS will only be taken into account when running GNATcheck through GNAT SAS. See Improve Your Code Specification.The
-j
switch for controlling the number of jobs, can be specified throughfor Switches ("analyze")
in the Analyzer package, which will override the settings set throughfor Default_Switches ("ada")
in the Check package.
3.4.4. Configuring Infer
GNAT SAS runs some analyses based on Infer by default. Enabled by default, can
be disabled with --no-infer
.
Some Infer analyses can be activated and/or parameterized using Infer-specific switches. These switches can be specified using the index "infer" of the project attribute Switches in the Analyzer package:
project My_Project is package Analyzer is for Switches ("infer") use ("--side-effects"); end Analyzer; end My_Project;
This example will enable emitting a warning when a function has side effects.
The section Infer Messages contains a list of all Infer messages, with their description and detailed configuration parameters.
3.4.5. Configuring GNAT Warnings
The GNAT front-end warnings. Enabled by default, can be disabled with
--no-gnat
.
3.4.5.1. Specifying warnings to check
When enabled, GNAT SAS calls the GNAT front-end with the switches you enabled through the Default_Switches ("Ada") attribute of the Compiler package of your GPR file and a default selection of checks chosen by GNATSAS itself (see the table listing GNAT Warnings for an exact list). To disable or enable additional checks, add the relevant switches to the Analyzer package in your project file. Disabling warnings can be achieved by using the same mechanism as GNAT, i.e. specifying the warning switch using capital letters.
For example:
project prj is
package Analyzer is
for Switches ("gnat") use ("-gnatwbz.a");
-- equivalent to:
-- for Switches ("gnat") use ("-gnatwb", "-gnatwz", "-gnatw.a");
-- disabled with:
-- for Switches ("gnat") use ("-gnatwBZ.A");
end Compiler;
end prj;
3.4.5.2. Ignoring Source File Timestamp Mismatch
If your environment changes the timestamps of your source files between GNAT SAS
runs (with no actual changes in source files contents), then in order to
minimize the regeneration of Inspector SCIL files or recomputation of GNAT
Warnings, you can specify the --incrementality-method=checksums
switch in
the Analyzer package of your project file, so that checksums rather than
timestamps should be used for determining whether source files have changed
since the previous run:
package Analyzer is
for Switches ("analyze") use ("--incrementality-method=checksums");
end Analyzer;
Note
This switch only impacts GNAT based engines, i.e., Inspector and GNAT Warnings.
Warning
When incrementality is based on checksums, some messages may end up referring to wrong source locations. Indeed:
Incrementality based on checksums internally relies on GPRbuild checksum computation. GPRbuild ignores comments when computing the checksum of a file. Hence, a file were only comments are modified between two gnatsas runs is not re-analyzed. While the messages on the file are still valid, they refer to source locations prior to the comments modifications.
3.4.6. Configuring Inspector
Inspector is the historical analysis engine of GNAT SAS. Enabled by default, can
be disabled with --no-inspector
.
See also
See Inspector Reference for more advanced Inspector configuration.
Example project file
Here is an example of a project file using some of the Inspector attributes described in the following sections:
project Prj1 is
...
package Analyzer is
for Excluded_Source_Files use ("file1.ads", "file2.adb");
for Output_Dir use "/work/project1.outputs";
for Switches ("analyze") use ("--keep-going");
for Switches ("report text") use ("--show-backtraces");
for Additional_Patterns use "ExtraMessagePatterns.xml";
end Analyzer;
end Prj1;
3.4.6.1. Analyzer package attributes
Message_Patterns
Alternate
MessagePatterns.xml
file that Inspector should use for this project.Additional_Patterns
Extra
MessagePatterns.xml
file that Inspector should use in addition to the default patterns file. This can be either a path relative to the project's directory, or an absolute path.
3.4.6.2. Ignoring Source File Timestamp Mismatch
3.4.6.3. Ignoring Exception Handlers
By default Inspector tries to take exception handlers into account in its
analysis, although by doing so this can lead to a loss of precision in the
detection of possible (or certain) run-time errors. If you want Inspector to
analyze the code by completely ignoring exception handlers (behave as if the
exception handlers were stripped from the code) then you can add the
-gnatd.x
switch, e.g.:
package Analyzer is
for Switches ("inspector") use ("-gnatd.x");
end Analyzer;
3.4.6.4. Handling Enumeration Representation Clauses
Even without -gnatI
, Inspector by default ignores enumeration representation
clauses, to reduce the various implicit representation transformations
required by such clauses, which can produce confusing output. If your
application uses Enum_Rep, Enum_Val, or Unchecked_Conversion to manipulate the
underlying codes specified by an enumeration representation clause, then you
may want to override this Inspector default by using the compiler switch
-gnatd.I
. This will cause Inspector to obey the enumeration representation
clause and ensure that Enum_Rep, Enum_Val, and Unchecked_Conversion are
interpreted correctly for this enumeration type. This switch can be added to
your project file, as follows:
package Analyzer is
for Switches ("inspector") use ("-gnatd.I");
end Analyzer;
3.4.6.5. Detection of Floating Point Overflow
Inspector assumes that floating point operations are carried out in single precision (binary32) or double precision (binary64) as defined in the IEEE-754 standard for floating point arithmetic. You should make sure that this is the case on your platform. For example, on x86 platforms, by default some intermediate computations may be carried out in extended precision, leading to unexpected results. With GNAT, you can specify the use of SSE arithmetic by using the compilation switches "-msse2 -mfpmath=sse" which cause all arithmetic to be done using the SSE instruction set which only provides 32-bit and 64-bit IEEE types, and does not provide extended precision. SSE arithmetic is also more efficient. Note that the ABI allows free mixing of units using the two types of floating-point, so it is not necessary to force all units in a program to use SSE arithmetic.
Inspector considers the floating point values which represent positive, negative infinity or NaN as invalid, and it checks that such values cannot occur.
By default, Inspector will only detect potential overflows on floating point operations on constrained floating point types (user floating point types with explicit ranges) and not on unconstrained types (e.g. predefined float types).
You can ask Inspector to check for possible floating point
overflows on unconstrained types (which will then lead to infinite
values) via the -gnateF
compiler switch, e.g.:
package Compiler is
for Switches ("Ada") use ("-gnateF");
end Compiler;