ClangTidy

Stage for C/C++ static analysis via 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 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 <toolFlags> [--extra-arg-before=<compileFlagsPre>]... [--extra-arg=<compileFlagsPost>]... <input>

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

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.

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:

Report Example

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