Files
carbon-lang/toolchain/diagnostics/coverage_test.cpp
T
Chandler CarruthandGeoff Romer 2b9fdd6e42 Fix the check that every registered diagnostic kind is declared (#7660)
`load_diagnostic_kind` matched `^\s+CARBON_DIAGNOSTIC_KIND` without
`re.MULTILINE` against a file whose entries start at column zero, so it
found nothing: `check_unused` was comparing an empty set of declarations
against every use and reporting nothing at all. The check has never run.

With it running, three kinds turn out to be registered and never
declared, and go: `BuildFailureRunningClangToLink`,
`BuildOutputFileOpenError`, and `BuildPreludeManifestError`.

`load_diagnostic_uses_in` looked only for `CARBON_DIAGNOSTIC`, so a
diagnostic declared with `CARBON_DIAGNOSTIC_ON_SCOPE` counted as unused,
and it read the two macros' own definitions in `diagnostic.h` as uses.
Both are why the kinds above could not simply be deleted before.

Assisted-by: Claude Code

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-08-21 22:21:54 +00:00

88 lines
3.1 KiB
C++

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include <gtest/gtest.h>
#include "absl/flags/flag.h"
#include "toolchain/diagnostics/kind.h"
#include "toolchain/testing/coverage_helper.h"
ABSL_FLAG(std::string, testdata_manifest, "",
"A path to a file containing repo-relative names of test files.");
namespace Carbon::Diagnostics {
namespace {
constexpr Kind Kinds[] = {
#define CARBON_DIAGNOSTIC_KIND(Name) Kind::Name,
#include "toolchain/diagnostics/kind.def"
};
constexpr Kind UntestedKinds[] = {
// These exist only for unit tests.
Kind::TestDiagnostic,
Kind::TestDiagnosticContext,
Kind::TestDiagnosticContext2,
Kind::TestDiagnosticNote,
Kind::TestDiagnosticOnScope,
Kind::TestDiagnosticSoftContext,
Kind::TestDiagnosticSoftContext2,
// Diagnosing erroneous install conditions, but test environments are
// typically correct.
Kind::BuildTempDirectoryCreationError,
Kind::BuildTempDirectoryDeletionError,
Kind::CompileCoreManifestError,
Kind::CompilePreludeManifestError,
Kind::ConfigFailedToReadDigest,
Kind::ConfigFailedToSetupTarget,
Kind::DriverInstallInvalid,
Kind::LinkCarbonPreludeBuildFailed,
// These diagnose filesystem issues that are hard to unit test.
Kind::ErrorReadingFile,
Kind::ErrorStattingFile,
Kind::FileTooLarge,
Kind::FailureBuildingRuntimes,
Kind::FailureRunningClang,
Kind::FailureRunningClangToLink,
// These aren't feasible to test with a normal testcase, but are tested in
// lex/tokenized_buffer_test.cpp.
Kind::TooManyTokens,
Kind::UnsupportedCrLineEnding,
Kind::UnsupportedLfCrLineEnding,
// This is a little long but is tested in lex/numeric_literal_test.cpp.
Kind::TooManyDigits,
// Producing an emit failure may be infeasible.
Kind::CodeGenUnableToEmit,
// TODO: This is currently hard to test because it requires building and
// importing a module, which attempts to create additional files with
// unpredictable names in the module cache, which bazel doesn't permit.
Kind::InCppModule,
// TODO: This can only fire if the first message in a diagnostic is rooted
// in a file other than the file being compiled. The language server
// currently only supports compiling one file at a time. Do one of:
// - When imports are supported, find a diagnostic whose first message isn't
// in the current file.
// - Require all diagnostics produced by compiling have their first location
// be in the file being compiled, never an import.
Kind::LanguageServerDiagnosticInWrongFile,
};
// Looks for diagnostic kinds that aren't covered by a file_test.
TEST(Coverage, Kind) {
Testing::TestKindCoverage(absl::GetFlag(FLAGS_testdata_manifest),
R"(^ *// CHECK:STDERR: .* \[(\w+)\]$)",
llvm::ArrayRef(Kinds),
llvm::ArrayRef(UntestedKinds));
}
} // namespace
} // namespace Carbon::Diagnostics