[DiagnosticVerifier] Add -verify-ignore-unrelated flag

This adds the implementation required for later changing the default
behaviour of the -verify flag to error when diagnostics are emitted
in buffers other than the main file and files added with
-verify-additional-file. To keep the current behaviour, use the flag
-verify-ignore-unrelated. This flag is added as a no-op so that tests
can start using it before the new behaviour is enabled by default.
This commit is contained in:
Henrik G. Olsson
2025-10-03 17:04:53 -07:00
parent 8edfd9c83f
commit e0c65b7c44
6 changed files with 60 additions and 4 deletions

View File

@@ -41,6 +41,11 @@ public:
/// \c VerifyMode is not \c NoVerify.
bool VerifyIgnoreUnknown = false;
/// Indicates whether to allow diagnostics for locations outside files parsed
/// for 'expected' diagnostics if \c VerifyMode is not \c NoVerify. Does not
/// allow diagnostics at <unknown>, that is controlled by VerifyIgnoreUnknown.
bool VerifyIgnoreUnrelated = false;
/// Indicates whether diagnostic passes should be skipped.
bool SkipDiagnosticPasses = false;

View File

@@ -99,6 +99,7 @@ class DiagnosticVerifier : public DiagnosticConsumer {
ArrayRef<std::string> AdditionalFilePaths;
bool AutoApplyFixes;
bool IgnoreUnknown;
bool IgnoreUnrelated;
bool UseColor;
ArrayRef<std::string> AdditionalExpectedPrefixes;
@@ -106,11 +107,11 @@ public:
explicit DiagnosticVerifier(SourceManager &SM, ArrayRef<unsigned> BufferIDs,
ArrayRef<std::string> AdditionalFilePaths,
bool AutoApplyFixes, bool IgnoreUnknown,
bool UseColor,
bool IgnoreUnrelated, bool UseColor,
ArrayRef<std::string> AdditionalExpectedPrefixes)
: SM(SM), BufferIDs(BufferIDs), AdditionalFilePaths(AdditionalFilePaths),
AutoApplyFixes(AutoApplyFixes), IgnoreUnknown(IgnoreUnknown),
UseColor(UseColor),
IgnoreUnrelated(IgnoreUnrelated), UseColor(UseColor),
AdditionalExpectedPrefixes(AdditionalExpectedPrefixes) {}
virtual void handleDiagnostic(SourceManager &SM,
@@ -131,6 +132,11 @@ private:
void printDiagnostic(const llvm::SMDiagnostic &Diag) const;
/// Check whether there were any diagnostics in files without expected
/// diagnostics
bool verifyUnrelated(
std::vector<CapturedDiagnosticInfo> &CapturedDiagnostics) const;
bool
verifyUnknown(std::vector<CapturedDiagnosticInfo> &CapturedDiagnostics) const;

View File

@@ -165,6 +165,8 @@ def verify_apply_fixes : Flag<["-"], "verify-apply-fixes">,
HelpText<"Like -verify, but updates the original source file">;
def verify_ignore_unknown: Flag<["-"], "verify-ignore-unknown">,
HelpText<"Allow diagnostics for '<unknown>' location in verify mode">;
def verify_ignore_unrelated: Flag<["-"], "verify-ignore-unrelated">,
HelpText<"Allow diagnostics in files outside those with expected diagnostics in verify mode">;
def verify_generic_signatures : Separate<["-"], "verify-generic-signatures">,
MetaVarName<"<module-name>">,
HelpText<"Verify the generic signatures in the given module">;

View File

@@ -2588,6 +2588,7 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
if (Args.hasArg(OPT_verify_apply_fixes))
Opts.VerifyMode = DiagnosticOptions::VerifyAndApplyFixes;
Opts.VerifyIgnoreUnknown |= Args.hasArg(OPT_verify_ignore_unknown);
Opts.VerifyIgnoreUnrelated |= Args.hasArg(OPT_verify_ignore_unrelated);
Opts.SkipDiagnosticPasses |= Args.hasArg(OPT_disable_diagnostic_passes);
Opts.ShowDiagnosticsAfterFatalError |=
Args.hasArg(OPT_show_diagnostics_after_fatal);

View File

@@ -400,6 +400,48 @@ bool DiagnosticVerifier::verifyUnknown(
auto diag = SM.GetMessage({}, llvm::SourceMgr::DK_Error, Message, {}, {});
printDiagnostic(diag);
}
if (HadError) {
auto NoteMessage = "use '-verify-ignore-unknown' to "
"ignore diagnostics at this location";
auto noteDiag =
SM.GetMessage({}, llvm::SourceMgr::DK_Note, NoteMessage, {}, {});
printDiagnostic(noteDiag);
}
return HadError;
}
bool DiagnosticVerifier::verifyUnrelated(
std::vector<CapturedDiagnosticInfo> &CapturedDiagnostics) const {
bool HadError = false;
for (unsigned i = 0, e = CapturedDiagnostics.size(); i != e; ++i) {
SourceLoc Loc = CapturedDiagnostics[i].Loc;
if (!Loc.isValid())
// checked by verifyUnknown
continue;
HadError = true;
std::string Message =
("unexpected " +
getDiagKindString(CapturedDiagnostics[i].Classification) +
" produced: " + CapturedDiagnostics[i].Message)
.str();
auto diag = SM.GetMessage(Loc, llvm::SourceMgr::DK_Error, Message, {}, {});
printDiagnostic(diag);
auto FileName = SM.getIdentifierForBuffer(SM.findBufferContainingLoc(Loc));
auto NoteMessage = ("file '" + FileName +
"' is not parsed for 'expected' statements. Use "
"'-verify-additional-file " +
FileName +
"' to enable, or '-verify-ignore-unrelated' to "
"ignore diagnostics in this file");
auto noteDiag =
SM.GetMessage(Loc, llvm::SourceMgr::DK_Note, NoteMessage, {}, {});
printDiagnostic(noteDiag);
}
return HadError;
}

View File

@@ -434,8 +434,8 @@ bool CompilerInstance::setupDiagnosticVerifierIfNeeded() {
DiagVerifier = std::make_unique<DiagnosticVerifier>(
SourceMgr, InputSourceCodeBufferIDs, diagOpts.AdditionalVerifierFiles,
diagOpts.VerifyMode == DiagnosticOptions::VerifyAndApplyFixes,
diagOpts.VerifyIgnoreUnknown, diagOpts.UseColor,
diagOpts.AdditionalDiagnosticVerifierPrefixes);
diagOpts.VerifyIgnoreUnknown, diagOpts.VerifyIgnoreUnrelated,
diagOpts.UseColor, diagOpts.AdditionalDiagnosticVerifierPrefixes);
addDiagnosticConsumer(DiagVerifier.get());
}