Static Analysis Overview

Static Analysis is a deprecated feature.

Static Analysis is not supported on OS X* systems.

Static analysis is the process of finding errors and security weaknesses in software through detailed analysis of source code.

This feature requires installation of another product. For more information, see Feature Requirements.

Static analysis finds a wide range of errors that could potentially be exploited by an attacker to defeat application security or cause the application to malfunction. Detected errors include buffer overflow, misuse of pointers and heap storage, unsafe or incorrect use of C/C++ or Fortran language features and libraries, and misuse of OpenMP* and Intel® Cilk™ Plus parallel programming constructs.

Static analysis requires that your code compile without serious errors using the Intel compiler.

Note

You can use static analysis even if you do not plan to use the Intel compiler to build your production binaries. Similarly, you can use it for programs that will be run on a processor type not supported by the Intel compiler.

How Static Analysis Works

The compiler performs the requested analysis by operating in a special mode. In this mode, the compiler dedicates more time to analysis and bypasses the instruction generation process entirely. This allows it to find errors that go undetected during ordinary compilation. This means your code must compile without serious errors with an Intel compiler, but the results of the compilation cannot be executed. Therefore, you can use static analysis even if you do not plan to use an Intel compiler to build your production binaries.

Static analysis first processes each source file individually, producing a pseudo object module. To avoid destroying your real object modules, keep the pseudo object modules generated during static analysis separate from the real object modules.

The analysis results are produced in the link step. This is similar to how Inter Procedural Optimization (IPO) operates, where the final instructions are generated only at the link step. This allows static analysis to find errors that span procedure and file boundaries. This implies that you must invoke the link step with the compiler, not invoke the linker directly.

Static Analysis Modes

Static analysis sometimes finds inconclusive evidence that a security weakness or a logic error exists. In such cases, there is no right behavior for the tool: emitting a diagnostic message risks a false positive, while keeping silent risks a false negative, that is, a missed real error. To cope with this limitation, static analysis provides three different analysis modes. The best choice depends on your situation and objectives.

  • Full attempts to find all program weaknesses, even at the expense of more false positives. This is appropriate when using the tool for security assurance. The high potential cost of a security weakness in a released product should justify the time needed to work through extra false positives. The Intel® Inspector GUI provides numerous techniques for dealing with large results and disposing of groups of similar errors when they are found to be false positives.
  • Concise attempts to reduce false positives by tolerating a higher rate of false negatives. This is appropriate when using the tool for general error detection. The time saved investigating false positives must be weighed against the relatively small increased risk of a false negative. In this mode, a confidence algorithm estimates the probability that a diagnostic will turn out to be true or false. If the estimated confidence is very low, the diagnostic is dropped entirely. Otherwise, the confidence is used to adjust the relative weight on the diagnostic. This can cause a more likely error of lesser impact to be given higher weight than a less likely error of greater impact

  • Precise reduces the false positive rate as low as possible while still providing a useful level of error detection. This is appropriate when using the tool for general error detection. Use this mode to provide a quick "go, no go" screening decision about a source version. The need to strongly avoid false positives significantly reduces the number and type of errors that can be detected. However, the low rate of false positives ensures the best return on time spent investigating analysis results. It also makes it reasonable to set a project policy requiring a clean analysis result in this mode before allowing a source change into a source code control repository

Use the [Q]diag-enable[:] sc-{full|concise|precise} option to specify the analysis mode.

Static Analysis: Whole Program vs Single File

Static analysis can be enabled for an entire program or on a single file. A supplied compiler option specifies that static analysis should process each source file individually. Skipping the usual whole-program analysis reduces memory requirements and analysis time on large programs but often finds fewer real errors.

Many errors can only be detected through global, whole-program analysis, and these errors would not be detected if single file analysis is enabled. On the other hand, whole program analysis for very large programs can take a long time. Using single file analysis may greatly reduce the time required (possibly from hours to minutes), which could, in turn, allow you to run analysis more frequently. This is cost-effective, since detecting and fixing bugs earlier is cheaper.

