Clang Diagnostics Overview

From emmtrix Wiki
Jump to navigation Jump to search

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.

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