# ClangTidy Stage for C/C++ static analysis via [Clang-Tidy](https://clang.llvm.org/extra/clang-tidy/). - Kind: Pre-Grading Stage - Behavior: Runs Clang-Tidy against a given list of files. ## Config ``` clangTidy: input: [String] # List of files to run Clang-Tidy over compileFlagsPre: [String]? # Compiler flags to prepend (Clang-Tidy option: --extra-arg-before=) compileFlagsPost: [String]? # Compiler flags to append (Clang-Tidy option: --extra-arg=) toolFlags: [String]? # Clang-Tidy flags to append additional_packages: [String]? # Any additional packages to install as dependencies scorePolicy: ScorePolicy? # The scoring policy for this stage ``` - This stage implements *Per-Element Scoring*. - An element is defined as one single diagnostic emitted by Clang-Tidy. - See [Scorable.md](../Scorable.md) for more information. - When constructing the list of arguments for Clang-Tidy, `toolFlags` will be inserted first, followed by `compileFlagsPre`, and finally `compileFlagsPost`, seen below: ``` clang-tidy [--extra-arg-before=]... [--extra-arg=]... ``` ## Report ``` clangTidy: - files: [String] # List of files processed by Clang-Tidy exitCode: Int # Clang-Tidy exit code isSuccess: Boolean # Whether this stage executed without errors hasTimedOut: Boolean # Whether the execution has timed out stdout: [String] # All standard output messages from Clang-Tidy stderr: [String] # All standard error messages from Clang-Tidy yamlReport: ClangTidyYAMLFile? # Fixes YAML emitted by Clang-Tidy score: Score? # The scoring information of this stage; See docs/pipeline/Scorable.md ``` [Example](examples/clang-tidy_report.yaml) `yamlReport` will be `null` if the report cannot be parsed by Grader's internal `ClangTidyYAMLFile` parser. ### `ClangTidyYAMLFile`: Clang-Tidy Fixes YAML `ClangTidyYAMLFile` is the internal name for the YAML file emitted by Clang-Tidy's `--export-fixes` flag. There are currently two known formats of this file. #### `Replacement` `Replacement` is a struct which is shared in both formats of the file. This struct indicates a possible auto-fix that may be applied to suppress the warning. ``` Replacement: FilePath: Path # Path to the file of this suggested replacement Offset: Long # Character offset relative to beginning of file Length: Long # Length of text to replace ReplacementText: String # Text to replace original range of [Offset, Offset + Length) ``` The C++ definition of the struct in `libtooling` can be found [here](https://clang.llvm.org/doxygen/classclang_1_1tooling_1_1Replacement.html). #### `ClangLegacyTidyYAML` `ClangLegacyTidyYAML` is the YAML format emitted by Clang-Tidy tools before LLVM 9. ``` MainSourceFile: String Diagnostics: [Diagnostic] # List of all warnings emitted Diagnostic: DiagnosticName: String # Clang/Clang-Tidy diagnostic name Message: String # Human-friendly message of this warning FileOffset: Long # Character offset relative to beginning of file FilePath: String # Path to the file of this warning Replacements: [Replacement]? # Possible replacements to suppress this warning ``` #### `Clang9TidyYAML` `Clang9TidyYAML` is the YAML format emitted by Clang-Tidy tools since LLVM 9. ``` MainSourceFile: String Diagnostics: [Diagnostic] # List of all warnings emitted Diagnostic: DiagnosticName: String # Clang/Clang-Tidy diagnostic name DiagnosticMessage: DiagnosticMessage # Details of the diagnostic Notes: [DiagnosticMessage]? # Diagnostic messages which do not fall under the core diagnostic message DiagnosticMessage: Message: String # Human-friend message of this warning FilePath: String # Path to the file of this warning FileOffset: Long # Character offset relative to beginning of file Replacements: [Replacement]? # Possible replacements to suppress this warning ``` The C++ definition of the structs in `libtooling` can be found here: - [Diagnostic](https://clang.llvm.org/doxygen/structclang_1_1tooling_1_1Diagnostic.html) - [DiagnosticMessage](https://clang.llvm.org/doxygen/structclang_1_1tooling_1_1DiagnosticMessage.html) ### Report Example ```yaml configError: null contextError: null pipelineError: null stageReports: clangTidy: - files: - "main.cpp" - "lib.cpp" hasTimedOut: false exitCode: 0 stdout: - "/vol/main.cpp:10:3: warning: Undefined or garbage value returned to caller\ \ [clang-analyzer-core.uninitialized.UndefReturn]" - " return a[1];" - " ^" - "/vol/main.cpp:4:3: note: Taking false branch" - " if constexpr (false) {" - " ^" - "/vol/main.cpp:10:3: note: Undefined or garbage value returned to caller" - " return a[1];" - " ^" - "/vol/main.cpp:10:10: warning: array index 1 is past the end of the array (which\ \ contains 1 element) [clang-diagnostic-array-bounds]" - " return a[1];" - " ^" - "/vol/main.cpp:8:3: note: array 'a' declared here" - " int a[1];" - " ^" - "/vol/lib.cpp:3:3: warning: Undefined or garbage value returned to caller [clang-analyzer-core.uninitialized.UndefReturn]" - " return c;" - " ^" - "/vol/lib.cpp:2:3: note: 'c' declared without an initial value" - " char c;" - " ^" - "/vol/lib.cpp:3:3: note: Undefined or garbage value returned to caller" - " return c;" - " ^" - "/vol/lib.cpp:3:10: warning: variable 'c' is uninitialized when used here [clang-diagnostic-uninitialized]" - " return c;" - " ^" - "/vol/lib.cpp:2:9: note: initialize the variable 'c' to silence this warning" - " char c;" - " ^" stderr: - "Error while trying to load a compilation database:" - "Could not auto-detect compilation database for file \"main.cpp\"" - "No compilation database found in /vol or any parent directory" - "fixed-compilation-database: Error while opening fixed database: No such file\ \ or directory" - "json-compilation-database: Error while opening JSON database: No such file\ \ or directory" - "Running without flags." - "2 warnings generated." - "4 warnings generated." yamlReport: diagnostics: - fileOffset: 97 replacements: null diagnosticName: "clang-analyzer-core.uninitialized.UndefReturn" filePath: "file:///vol/main.cpp" message: "Undefined or garbage value returned to caller" - fileOffset: 104 replacements: null diagnosticName: "clang-diagnostic-array-bounds" filePath: "file:///vol/main.cpp" message: "array index 1 is past the end of the array (which contains 1 element)" - fileOffset: 33 replacements: null diagnosticName: "clang-analyzer-core.uninitialized.UndefReturn" filePath: "file:///vol/lib.cpp" message: "Undefined or garbage value returned to caller" - fileOffset: 40 replacements: - replacementText: " = '\\0'" filePath: "file:///vol/lib.cpp" length: 0 offset: 29 diagnosticName: "clang-diagnostic-uninitialized" filePath: "file:///vol/lib.cpp" message: "variable 'c' is uninitialized when used here" mainSourceFile: "file:///vol/main.cpp" score: score: -4.0 total: 0.0 isSuccess: true ```