Compilers comprise a complex pipeline of analysis and transformation stages. Changes in one stage are frequently amplified by subsequent stages. It makes compilers very sensitive to configuration, with a seemingly minor change to the compiler’s configuration options potentially having a huge impact on the generated executable code. For compiler qualification in safety-critical applications, that matters a lot. If you do not qualify the compiler for the exact use case (or configuration) you are using, the compiler is not qualified at all.
So, what defines a use case?
The use case contains all factors that influence the translation of the compiler’s input (your specific application’s source code) into its output (the application’s executable code). That includes the compiler version because virtually every compiler update will introduce subtle changes in the generated executable.
Equally important are changes to the compiler’s option settings. Every option potentially alters the compiler pipeline’s downstream behavior and this effect cascades. Every option combination potentially generates a different output. That is why a pre-qualified compiler is only a good fit if it is qualified for a specific defined use case.
Another critical factor is the targeted version of the programming language. A compiler configured to compile C99 code, for example, should be qualified following the C99 specification – not the latest C18 specification.
Every option combination is different, but there are permissible changes
GCC and Clang-based compilers have, in the order of a thousand options. However, not every option changes the pipeline’s behavior. For example, diagnostic options related to compiler error messages typically don’t change the output, although they may result in compile-time errors. Including a useful diagnostic option that only prevents a few programs from compiling may be an acceptable change in the use case.
Do things in the right order
The take-home is simple. If you are going to qualify your compiler for the specific use case of your application, you’d better make sure you identify that use case properly. Due to the potential complexity of the build system, doing so is not trivial. Our friends at BUGSENG, for example, recently analyzed the configurations used to compile the open-source Xen project hypervisor for x86-64 in the default configuration. In this single project, they identified 40 different use cases (!), targeting 3 different versions of C. Fortunately, few safety-critical applications are this complex, but the message remains the same – if you want to qualify your compiler, make sure you have your use case straightened out beforehand.
Dr. Marcel Beemster, CTO & Remi van Veen, Qualification Lead Engineer
Subscribe to our monthly blog!