-
Notifications
You must be signed in to change notification settings - Fork 14.4k
Reapply "[clang] Extend diagnose_if to accept more detailed warning information (#70976)" #108453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…nformation (llvm#70976)" This reverts commit e0cd11e. Fix flang
@llvm/pr-subscribers-flang-driver @llvm/pr-subscribers-clang-tools-extra Author: Nikolas Klauser (philnik777) ChangesThis reverts commit e0cd11e. Fix flang Patch is 65.53 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/108453.diff 29 Files Affected:
diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp
index d5eca083eb6512..552dd36b6900bf 100644
--- a/clang-tools-extra/clangd/Diagnostics.cpp
+++ b/clang-tools-extra/clangd/Diagnostics.cpp
@@ -579,7 +579,17 @@ std::vector<Diag> StoreDiags::take(const clang::tidy::ClangTidyContext *Tidy) {
for (auto &Diag : Output) {
if (const char *ClangDiag = getDiagnosticCode(Diag.ID)) {
// Warnings controlled by -Wfoo are better recognized by that name.
- StringRef Warning = DiagnosticIDs::getWarningOptionForDiag(Diag.ID);
+ const StringRef Warning = [&] {
+ if (OrigSrcMgr) {
+ return OrigSrcMgr->getDiagnostics()
+ .getDiagnosticIDs()
+ ->getWarningOptionForDiag(Diag.ID);
+ }
+ if (!DiagnosticIDs::IsCustomDiag(Diag.ID))
+ return DiagnosticIDs{}.getWarningOptionForDiag(Diag.ID);
+ return StringRef{};
+ }();
+
if (!Warning.empty()) {
Diag.Name = ("-W" + Warning).str();
} else {
@@ -896,20 +906,23 @@ void StoreDiags::flushLastDiag() {
Output.push_back(std::move(*LastDiag));
}
-bool isBuiltinDiagnosticSuppressed(unsigned ID,
- const llvm::StringSet<> &Suppress,
- const LangOptions &LangOpts) {
+bool isDiagnosticSuppressed(const clang::Diagnostic &Diag,
+ const llvm::StringSet<> &Suppress,
+ const LangOptions &LangOpts) {
// Don't complain about header-only stuff in mainfiles if it's a header.
// FIXME: would be cleaner to suppress in clang, once we decide whether the
// behavior should be to silently-ignore or respect the pragma.
- if (ID == diag::pp_pragma_sysheader_in_main_file && LangOpts.IsHeaderFile)
+ if (Diag.getID() == diag::pp_pragma_sysheader_in_main_file &&
+ LangOpts.IsHeaderFile)
return true;
- if (const char *CodePtr = getDiagnosticCode(ID)) {
+ if (const char *CodePtr = getDiagnosticCode(Diag.getID())) {
if (Suppress.contains(normalizeSuppressedCode(CodePtr)))
return true;
}
- StringRef Warning = DiagnosticIDs::getWarningOptionForDiag(ID);
+ StringRef Warning =
+ Diag.getDiags()->getDiagnosticIDs()->getWarningOptionForDiag(
+ Diag.getID());
if (!Warning.empty() && Suppress.contains(Warning))
return true;
return false;
diff --git a/clang-tools-extra/clangd/Diagnostics.h b/clang-tools-extra/clangd/Diagnostics.h
index d4c0478c63a5cf..c45d8dc3aa6ce6 100644
--- a/clang-tools-extra/clangd/Diagnostics.h
+++ b/clang-tools-extra/clangd/Diagnostics.h
@@ -181,11 +181,11 @@ class StoreDiags : public DiagnosticConsumer {
};
/// Determine whether a (non-clang-tidy) diagnostic is suppressed by config.
-bool isBuiltinDiagnosticSuppressed(unsigned ID,
- const llvm::StringSet<> &Suppressed,
- const LangOptions &);
+bool isDiagnosticSuppressed(const clang::Diagnostic &Diag,
+ const llvm::StringSet<> &Suppressed,
+ const LangOptions &);
/// Take a user-specified diagnostic code, and convert it to a normalized form
-/// stored in the config and consumed by isBuiltinDiagnosticsSuppressed.
+/// stored in the config and consumed by isDiagnosticsSuppressed.
///
/// (This strips err_ and -W prefix so we can match with or without them.)
llvm::StringRef normalizeSuppressedCode(llvm::StringRef);
diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp
index a8b6cc8dd0a46f..4491be9aa0362b 100644
--- a/clang-tools-extra/clangd/ParsedAST.cpp
+++ b/clang-tools-extra/clangd/ParsedAST.cpp
@@ -340,7 +340,7 @@ void applyWarningOptions(llvm::ArrayRef<std::string> ExtraArgs,
if (Enable) {
if (Diags.getDiagnosticLevel(ID, SourceLocation()) <
DiagnosticsEngine::Warning) {
- auto Group = DiagnosticIDs::getGroupForDiag(ID);
+ auto Group = Diags.getDiagnosticIDs()->getGroupForDiag(ID);
if (!Group || !EnabledGroups(*Group))
continue;
Diags.setSeverity(ID, diag::Severity::Warning, SourceLocation());
@@ -583,8 +583,8 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
ASTDiags.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &Info) {
if (Cfg.Diagnostics.SuppressAll ||
- isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress,
- Clang->getLangOpts()))
+ isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress,
+ Clang->getLangOpts()))
return DiagnosticsEngine::Ignored;
auto It = OverriddenSeverity.find(Info.getID());
diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp
index dd13b1a9e5613d..84e8fec342829c 100644
--- a/clang-tools-extra/clangd/Preamble.cpp
+++ b/clang-tools-extra/clangd/Preamble.cpp
@@ -621,8 +621,8 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
PreambleDiagnostics.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &Info) {
if (Cfg.Diagnostics.SuppressAll ||
- isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress,
- CI.getLangOpts()))
+ isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress,
+ CI.getLangOpts()))
return DiagnosticsEngine::Ignored;
switch (Info.getID()) {
case diag::warn_no_newline_eof:
diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
index 4ecfdf0184ab40..a812bac0338aa7 100644
--- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
@@ -298,20 +298,41 @@ TEST_F(ConfigCompileTests, DiagnosticSuppression) {
"unreachable-code", "unused-variable",
"typecheck_bool_condition",
"unexpected_friend", "warn_alloca"));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
- diag::warn_unreachable, Conf.Diagnostics.Suppress, LangOptions()));
+ clang::DiagnosticsEngine DiagEngine(nullptr, nullptr,
+ new clang::IgnoringDiagConsumer);
+
+ using Diag = clang::Diagnostic;
+ {
+ auto D = DiagEngine.Report(diag::warn_unreachable);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
// Subcategory not respected/suppressed.
- EXPECT_FALSE(isBuiltinDiagnosticSuppressed(
- diag::warn_unreachable_break, Conf.Diagnostics.Suppress, LangOptions()));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
- diag::warn_unused_variable, Conf.Diagnostics.Suppress, LangOptions()));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(diag::err_typecheck_bool_condition,
- Conf.Diagnostics.Suppress,
- LangOptions()));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
- diag::err_unexpected_friend, Conf.Diagnostics.Suppress, LangOptions()));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
- diag::warn_alloca, Conf.Diagnostics.Suppress, LangOptions()));
+ {
+ auto D = DiagEngine.Report(diag::warn_unreachable_break);
+ EXPECT_FALSE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
+ {
+ auto D = DiagEngine.Report(diag::warn_unused_variable);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
+ {
+ auto D = DiagEngine.Report(diag::err_typecheck_bool_condition);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
+ {
+ auto D = DiagEngine.Report(diag::err_unexpected_friend);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
+ {
+ auto D = DiagEngine.Report(diag::warn_alloca);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
Frag.Diagnostics.Suppress.emplace_back("*");
EXPECT_TRUE(compileAndApply());
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 9a7b163b2c6da8..70fad60d4edbb5 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3358,18 +3358,16 @@ def DiagnoseIf : InheritableAttr {
let Spellings = [GNU<"diagnose_if">];
let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
- EnumArgument<"DiagnosticType", "DiagnosticType",
+ EnumArgument<"DefaultSeverity",
+ "DefaultSeverity",
/*is_string=*/true,
- ["error", "warning"],
- ["DT_Error", "DT_Warning"]>,
+ ["error", "warning"],
+ ["DS_error", "DS_warning"]>,
+ StringArgument<"WarningGroup", /*optional*/ 1>,
BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
DeclArgument<Named, "Parent", 0, /*fake*/ 1>];
let InheritEvenIfAlreadyPresent = 1;
let LateParsed = LateAttrParseStandard;
- let AdditionalMembers = [{
- bool isError() const { return diagnosticType == DT_Error; }
- bool isWarning() const { return diagnosticType == DT_Warning; }
- }];
let TemplateDependent = 1;
let Documentation = [DiagnoseIfDocs];
}
diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
index 0c7836c2ea569c..54b69e98540239 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -336,10 +336,12 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
// Map extensions to warnings or errors?
diag::Severity ExtBehavior = diag::Severity::Ignored;
- DiagState()
+ DiagnosticIDs &DiagIDs;
+
+ DiagState(DiagnosticIDs &DiagIDs)
: IgnoreAllWarnings(false), EnableAllWarnings(false),
WarningsAsErrors(false), ErrorsAsFatal(false),
- SuppressSystemWarnings(false) {}
+ SuppressSystemWarnings(false), DiagIDs(DiagIDs) {}
using iterator = llvm::DenseMap<unsigned, DiagnosticMapping>::iterator;
using const_iterator =
@@ -870,6 +872,8 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
/// \param FormatString A fixed diagnostic format string that will be hashed
/// and mapped to a unique DiagID.
template <unsigned N>
+ // TODO: Deprecate this once all uses are removed from LLVM
+ // [[deprecated("Use a CustomDiagDesc instead of a Level")]]
unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
StringRef(FormatString, N - 1));
diff --git a/clang/include/clang/Basic/DiagnosticCategories.h b/clang/include/clang/Basic/DiagnosticCategories.h
index 14be326f7515f8..839f8dee3ca89f 100644
--- a/clang/include/clang/Basic/DiagnosticCategories.h
+++ b/clang/include/clang/Basic/DiagnosticCategories.h
@@ -21,11 +21,12 @@ namespace clang {
};
enum class Group {
-#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
- GroupName,
+#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
+ GroupName,
#include "clang/Basic/DiagnosticGroups.inc"
#undef CATEGORY
#undef DIAG_ENTRY
+ NUM_GROUPS
};
} // end namespace diag
} // end namespace clang
diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h
index 8b976bdac6dc51..2402996ece5c94 100644
--- a/clang/include/clang/Basic/DiagnosticIDs.h
+++ b/clang/include/clang/Basic/DiagnosticIDs.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
#define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
+#include "clang/Basic/DiagnosticCategories.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
@@ -82,7 +83,7 @@ namespace clang {
/// to either Ignore (nothing), Remark (emit a remark), Warning
/// (emit a warning) or Error (emit as an error). It allows clients to
/// map ERRORs to Error or Fatal (stop emitting diagnostics after this one).
- enum class Severity {
+ enum class Severity : uint8_t {
// NOTE: 0 means "uncomputed".
Ignored = 1, ///< Do not present this diagnostic, ignore it.
Remark = 2, ///< Present this diagnostic as a remark.
@@ -179,13 +180,96 @@ class DiagnosticMapping {
class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
public:
/// The level of the diagnostic, after it has been through mapping.
- enum Level {
- Ignored, Note, Remark, Warning, Error, Fatal
+ enum Level : uint8_t { Ignored, Note, Remark, Warning, Error, Fatal };
+
+ // Diagnostic classes.
+ enum Class {
+ CLASS_INVALID = 0x00,
+ CLASS_NOTE = 0x01,
+ CLASS_REMARK = 0x02,
+ CLASS_WARNING = 0x03,
+ CLASS_EXTENSION = 0x04,
+ CLASS_ERROR = 0x05
+ };
+
+ static bool IsCustomDiag(diag::kind Diag) {
+ return Diag >= diag::DIAG_UPPER_LIMIT;
+ }
+
+ class CustomDiagDesc {
+ LLVM_PREFERRED_TYPE(diag::Severity)
+ unsigned DefaultSeverity : 3;
+ LLVM_PREFERRED_TYPE(Class)
+ unsigned DiagClass : 3;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ShowInSystemHeader : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ShowInSystemMacro : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasGroup : 1;
+ diag::Group Group;
+ std::string Description;
+
+ auto get_as_tuple() const {
+ return std::tuple(DefaultSeverity, DiagClass, ShowInSystemHeader,
+ ShowInSystemMacro, HasGroup, Group,
+ std::string_view{Description});
+ }
+
+ public:
+ CustomDiagDesc(diag::Severity DefaultSeverity, std::string Description,
+ unsigned Class = CLASS_WARNING,
+ bool ShowInSystemHeader = false,
+ bool ShowInSystemMacro = false,
+ std::optional<diag::Group> Group = std::nullopt)
+ : DefaultSeverity(static_cast<unsigned>(DefaultSeverity)),
+ DiagClass(Class), ShowInSystemHeader(ShowInSystemHeader),
+ ShowInSystemMacro(ShowInSystemMacro), HasGroup(Group != std::nullopt),
+ Group(Group.value_or(diag::Group{})),
+ Description(std::move(Description)) {}
+
+ std::optional<diag::Group> GetGroup() const {
+ if (HasGroup)
+ return Group;
+ return std::nullopt;
+ }
+
+ diag::Severity GetDefaultSeverity() const {
+ return static_cast<diag::Severity>(DefaultSeverity);
+ }
+
+ Class GetClass() const { return static_cast<Class>(DiagClass); }
+ std::string_view GetDescription() const { return Description; }
+ bool ShouldShowInSystemHeader() const { return ShowInSystemHeader; }
+
+ friend bool operator==(const CustomDiagDesc &lhs,
+ const CustomDiagDesc &rhs) {
+ return lhs.get_as_tuple() == rhs.get_as_tuple();
+ }
+
+ friend bool operator<(const CustomDiagDesc &lhs,
+ const CustomDiagDesc &rhs) {
+ return lhs.get_as_tuple() < rhs.get_as_tuple();
+ }
+ };
+
+ struct GroupInfo {
+ LLVM_PREFERRED_TYPE(diag::Severity)
+ unsigned Severity : 3;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasNoWarningAsError : 1;
};
private:
/// Information for uniquing and looking up custom diags.
std::unique_ptr<diag::CustomDiagInfo> CustomDiagInfo;
+ std::unique_ptr<GroupInfo[]> GroupInfos = []() {
+ auto GIs = std::make_unique<GroupInfo[]>(
+ static_cast<size_t>(diag::Group::NUM_GROUPS));
+ for (size_t i = 0; i != static_cast<size_t>(diag::Group::NUM_GROUPS); ++i)
+ GIs[i] = {{}, false};
+ return GIs;
+ }();
public:
DiagnosticIDs();
@@ -200,7 +284,34 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
// FIXME: Replace this function with a create-only facilty like
// createCustomDiagIDFromFormatString() to enforce safe usage. At the time of
// writing, nearly all callers of this function were invalid.
- unsigned getCustomDiagID(Level L, StringRef FormatString);
+ unsigned getCustomDiagID(CustomDiagDesc Diag);
+
+ // TODO: Deprecate this once all uses are removed from LLVM
+ // [[deprecated("Use a CustomDiagDesc instead of a Level")]]
+ unsigned getCustomDiagID(Level Level, StringRef Message) {
+ return getCustomDiagID([&]() -> CustomDiagDesc {
+ switch (Level) {
+ case DiagnosticIDs::Level::Ignored:
+ return {diag::Severity::Ignored, std::string(Message), CLASS_WARNING,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Note:
+ return {diag::Severity::Fatal, std::string(Message), CLASS_NOTE,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Remark:
+ return {diag::Severity::Remark, std::string(Message), CLASS_REMARK,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Warning:
+ return {diag::Severity::Warning, std::string(Message), CLASS_WARNING,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Error:
+ return {diag::Severity::Error, std::string(Message), CLASS_ERROR,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Fatal:
+ return {diag::Severity::Fatal, std::string(Message), CLASS_ERROR,
+ /*ShowInSystemHeader*/ true};
+ }
+ }());
+ }
//===--------------------------------------------------------------------===//
// Diagnostic classification and reporting interfaces.
@@ -212,35 +323,36 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
/// Return true if the unmapped diagnostic levelof the specified
/// diagnostic ID is a Warning or Extension.
///
- /// This only works on builtin diagnostics, not custom ones, and is not
- /// legal to call on NOTEs.
- static bool isBuiltinWarningOrExtension(unsigned DiagID);
+ /// This is not legal to call on NOTEs.
+ bool isWarningOrExtension(unsigned DiagID) const;
/// Return true if the specified diagnostic is mapped to errors by
/// default.
- static bool isDefaultMappingAsError(unsigned DiagID);
+ bool isDefaultMappingAsError(unsigned DiagID) const;
/// Get the default mapping for this diagnostic.
- static DiagnosticMapping getDefaultMapping(unsigned DiagID);
+ DiagnosticMapping getDefaultMapping(unsigned DiagID) const;
+
+ void initCustomDiagMapping(DiagnosticMapping &, unsigned DiagID);
- /// Determine whether the given built-in diagnostic ID is a Note.
- static bool isBuiltinNote(unsigned DiagID);
+ /// Determine whether the given diagnostic ID is a Note.
+ bool isNote(unsigned DiagID) const;
- /// Determine whether the given built-in diagnostic ID is for an
+ /// Determine whether the given diagnostic ID is for an
/// extension of some sort.
- static bool isBuiltinExtensionDiag(unsigned DiagID) {
+ bool isExtensionDiag(unsigned DiagID) const {
bool ignored;
- return isBuiltinExtensionDiag(DiagID, ignored);
+ return isExtensionDiag(DiagID, ignored);
}
- /// Determine whether the given built-in diagnostic ID is for an
+ /// Determine whether the given diagnostic ID is for an
/// extension of some sort, and whether it is enabled by default.
///
/// This also returns EnabledByDefault, which is set to indicate whether the
/// diagnostic is ignored by default (in which case -pedantic enables it) or
/// treated as a warning/error by default.
///
- static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
+ bool isExtensionDiag(unsigned DiagID, bool &EnabledByDefault) const;
/// Given a group ID, returns the flag that toggles the group.
/// For example, for Group::DeprecatedDeclarations, returns
@@ -250,19 +362,22 @@ class DiagnosticID...
[truncated]
|
@llvm/pr-subscribers-clang-static-analyzer-1 Author: Nikolas Klauser (philnik777) ChangesThis reverts commit e0cd11e. Fix flang Patch is 65.53 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/108453.diff 29 Files Affected:
diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp
index d5eca083eb6512..552dd36b6900bf 100644
--- a/clang-tools-extra/clangd/Diagnostics.cpp
+++ b/clang-tools-extra/clangd/Diagnostics.cpp
@@ -579,7 +579,17 @@ std::vector<Diag> StoreDiags::take(const clang::tidy::ClangTidyContext *Tidy) {
for (auto &Diag : Output) {
if (const char *ClangDiag = getDiagnosticCode(Diag.ID)) {
// Warnings controlled by -Wfoo are better recognized by that name.
- StringRef Warning = DiagnosticIDs::getWarningOptionForDiag(Diag.ID);
+ const StringRef Warning = [&] {
+ if (OrigSrcMgr) {
+ return OrigSrcMgr->getDiagnostics()
+ .getDiagnosticIDs()
+ ->getWarningOptionForDiag(Diag.ID);
+ }
+ if (!DiagnosticIDs::IsCustomDiag(Diag.ID))
+ return DiagnosticIDs{}.getWarningOptionForDiag(Diag.ID);
+ return StringRef{};
+ }();
+
if (!Warning.empty()) {
Diag.Name = ("-W" + Warning).str();
} else {
@@ -896,20 +906,23 @@ void StoreDiags::flushLastDiag() {
Output.push_back(std::move(*LastDiag));
}
-bool isBuiltinDiagnosticSuppressed(unsigned ID,
- const llvm::StringSet<> &Suppress,
- const LangOptions &LangOpts) {
+bool isDiagnosticSuppressed(const clang::Diagnostic &Diag,
+ const llvm::StringSet<> &Suppress,
+ const LangOptions &LangOpts) {
// Don't complain about header-only stuff in mainfiles if it's a header.
// FIXME: would be cleaner to suppress in clang, once we decide whether the
// behavior should be to silently-ignore or respect the pragma.
- if (ID == diag::pp_pragma_sysheader_in_main_file && LangOpts.IsHeaderFile)
+ if (Diag.getID() == diag::pp_pragma_sysheader_in_main_file &&
+ LangOpts.IsHeaderFile)
return true;
- if (const char *CodePtr = getDiagnosticCode(ID)) {
+ if (const char *CodePtr = getDiagnosticCode(Diag.getID())) {
if (Suppress.contains(normalizeSuppressedCode(CodePtr)))
return true;
}
- StringRef Warning = DiagnosticIDs::getWarningOptionForDiag(ID);
+ StringRef Warning =
+ Diag.getDiags()->getDiagnosticIDs()->getWarningOptionForDiag(
+ Diag.getID());
if (!Warning.empty() && Suppress.contains(Warning))
return true;
return false;
diff --git a/clang-tools-extra/clangd/Diagnostics.h b/clang-tools-extra/clangd/Diagnostics.h
index d4c0478c63a5cf..c45d8dc3aa6ce6 100644
--- a/clang-tools-extra/clangd/Diagnostics.h
+++ b/clang-tools-extra/clangd/Diagnostics.h
@@ -181,11 +181,11 @@ class StoreDiags : public DiagnosticConsumer {
};
/// Determine whether a (non-clang-tidy) diagnostic is suppressed by config.
-bool isBuiltinDiagnosticSuppressed(unsigned ID,
- const llvm::StringSet<> &Suppressed,
- const LangOptions &);
+bool isDiagnosticSuppressed(const clang::Diagnostic &Diag,
+ const llvm::StringSet<> &Suppressed,
+ const LangOptions &);
/// Take a user-specified diagnostic code, and convert it to a normalized form
-/// stored in the config and consumed by isBuiltinDiagnosticsSuppressed.
+/// stored in the config and consumed by isDiagnosticsSuppressed.
///
/// (This strips err_ and -W prefix so we can match with or without them.)
llvm::StringRef normalizeSuppressedCode(llvm::StringRef);
diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp
index a8b6cc8dd0a46f..4491be9aa0362b 100644
--- a/clang-tools-extra/clangd/ParsedAST.cpp
+++ b/clang-tools-extra/clangd/ParsedAST.cpp
@@ -340,7 +340,7 @@ void applyWarningOptions(llvm::ArrayRef<std::string> ExtraArgs,
if (Enable) {
if (Diags.getDiagnosticLevel(ID, SourceLocation()) <
DiagnosticsEngine::Warning) {
- auto Group = DiagnosticIDs::getGroupForDiag(ID);
+ auto Group = Diags.getDiagnosticIDs()->getGroupForDiag(ID);
if (!Group || !EnabledGroups(*Group))
continue;
Diags.setSeverity(ID, diag::Severity::Warning, SourceLocation());
@@ -583,8 +583,8 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
ASTDiags.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &Info) {
if (Cfg.Diagnostics.SuppressAll ||
- isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress,
- Clang->getLangOpts()))
+ isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress,
+ Clang->getLangOpts()))
return DiagnosticsEngine::Ignored;
auto It = OverriddenSeverity.find(Info.getID());
diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp
index dd13b1a9e5613d..84e8fec342829c 100644
--- a/clang-tools-extra/clangd/Preamble.cpp
+++ b/clang-tools-extra/clangd/Preamble.cpp
@@ -621,8 +621,8 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
PreambleDiagnostics.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &Info) {
if (Cfg.Diagnostics.SuppressAll ||
- isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress,
- CI.getLangOpts()))
+ isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress,
+ CI.getLangOpts()))
return DiagnosticsEngine::Ignored;
switch (Info.getID()) {
case diag::warn_no_newline_eof:
diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
index 4ecfdf0184ab40..a812bac0338aa7 100644
--- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
@@ -298,20 +298,41 @@ TEST_F(ConfigCompileTests, DiagnosticSuppression) {
"unreachable-code", "unused-variable",
"typecheck_bool_condition",
"unexpected_friend", "warn_alloca"));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
- diag::warn_unreachable, Conf.Diagnostics.Suppress, LangOptions()));
+ clang::DiagnosticsEngine DiagEngine(nullptr, nullptr,
+ new clang::IgnoringDiagConsumer);
+
+ using Diag = clang::Diagnostic;
+ {
+ auto D = DiagEngine.Report(diag::warn_unreachable);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
// Subcategory not respected/suppressed.
- EXPECT_FALSE(isBuiltinDiagnosticSuppressed(
- diag::warn_unreachable_break, Conf.Diagnostics.Suppress, LangOptions()));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
- diag::warn_unused_variable, Conf.Diagnostics.Suppress, LangOptions()));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(diag::err_typecheck_bool_condition,
- Conf.Diagnostics.Suppress,
- LangOptions()));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
- diag::err_unexpected_friend, Conf.Diagnostics.Suppress, LangOptions()));
- EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
- diag::warn_alloca, Conf.Diagnostics.Suppress, LangOptions()));
+ {
+ auto D = DiagEngine.Report(diag::warn_unreachable_break);
+ EXPECT_FALSE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
+ {
+ auto D = DiagEngine.Report(diag::warn_unused_variable);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
+ {
+ auto D = DiagEngine.Report(diag::err_typecheck_bool_condition);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
+ {
+ auto D = DiagEngine.Report(diag::err_unexpected_friend);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
+ {
+ auto D = DiagEngine.Report(diag::warn_alloca);
+ EXPECT_TRUE(isDiagnosticSuppressed(
+ Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
+ }
Frag.Diagnostics.Suppress.emplace_back("*");
EXPECT_TRUE(compileAndApply());
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 9a7b163b2c6da8..70fad60d4edbb5 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3358,18 +3358,16 @@ def DiagnoseIf : InheritableAttr {
let Spellings = [GNU<"diagnose_if">];
let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
- EnumArgument<"DiagnosticType", "DiagnosticType",
+ EnumArgument<"DefaultSeverity",
+ "DefaultSeverity",
/*is_string=*/true,
- ["error", "warning"],
- ["DT_Error", "DT_Warning"]>,
+ ["error", "warning"],
+ ["DS_error", "DS_warning"]>,
+ StringArgument<"WarningGroup", /*optional*/ 1>,
BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
DeclArgument<Named, "Parent", 0, /*fake*/ 1>];
let InheritEvenIfAlreadyPresent = 1;
let LateParsed = LateAttrParseStandard;
- let AdditionalMembers = [{
- bool isError() const { return diagnosticType == DT_Error; }
- bool isWarning() const { return diagnosticType == DT_Warning; }
- }];
let TemplateDependent = 1;
let Documentation = [DiagnoseIfDocs];
}
diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
index 0c7836c2ea569c..54b69e98540239 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -336,10 +336,12 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
// Map extensions to warnings or errors?
diag::Severity ExtBehavior = diag::Severity::Ignored;
- DiagState()
+ DiagnosticIDs &DiagIDs;
+
+ DiagState(DiagnosticIDs &DiagIDs)
: IgnoreAllWarnings(false), EnableAllWarnings(false),
WarningsAsErrors(false), ErrorsAsFatal(false),
- SuppressSystemWarnings(false) {}
+ SuppressSystemWarnings(false), DiagIDs(DiagIDs) {}
using iterator = llvm::DenseMap<unsigned, DiagnosticMapping>::iterator;
using const_iterator =
@@ -870,6 +872,8 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
/// \param FormatString A fixed diagnostic format string that will be hashed
/// and mapped to a unique DiagID.
template <unsigned N>
+ // TODO: Deprecate this once all uses are removed from LLVM
+ // [[deprecated("Use a CustomDiagDesc instead of a Level")]]
unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
StringRef(FormatString, N - 1));
diff --git a/clang/include/clang/Basic/DiagnosticCategories.h b/clang/include/clang/Basic/DiagnosticCategories.h
index 14be326f7515f8..839f8dee3ca89f 100644
--- a/clang/include/clang/Basic/DiagnosticCategories.h
+++ b/clang/include/clang/Basic/DiagnosticCategories.h
@@ -21,11 +21,12 @@ namespace clang {
};
enum class Group {
-#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
- GroupName,
+#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
+ GroupName,
#include "clang/Basic/DiagnosticGroups.inc"
#undef CATEGORY
#undef DIAG_ENTRY
+ NUM_GROUPS
};
} // end namespace diag
} // end namespace clang
diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h
index 8b976bdac6dc51..2402996ece5c94 100644
--- a/clang/include/clang/Basic/DiagnosticIDs.h
+++ b/clang/include/clang/Basic/DiagnosticIDs.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
#define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
+#include "clang/Basic/DiagnosticCategories.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
@@ -82,7 +83,7 @@ namespace clang {
/// to either Ignore (nothing), Remark (emit a remark), Warning
/// (emit a warning) or Error (emit as an error). It allows clients to
/// map ERRORs to Error or Fatal (stop emitting diagnostics after this one).
- enum class Severity {
+ enum class Severity : uint8_t {
// NOTE: 0 means "uncomputed".
Ignored = 1, ///< Do not present this diagnostic, ignore it.
Remark = 2, ///< Present this diagnostic as a remark.
@@ -179,13 +180,96 @@ class DiagnosticMapping {
class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
public:
/// The level of the diagnostic, after it has been through mapping.
- enum Level {
- Ignored, Note, Remark, Warning, Error, Fatal
+ enum Level : uint8_t { Ignored, Note, Remark, Warning, Error, Fatal };
+
+ // Diagnostic classes.
+ enum Class {
+ CLASS_INVALID = 0x00,
+ CLASS_NOTE = 0x01,
+ CLASS_REMARK = 0x02,
+ CLASS_WARNING = 0x03,
+ CLASS_EXTENSION = 0x04,
+ CLASS_ERROR = 0x05
+ };
+
+ static bool IsCustomDiag(diag::kind Diag) {
+ return Diag >= diag::DIAG_UPPER_LIMIT;
+ }
+
+ class CustomDiagDesc {
+ LLVM_PREFERRED_TYPE(diag::Severity)
+ unsigned DefaultSeverity : 3;
+ LLVM_PREFERRED_TYPE(Class)
+ unsigned DiagClass : 3;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ShowInSystemHeader : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ShowInSystemMacro : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasGroup : 1;
+ diag::Group Group;
+ std::string Description;
+
+ auto get_as_tuple() const {
+ return std::tuple(DefaultSeverity, DiagClass, ShowInSystemHeader,
+ ShowInSystemMacro, HasGroup, Group,
+ std::string_view{Description});
+ }
+
+ public:
+ CustomDiagDesc(diag::Severity DefaultSeverity, std::string Description,
+ unsigned Class = CLASS_WARNING,
+ bool ShowInSystemHeader = false,
+ bool ShowInSystemMacro = false,
+ std::optional<diag::Group> Group = std::nullopt)
+ : DefaultSeverity(static_cast<unsigned>(DefaultSeverity)),
+ DiagClass(Class), ShowInSystemHeader(ShowInSystemHeader),
+ ShowInSystemMacro(ShowInSystemMacro), HasGroup(Group != std::nullopt),
+ Group(Group.value_or(diag::Group{})),
+ Description(std::move(Description)) {}
+
+ std::optional<diag::Group> GetGroup() const {
+ if (HasGroup)
+ return Group;
+ return std::nullopt;
+ }
+
+ diag::Severity GetDefaultSeverity() const {
+ return static_cast<diag::Severity>(DefaultSeverity);
+ }
+
+ Class GetClass() const { return static_cast<Class>(DiagClass); }
+ std::string_view GetDescription() const { return Description; }
+ bool ShouldShowInSystemHeader() const { return ShowInSystemHeader; }
+
+ friend bool operator==(const CustomDiagDesc &lhs,
+ const CustomDiagDesc &rhs) {
+ return lhs.get_as_tuple() == rhs.get_as_tuple();
+ }
+
+ friend bool operator<(const CustomDiagDesc &lhs,
+ const CustomDiagDesc &rhs) {
+ return lhs.get_as_tuple() < rhs.get_as_tuple();
+ }
+ };
+
+ struct GroupInfo {
+ LLVM_PREFERRED_TYPE(diag::Severity)
+ unsigned Severity : 3;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasNoWarningAsError : 1;
};
private:
/// Information for uniquing and looking up custom diags.
std::unique_ptr<diag::CustomDiagInfo> CustomDiagInfo;
+ std::unique_ptr<GroupInfo[]> GroupInfos = []() {
+ auto GIs = std::make_unique<GroupInfo[]>(
+ static_cast<size_t>(diag::Group::NUM_GROUPS));
+ for (size_t i = 0; i != static_cast<size_t>(diag::Group::NUM_GROUPS); ++i)
+ GIs[i] = {{}, false};
+ return GIs;
+ }();
public:
DiagnosticIDs();
@@ -200,7 +284,34 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
// FIXME: Replace this function with a create-only facilty like
// createCustomDiagIDFromFormatString() to enforce safe usage. At the time of
// writing, nearly all callers of this function were invalid.
- unsigned getCustomDiagID(Level L, StringRef FormatString);
+ unsigned getCustomDiagID(CustomDiagDesc Diag);
+
+ // TODO: Deprecate this once all uses are removed from LLVM
+ // [[deprecated("Use a CustomDiagDesc instead of a Level")]]
+ unsigned getCustomDiagID(Level Level, StringRef Message) {
+ return getCustomDiagID([&]() -> CustomDiagDesc {
+ switch (Level) {
+ case DiagnosticIDs::Level::Ignored:
+ return {diag::Severity::Ignored, std::string(Message), CLASS_WARNING,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Note:
+ return {diag::Severity::Fatal, std::string(Message), CLASS_NOTE,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Remark:
+ return {diag::Severity::Remark, std::string(Message), CLASS_REMARK,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Warning:
+ return {diag::Severity::Warning, std::string(Message), CLASS_WARNING,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Error:
+ return {diag::Severity::Error, std::string(Message), CLASS_ERROR,
+ /*ShowInSystemHeader*/ true};
+ case DiagnosticIDs::Level::Fatal:
+ return {diag::Severity::Fatal, std::string(Message), CLASS_ERROR,
+ /*ShowInSystemHeader*/ true};
+ }
+ }());
+ }
//===--------------------------------------------------------------------===//
// Diagnostic classification and reporting interfaces.
@@ -212,35 +323,36 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
/// Return true if the unmapped diagnostic levelof the specified
/// diagnostic ID is a Warning or Extension.
///
- /// This only works on builtin diagnostics, not custom ones, and is not
- /// legal to call on NOTEs.
- static bool isBuiltinWarningOrExtension(unsigned DiagID);
+ /// This is not legal to call on NOTEs.
+ bool isWarningOrExtension(unsigned DiagID) const;
/// Return true if the specified diagnostic is mapped to errors by
/// default.
- static bool isDefaultMappingAsError(unsigned DiagID);
+ bool isDefaultMappingAsError(unsigned DiagID) const;
/// Get the default mapping for this diagnostic.
- static DiagnosticMapping getDefaultMapping(unsigned DiagID);
+ DiagnosticMapping getDefaultMapping(unsigned DiagID) const;
+
+ void initCustomDiagMapping(DiagnosticMapping &, unsigned DiagID);
- /// Determine whether the given built-in diagnostic ID is a Note.
- static bool isBuiltinNote(unsigned DiagID);
+ /// Determine whether the given diagnostic ID is a Note.
+ bool isNote(unsigned DiagID) const;
- /// Determine whether the given built-in diagnostic ID is for an
+ /// Determine whether the given diagnostic ID is for an
/// extension of some sort.
- static bool isBuiltinExtensionDiag(unsigned DiagID) {
+ bool isExtensionDiag(unsigned DiagID) const {
bool ignored;
- return isBuiltinExtensionDiag(DiagID, ignored);
+ return isExtensionDiag(DiagID, ignored);
}
- /// Determine whether the given built-in diagnostic ID is for an
+ /// Determine whether the given diagnostic ID is for an
/// extension of some sort, and whether it is enabled by default.
///
/// This also returns EnabledByDefault, which is set to indicate whether the
/// diagnostic is ignored by default (in which case -pedantic enables it) or
/// treated as a warning/error by default.
///
- static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
+ bool isExtensionDiag(unsigned DiagID, bool &EnabledByDefault) const;
/// Given a group ID, returns the flag that toggles the group.
/// For example, for Group::DeprecatedDeclarations, returns
@@ -250,19 +362,22 @@ class DiagnosticID...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff d37d05795dbbdd1b7e629e966013df5967d2da5b b429f137f3c1e2b2a72c9f3f444f6d43a8b5e35d --extensions c,h,cpp -- clang/test/SemaCXX/diagnose_if-warning-group.cpp clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/Diagnostics.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp clang/include/clang/Basic/Diagnostic.h clang/include/clang/Basic/DiagnosticCategories.h clang/include/clang/Basic/DiagnosticIDs.h clang/lib/Basic/Diagnostic.cpp clang/lib/Basic/DiagnosticIDs.cpp clang/lib/Frontend/LogDiagnosticPrinter.cpp clang/lib/Frontend/SerializedDiagnosticPrinter.cpp clang/lib/Frontend/TextDiagnosticPrinter.cpp clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaCUDA.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/lib/Sema/SemaOverload.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp clang/test/Sema/diagnose_if.c clang/tools/diagtool/ListWarnings.cpp clang/tools/diagtool/ShowEnabledWarnings.cpp clang/tools/libclang/CXStoredDiagnostic.cpp flang/lib/Frontend/TextDiagnosticPrinter.cpp View the diff from clang-format here.diff --git a/flang/lib/Frontend/TextDiagnosticPrinter.cpp b/flang/lib/Frontend/TextDiagnosticPrinter.cpp
index 8b00fb69b3..e4d4cbe91b 100644
--- a/flang/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/flang/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -38,8 +38,9 @@ TextDiagnosticPrinter::~TextDiagnosticPrinter() {}
static void printRemarkOption(llvm::raw_ostream &os,
clang::DiagnosticsEngine::Level level,
const clang::Diagnostic &info) {
- llvm::StringRef opt = info.getDiags()->getDiagnosticIDs()
- ->getWarningOptionForDiag(info.getID());
+ llvm::StringRef opt =
+ info.getDiags()->getDiagnosticIDs()->getWarningOptionForDiag(
+ info.getID());
if (!opt.empty()) {
// We still need to check if the level is a Remark since, an unknown option
// warning could be printed i.e. [-Wunknown-warning-option]
|
This caused a UBSan violation:
|
…arning information (#70976)" (#108453)" This reverts commit e7f782e. This had UBSan failures: [----------] 1 test from ConfigCompileTests [ RUN ] ConfigCompileTests.DiagnosticSuppression Config fragment: compiling <unknown>:0 -> 0x00007B8366E2F7D8 (trusted=false) /usr/local/google/home/fmayer/large/llvm-project/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h:203:33: runtime error: reference binding to null pointer of type 'clang::DiagnosticIDs' UndefinedBehaviorSanitizer: undefined-behavior /usr/local/google/home/fmayer/large/llvm-project/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h:203:33 Pull Request: #108645
Hello, I noticed that before this patch Is this on purpose? |
This reverts commit e0cd11e.
Update the use of
getWarningOptionForDiag
in flang to use the DiagnosticIDs.