Skip to content

Commit a609c6d

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.6
2 parents 009da92 + b0aa1c4 commit a609c6d

File tree

8 files changed

+38
-76
lines changed

8 files changed

+38
-76
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ Potentially Breaking Changes
6969
call the member ``operator delete`` instead of the expected global
7070
delete operator. The old behavior is retained under ``-fclang-abi-compat=21``
7171
flag.
72+
- Clang warning suppressions file, ``--warning-suppression-mappings=``, now will
73+
use the last matching entry instead of the longest one.
7274

7375
C/C++ Language Potentially Breaking Changes
7476
-------------------------------------------

clang/docs/WarningSuppressionMappings.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Format
6363
Warning suppression mappings uses the same format as
6464
:doc:`SanitizerSpecialCaseList`.
6565

66-
Sections describe which diagnostic group's behaviour to change, e.g.
66+
Sections describe which diagnostic group's behavior to change, e.g.
6767
``[unused]``. When a diagnostic is matched by multiple sections, the latest
6868
section takes precedence.
6969

@@ -76,7 +76,7 @@ Source files are matched against these globs either:
7676
- as paths relative to the current working directory
7777
- as absolute paths.
7878

79-
When a source file matches multiple globs in a section, the longest one takes
79+
When a source file matches multiple globs in a section, the last one takes
8080
precedence.
8181

8282
.. code-block:: bash

clang/include/clang/Basic/Diagnostic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
971971
/// diagnostics in specific files.
972972
/// Mapping file is expected to be a special case list with sections denoting
973973
/// diagnostic groups and `src` entries for globs to suppress. `emit` category
974-
/// can be used to disable suppression. Longest glob that matches a filepath
974+
/// can be used to disable suppression. THe last glob that matches a filepath
975975
/// takes precedence. For example:
976976
/// [unused]
977977
/// src:clang/*

clang/lib/Basic/Diagnostic.cpp

Lines changed: 24 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -517,12 +517,6 @@ class WarningsSpecialCaseList : public llvm::SpecialCaseList {
517517
const SourceManager &SM) const;
518518

519519
private:
520-
// Find the longest glob pattern that matches FilePath amongst
521-
// CategoriesToMatchers, return true iff the match exists and belongs to a
522-
// positive category.
523-
bool globsMatches(const llvm::StringMap<Matcher> &CategoriesToMatchers,
524-
StringRef FilePath) const;
525-
526520
llvm::DenseMap<diag::kind, const Section *> DiagToSection;
527521
};
528522
} // namespace
@@ -537,33 +531,16 @@ WarningsSpecialCaseList::create(const llvm::MemoryBuffer &Input,
537531
}
538532