Single file analysis may cause analysis of some programs to take longer. When a program consists of numerous small files, it can be faster to read everything into memory at once than to process each file individually. In such cases, this single file analysis provides little value and should not be used.

Use the [Q]diag-enable[:] sc-single-file option to specify single file analysis.

Static Analysis and Enumeration Variables

Static analysis provides an option to treat enumeration variables as known values equal to any one of the associated enumeration literals. By default, static analysis treats unknown enumeration variables as unknown integer values.

Setting this option may uncover additional errors but may also create more false positives.

Consider the following program:

typedef enum {red = -1, yellow = 0, blue= 1} color;
volatile int v1;
volatile color v2;
int x[10];
int f() {
    int y1 = v1;
    int y2 = v1;
    color y3 = v2;
    if ((y2 >= -1) && (y2 <= 1))
       return (x[y1] + x[y2] + x[y3]);
    else return 0;
}

This program uses volatile global variables as a source of unknown values; there are many other ways to encounter unknown values.

There are three array index operations, any one of which can cause a bounds violation:

  • Static analysis will not flag x[y1]. Since y1 is a completely unknown integer value, there is no basis to challenge this index operation.

  • Static analysis will flag x[y2]. Here, an "if" statement limits the value of y2 to the set {-1,0,1}, yet one of those possible values will cause a bounds violation. This strongly suggests a logic error.

  • The third index, x[y3], is less clear. There is no "if" statement to indicate what the programmer was thinking. The programmer declared y3 as an enumeration type, and this choice effectively limits the possible values of y3 to the set {-1,0,1}, just as the "if" statement did for y2. Since there is weaker evidence that an error exists, an array index operation like x[y3] will be flagged if and only if the sc-enum option is set.

Use the [Q]diag-enable[:] sc-enums option to specify treatment of enums.

Static Analysis and SAL

The Intel® C++ Compiler supports the Microsoft* standard source code annotation language (SAL). SAL enables static checking of calls to external routines that are not provided in source form. Subroutine declarations can be annotated with a set of SAL macros that describe proper usage.

The Intel® C++ Compiler will ignore any annotations unless you are compiling with static security analysis enabled. When enabled, static analysis will diagnose violations of the constraints implied by SAL annotations.

See the Microsoft* Visual C++* documentation for detailed descriptions of the SAL annotations.

Static Analysis Recommendations

It is not necessary to convert your application to build with the Intel® C++ Compiler to use static analysis, but static analysis requires source level compatibility with the Intel® C++ Compiler. If you are not already building with the Intel® C++ compiler, follow these guidelines:

The Intel® C++ Compiler is compatible with both the Microsoft* Visual C++* and GNU* compilers so most applications do not encounter compatibility issues.

Static analysis is most effective on a complete program; this is because some problems can only be detected by analyzing interactions across source files. You can perform static analysis on partial programs or even on single files simply by linking fewer modules. You can also use the single file analysis option to increase processing speed. However, doing this may hide some problems that would be uncovered on whole program analysis. Even if you do not use complete program analysis on a regular basis, be sure to do a periodic scan of everything together to ensure that true program errors do not go undetected.

If you use static analysis on projects that build and link against libraries, analyze a library before analyzing projects that link against that library. When you analyze a project that links against an analyzed library, the modules of the library participate fully in the analysis, as if the library sources were part of the application.

Analyzing a library by itself diagnoses problems only within that library. The pseudo object modules produced during the compilation step can be combined into a static link library using the standard librarian utility. When you analyze a dynamic library, a static library is produced during the link step in place of the usual export library. Linking against an unanalyzed library is permitted; however, the sources of an unanalyzed library do not participate in the analysis.

It is often best to start using static analysis in precise mode. This helps you address the most obvious problems quickly. You can then move on to a more aggressive analysis mode.

Closer checking of enumeration variables may reveal additional true errors but may increase false positives. To determine whether the [Q]diag-enable[:] sc-enums is useful for you, perform static analysis without specifying the option and then, without changing the source, run analysis again, this time specifying the option. If there are only a few new problems, you should investigate them. If large numbers of new problems are reported, this option may not be useful to you.

For more complete information about compiler optimizations, see our Optimization Notice.