Intermodular Analysis of C and C++ Projects in Detail (Part 2)

In part one, we discussed the basics of C and C++ project compiling. We also talked about linking and optimizations. In part 2, we will delve deeper into intermodular analysis and discuss its other purpose. But this time, we won't talk about source code optimizations — we'll find out how to improve the quality of static analysis.

Static Analysis

The way most static analyzers work is similar to the way the compiler's front end works. To parse the code, developers build a similar model and use the same traversal algorithms. So, in this part of the article, you'll learn many terms related to compilation theory. We discussed many of them in part one — do take a look if you haven't already!

Intermodular Analysis of C and C++ Projects in Detail (Part 1)

Starting from PVS-Studio 7.14, the C and C++ analyzer has supported intermodular analysis. In this two-part article, we'll describe how similar mechanisms are arranged in compilers and reveal some technical details of how we implemented intermodular analysis in our static analyzer.

Preface

Before we inspect intermodular analysis, let's remember how compilation works in the C and C++ world. This article focuses on various technical solutions for object module layout. We'll also see how well-known compilers use intermodular analysis and how it's related to Link Time Optimizations (LTO).

Intermodular Analysis of C++ Projects in PVS-Studio

Why would we need intermodular analysis? How does the analyzer benefit from it? Normally, our tool is checking only one source file at a time. The analyzer doesn't know about the contents of other project files. Intermodular analysis allows us to provide the analyzer with information about the entire project structure. This way, the analysis becomes more accurate and qualitative. This approach is similar to Link Time Optimization (LTO). For example, the analyzer can learn about a function behavior from another project file and issue a warning. It may be, for instance, dereference of a null pointer that was passed as an argument to an external function.

Implementation of intermodular analysis is a challenging task. Why? To find out the answer to this question, let's first dig into the structure of C++ projects.