Clang Diagnostics Overview
Clang, as part of the LLVM project, provides a comprehensive suite of diagnostic messages to aid developers in identifying and resolving issues within their C, C++, Objective-C, and Objective-C++ code. These diagnostics cover a wide range of issues from syntax errors to optimizations and potential bugs.
Diagnostic messages in Clang are designed to be clear and actionable. They not only indicate what the issue is but also provide suggestions for how to fix it. Clang diagnostics can be categorized into several types, including warnings, errors, fatal errors, notes, and downgradable errors. This article focuses on organizing the different types of diagnostic messages into a table for easy reference.
Diagnostic Types
Type | Description | Examples |
---|---|---|
Remark | Provides observations or comments that do not indicate potential errors but may be useful to the developer. | Performance hints, optimization suggestions.
remark: vectorized loop (vectorization width: 4, interleaved count: 2) [-Rpass=loop-vectorize] [Example] |
Warning | Indicates a potential issue or best practice violation that does not prevent the compilation. | Unused variables, overshadowed names, potential type mismatches.
warning: unused variable 'a' [-Wunused-variable] [Example] |
Downgradable Error | Errors that can be treated as warnings based on -Wno-error=<group> flags.
|
C99 implicit function declarations.
error: call to undeclared function 'missing'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] [Example] |
Error | Indicates a problem that prevents the compiler from continuing. | Syntax errors, undeclared identifiers.
error: use of undeclared identifier 'x' [Example] |
Fatal Error | Indicates a severe problem that stops the compilation process immediately. | Missing system headers, invalid compiler flags.
fatal error: 'missing.h' file not found [Example] |
Note | Provides additional information about warnings or errors. | Suggestions for fixing an issue, clarifications.
note: 'test' declared here [Example] |
Diagnostic Groups
Each warning in Clang is part of several groups. Diagnostic groups are used by command line arguments (diagnostic flags) to control sets of related diagnostics. Diagnostic flags, such as -W<group>
, allow for the activation of warnings within a specific group. Similarly, -Werror=<group>
can be used to escalate warnings in a given group to errors.
Main Group
Each warning is associated with a main group. Main groups encapsulate a relatively small set of related warnings, providing a unique method for identifying and controlling them. Direct control over individual warnings is not available. For example, warnings about unused variables have the main group utilized by the -Wunused-variable
flag. The diagnostic flag of the main group is also displayed when the warning is issue (e.g. [-Wunused-variable]
) giving the developer a hint how to control the warning.
Supergroups
Supergroups are groups of warnings that cover a larger set of warnings. Internally, supergroups are defined by a set of one or more subgroup, whereby a subgroup can be a main groups or other supergroups. However, the internal structure is not exposed to the developer.
A common example is the -Wunused
group, which covers warnings related to unused code elements, such as variables, functions, or labels. The -Wunused-* groups
(including -Wunused-variable
) fall under this group.
Large diagnostic groups such as -Wall
, -Wextra
, -Wpedantic
, and -Weverything
serve as comprehensive collections that enable a broad spectrum of warnings. These groups are particularly useful for enforcing strict coding standards and ensuring code quality by covering a wide range of potential issues, from minor stylistic concerns to critical bugs.
Control Diagnostics
Diagnostic Flags via Command Line
Clang's diagnostic messages can be controlled using various command line flags. These flags allow developers to enable, disable, or escalate certain types of diagnostics, including downgrading errors to warnings. Here are a few examples of diagnostic flags:
Flag | Purpose | Example |
---|---|---|
-W<group>
|
Enable warnings within a specific group. | -Wall
|
-Wno-<group>
|
Disable warnings within a specific group. | -Wno-unused
|
-Werror=<group>
|
Treating warnings as errors. | -Werror=implicit-function-declaration
|
-Wno-error=<group>
|
Treating downgradable errors as warnings | |
-Werror
|
Treats all warnings as errors. | |
-Wfatal-errors
|
Treat all errors as fatal errors. | |
-pedantic-errors
|
Error on language extensions. | |
-Wsystem-headers
|
Enable warnings from system headers. |
Control Diagnostics Inside Code
The #pragma clang diagnostic
directive allows to control diagnostics directly within the code. For example, to ignore all warnings in a specific group within a block of code, you can use:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-W<group>"
// Code that triggers warnings you want to ignore
#pragma clang diagnostic pop
This approach enables developers to suppress specific warnings in parts of the code where they are aware of the issues but have chosen not to address them, either because they are false positives or for some other reason.
Flags Influencing Diagnostic Output
Flag | Effect | Example |
---|---|---|
-Werror -Werror=<group>
|
warning is changed to error , -Werror is added
|
warning: unused variable 'x' [-Wunused-variable] (without flag)
error: unused variable 'x' [-Werror,-Wunused-variable] (with flag) |
-Wfatal-errors
|
error is changed to fatal error
|
error: use of undeclared identifier 'id' (without flag)
fatal error: use of undeclared identifier 'id' (with flag) |
-Wno-error=<group>
|
error is changed to warning
|
error: call to undeclared function 'missing'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] (without flag)
warning: call to undeclared function 'missing'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] (with flag) |
-fno-diagnostics-show-option
|
Don't print option name with mappable diagnostics | warning: unused variable 'x' [-Wunused-variable] (without flag)
warning: unused variable 'x' (with flag) |
-fansi-escape-codes
|
Use ANSI escape codes for diagnostics | To be done |
-fcaret-diagnostics -fno-caret-diagnostics
|
Enable/disable caret diagnostics | To be done |
-fcolor-diagnostics -fno-color-diagnostics
|
Enable/disable colors in diagnostics | To be done |
-fdiagnostics-absolute-paths
|
Print absolute paths in diagnostics | To be done |
-fdiagnostics-hotness-threshold=<number>
|
Set a threshold for hotness in diagnostics | To be done |
-fdiagnostics-parseable-fixits
|
Produce machine-parseable fix suggestions | To be done |
-fdiagnostics-print-source-range-info
|
Print source range information in diagnostics | To be done |
-fdiagnostics-show-hotness
|
Enable profile hotness information in diagnostic line | To be done |
-fdiagnostics-show-note-include-stack
|
Display include stacks for diagnostic notes | To be done |
-fdiagnostics-show-template-tree
|
Display template instantiation tree in diagnostics | To be done |
-fmodules-disable-diagnostic-validation
|
Disable validation of diagnostic options when loading modules | To be done |
Disable caret diagnostics | To be done | |
-fno-crash-diagnostics
|
Disable auto-generation of repro files on crash | To be done |
-fno-diagnostics-fixit-info
|
Do not include fixit information in diagnostics | To be done |
-fno-elide-type
|
Do not elide types in diagnostics | To be done |
-fno-show-column
|
Do not show column number in diagnostics | To be done |
-fmacro-backtrace-limit=<limit>
|
note: (skipping 4 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all) is issued when the limit is exceeded | |
-ferror-limit=<limit>
|
Specify the maximum number of errors. | fatal error: too many errors emitted, stopping now [-ferror-limit=] is issued when the limit is exceeded |
-fmessage-length=<n>
|
Try to format error messages so that they fit on lines of about n characters. | |
-Xclang -fdiagnostics-show-category -Xclang name
|
Display diagnostic category name per diagnostic | warning: unused variable 'x' [-Wunused-variable,Unused Entity Issue] includes Unused Entity Issue category name. |
Clang Internals
Within Clang's source code, the Diagnostic*Kinds.td
files defines the various kinds of diagnostic messages that Clang can produce, including errors, warnings, and notes. It acts as a central registry for all diagnostics used throughout Clang, enabling developers working on Clang to add new diagnostics or modify existing ones in a structured manner. This system ensures consistency and manageability of diagnostic messages as Clang evolves.
- See internal manual about The Diagnostics Subsystem for more details.
- See clang repository: https://github.com/llvm/llvm-project/tree/main/clang/include/clang/Basic
Example
For example, the unused variable warning is defined in DiagnosticSemaKinds.td
def warn_unused_variable : Warning<"unused variable %0">,
InGroup<UnusedVariable>, DefaultIgnore;
During the clang's compilation, a DiagnosticSemaKinds.inc
file is created in tools/clang/include/clang/Basic
including an entry for each warning. The clang-tblgen
tools is used with -gen-clang-diags-defs
flag to generate the inc file as specified in the CMakeLists.txt of the containing directory. The unused variable warning is converted into the following code
DIAG(warn_unused_variable, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unused variable %0", 903, SFINAE_Suppress, false, false, true, false, 35)
Diagnostic Categories
A diagnostic is part of one of the following categories:
Category | Description |
---|---|
Lexical or Preprocessor Issue | Issues related to lexical elements or preprocessor directives. |
Semantic Issue | Problems related to the semantics of the code. |
Lambda Issue | Issues specific to lambda expressions. |
Parse Issue | Problems encountered during parsing. |
ARC Semantic Issue | Issues related to Automatic Reference Counting semantics. |
ARC and @properties | Specific to ARC and @property declarations. |
ARC Casting Rules | Issues related to casting rules under ARC. |
ARC Weak References | Pertains to the use of weak references in ARC. |
ARC Restrictions | Restrictions imposed by ARC. |
OpenMP Issue | Problems related to OpenMP directives. |
Inline Assembly Issue | Issues in inline assembly code. |
AST Deserialization Issue | Issues during AST deserialization. |
Modules Issue | Problems related to module import and export. |
Coroutines Issue | Specific to coroutine usage. |
Concepts Issue | Issues related to C++ concepts. |
Dependency Directive Source Scanner Issue | Problems found by the source scanner in dependency directives. |
Backend Issue | Issues during the backend compilation phase. |
SourceMgr Reported Issue | Problems reported by the Source Manager. |
Related Result Type Issue | Issues with related result types. |
AST Serialization Issue | Problems during AST serialization. |
Nullability Issue | Issues related to nullability annotations. |
Generics Issue | Specific to generics in Objective-C. |
User-Defined Issue | Custom issues defined by the user. |
Refactoring Invocation Issue | Problems encountered during refactoring invocations. |
VTable ABI Issue | Issues with the VTable ABI. |
Value Conversion Issue | Problems related to value conversion. |
Documentation Issue | Issues in documentation comments. |
ARC Retain Cycle | Specific to retain cycles in ARC. |
Deprecations | Warnings about deprecated features. |
Format String Issue | Issues in format strings. |
Cocoa API Issue | Problems specific to Cocoa API usage. |
#pragma message Directive | Messages generated by #pragma message. |
Instrumentation Issue | Issues related to code instrumentation. |
Unused Entity Issue | Warnings about unused entities. |
References
- Clang Diagnostics Reference
- Clang Compiler User’s Manual - Controlling Errors and Warnings
- LLVM Project