539533
void WarningsSpecialCaseList::processSections(DiagnosticsEngine &Diags) {
540-
// Drop the default section introduced by special case list, we only support
541-
// exact diagnostic group names.
542-
// FIXME: We should make this configurable in the parser instead.
543-
// FIXME: C++20 can use std::erase_if(Sections, [](Section &sec) { return
544-
// sec.SectionStr == "*"; });
545-
llvm::erase_if(Sections, [](Section &sec) { return sec.SectionStr == "*"; });
546-
// Make sure we iterate sections by their line numbers.
547-
std::vector<std::pair<unsigned, const Section *>> LineAndSectionEntry;
548-
LineAndSectionEntry.reserve(Sections.size());
549-
for (const auto &Entry : Sections) {
550-
StringRef DiagName = Entry.SectionStr;
551-
// Each section has a matcher with that section's name, attached to that
552-
// line.
553-
const auto &DiagSectionMatcher = Entry.SectionMatcher;
554-
unsigned DiagLine = 0;
555-
for (const auto &Glob : DiagSectionMatcher->Globs)
556-
if (Glob->Name == DiagName) {
557-
DiagLine = Glob->LineNo;
558-
break;
559-
}
560-
LineAndSectionEntry.emplace_back(DiagLine, &Entry);
561-
}
562-
llvm::sort(LineAndSectionEntry);
563534
static constexpr auto WarningFlavor = clang::diag::Flavor::WarningOrError;
564-
for (const auto &[_, SectionEntry] : LineAndSectionEntry) {
535+
for (const auto &SectionEntry : Sections) {
536+
StringRef DiagGroup = SectionEntry.SectionStr;
537+
if (DiagGroup == "*") {
538+
// Drop the default section introduced by special case list, we only
539+
// support exact diagnostic group names.
540+
// FIXME: We should make this configurable in the parser instead.
541+
continue;
542+
}
565543
SmallVector<diag::kind> GroupDiags;
566-
StringRef DiagGroup = SectionEntry->SectionStr;
567544
if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup(
568545
WarningFlavor, DiagGroup, GroupDiags)) {
569546
StringRef Suggestion =
@@ -576,7 +553,7 @@ void WarningsSpecialCaseList::processSections(DiagnosticsEngine &Diags) {
576553
for (diag::kind Diag : GroupDiags)
577554
// We're intentionally overwriting any previous mappings here to make sure
578555
// latest one takes precedence.
579-
DiagToSection[Diag] = SectionEntry;
556+
DiagToSection[Diag] = &SectionEntry;
580557
}
581558
}
582559

@@ -601,43 +578,26 @@ void DiagnosticsEngine::setDiagSuppressionMapping(llvm::MemoryBuffer &Input) {
601578
bool WarningsSpecialCaseList::isDiagSuppressed(diag::kind DiagId,
602579
SourceLocation DiagLoc,
603580
const SourceManager &SM) const {
581+
PresumedLoc PLoc = SM.getPresumedLoc(DiagLoc);
582+
if (!PLoc.isValid())
583+
return false;
604584
const Section *DiagSection = DiagToSection.lookup(DiagId);
605585
if (!DiagSection)
606586
return false;
607-
const SectionEntries &EntityTypeToCategories = DiagSection->Entries;
608-
auto SrcEntriesIt = EntityTypeToCategories.find("src");
609-
if (SrcEntriesIt == EntityTypeToCategories.end())
587+
588+
StringRef F = llvm::sys::path::remove_leading_dotslash(PLoc.getFilename());
589+
590+
unsigned SuppressLineNo =
591+
llvm::SpecialCaseList::inSectionBlame(DiagSection->Entries, "src", F, "");
592+
if (!SuppressLineNo)
610593
return false;
611-
const llvm::StringMap<llvm::SpecialCaseList::Matcher> &CategoriesToMatchers =
612-
SrcEntriesIt->getValue();
613-
// We also use presumed locations here to improve reproducibility for
614-
// preprocessed inputs.
615-
if (PresumedLoc PLoc = SM.getPresumedLoc(DiagLoc); PLoc.isValid())
616-
return globsMatches(
617-
CategoriesToMatchers,
618-
llvm::sys::path::remove_leading_dotslash(PLoc.getFilename()));
619-
return false;
620-
}
621594

622-
bool WarningsSpecialCaseList::globsMatches(
623-
const llvm::StringMap<Matcher> &CategoriesToMatchers,
624-
StringRef FilePath) const {
625-
StringRef LongestMatch;
626-
bool LongestIsPositive = false;
627-
for (const auto &Entry : CategoriesToMatchers) {
628-
StringRef Category = Entry.getKey();
629-
const llvm::SpecialCaseList::Matcher &Matcher = Entry.getValue();
630-
bool IsPositive = Category != "emit";
631-
for (const auto &Glob : Matcher.Globs) {
632-
if (Glob->Name.size() < LongestMatch.size())
633-
continue;
634-
if (!Glob->Pattern.match(FilePath))
635-
continue;
636-
LongestMatch = Glob->Name;
637-
LongestIsPositive = IsPositive;
638-
}
639-
}
640-
return LongestIsPositive;
595+
unsigned EmitLineNo = llvm::SpecialCaseList::inSectionBlame(
596+
DiagSection->Entries, "src", F, "emit");
597+
if (!EmitLineNo)
598+
return true;
599+
600+
return SuppressLineNo > EmitLineNo;
641601
}
642602

643603
bool DiagnosticsEngine::isSuppressedViaMapping(diag::kind DiagId,

clang/lib/Basic/SanitizerSpecialCaseList.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void SanitizerSpecialCaseList::createSanitizerSections() {
4242
SanitizerMask Mask;
4343

4444
#define SANITIZER(NAME, ID) \
45-
if (S.SectionMatcher->match(NAME)) \
45+
if (S.SectionMatcher.match(NAME)) \
4646
Mask |= SanitizerKind::ID;
4747
#define SANITIZER_GROUP(NAME, ID, ALIAS) SANITIZER(NAME, ID)
4848

clang/unittests/Basic/DiagnosticTest.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ TEST_F(SuppressionMappingTest, EmitCategoryIsExcluded) {
294294
locForFile("foo.cpp")));
295295
}
296296

297-
TEST_F(SuppressionMappingTest, LongestMatchWins) {
297+
TEST_F(SuppressionMappingTest, LastMatchWins) {
298298
llvm::StringLiteral SuppressionMappingFile = R"(
299299
[unused]
300300
src:*clang/*
@@ -327,10 +327,8 @@ TEST_F(SuppressionMappingTest, LongShortMatch) {
327327

328328
EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function,
329329
locForFile("test/t1.cpp")));
330-
331-
// FIXME: This is confusing.
332-
EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function,
333-
locForFile("lld/test/t2.cpp")));
330+
EXPECT_FALSE(Diags.isSuppressedViaMapping(diag::warn_unused_function,
331+
locForFile("lld/test/t2.cpp")));
334332
}
335333

336334
TEST_F(SuppressionMappingTest, ShortLongMatch) {

llvm/include/llvm/Support/SpecialCaseList.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ class SpecialCaseList {
147147
Section(StringRef Str, unsigned FileIdx)
148148
: SectionStr(Str), FileIdx(FileIdx) {};
149149

150-
std::unique_ptr<Matcher> SectionMatcher = std::make_unique<Matcher>();
150+
Section(Section &&) = default;
151+
152+
Matcher SectionMatcher;
151153
SectionEntries Entries;
152154
std::string SectionStr;
153155
unsigned FileIdx;

llvm/lib/Support/SpecialCaseList.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ SpecialCaseList::addSection(StringRef SectionStr, unsigned FileNo,
135135
Sections.emplace_back(SectionStr, FileNo);
136136
auto &Section = Sections.back();
137137

138-
if (auto Err = Section.SectionMatcher->insert(SectionStr, LineNo, UseGlobs)) {
138+
if (auto Err = Section.SectionMatcher.insert(SectionStr, LineNo, UseGlobs)) {
139139
return createStringError(errc::invalid_argument,
140140
"malformed section at line " + Twine(LineNo) +
141141
": '" + SectionStr +
@@ -218,7 +218,7 @@ std::pair<unsigned, unsigned>
218218
SpecialCaseList::inSectionBlame(StringRef Section, StringRef Prefix,
219219
StringRef Query, StringRef Category) const {
220220
for (const auto &S : reverse(Sections)) {
221-
if (S.SectionMatcher->match(Section)) {
221+
if (S.SectionMatcher.match(Section)) {
222222
unsigned Blame = inSectionBlame(S.Entries, Prefix, Query, Category);
223223
if (Blame)
224224
return {S.FileIdx, Blame};

0 commit comments

Comments
 (0)