Skip to content

Commit 5dfd521

Browse files
committed
fixup! [Diagnostics] Add -[no-]warning-as-error flags for precise control over warning behavior
1 parent 32d599d commit 5dfd521

12 files changed

+117
-142
lines changed

include/swift/AST/DefineDiagnosticGroupsMacros.h

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,60 +20,47 @@
2020

2121
#undef DEFINE_DIAGNOSTIC_GROUPS_MACROS
2222

23-
#ifndef GROUP_DECL
24-
#error GROUP_DECL(Name, Version) macro is not defined
23+
#if !(defined(GROUP) || defined(GROUP_LINK))
24+
#error No reqired macros defined. Define at least one of the following macros: GROUP(Name, DocsFile), GROUP_LINK(Parent, Child)
2525
#endif
2626

27-
#ifndef GROUP_LINK
28-
#error GROUP_LINK(Parent, Child) macro is not defined
29-
#endif
30-
31-
// FOR_EACH macro implementation from
32-
// https://www.scs.stanford.edu/~dm/blog/va-opt.html
33-
// Extended with "context" parameter to pass an additional common argument
34-
#define PARENS ()
35-
#define EXPAND(...) EXPAND4(EXPAND4(EXPAND4(EXPAND4(__VA_ARGS__))))
36-
#define EXPAND4(...) EXPAND3(EXPAND3(EXPAND3(EXPAND3(__VA_ARGS__))))
37-
#define EXPAND3(...) EXPAND2(EXPAND2(EXPAND2(EXPAND2(__VA_ARGS__))))
38-
#define EXPAND2(...) EXPAND1(EXPAND1(EXPAND1(EXPAND1(__VA_ARGS__))))
39-
#define EXPAND1(...) __VA_ARGS__
40-
#define FOR_EACH_WITH_CTX(macro, context, ...) \
41-
__VA_OPT__(EXPAND(FOR_EACH_WITH_CTX_HELPER(macro, context, __VA_ARGS__)))
42-
#define FOR_EACH_WITH_CTX_HELPER(macro, context, a1, ...) \
43-
macro(context, a1) \
44-
__VA_OPT__(FOR_EACH_WITH_CTX_AGAIN PARENS (macro, context, __VA_ARGS__))
45-
#define FOR_EACH_WITH_CTX_AGAIN() FOR_EACH_WITH_CTX_HELPER
46-
4727
// GROUP macro:
28+
// Declares a diagnostic group.
29+
// Parameters:
4830
// Name - group name as it appears in DiagGroupID enum and DiagGroupInfo.name
49-
// Version - compiler version when this group was added
50-
// __VA_ARGS__ - subgroups of this group
51-
#define GROUP(Name, Version, ...) \
52-
GROUP_DECL(Name, Version) \
53-
FOR_EACH_WITH_CTX(GROUP_LINK, Name, __VA_ARGS__)
31+
// DocsFile - file with a human readable description for the group located in
32+
// userdocs/diagnostic_groups
33+
#ifndef GROUP
34+
#define GROUP(Name, DocsFile)
35+
#endif
36+
37+
// GROUP_LINK macro:
38+
// Establishes an edge in the diagnostic group graph between
39+
// a supergroup(Parent) and its subgroup(Child).
40+
// Parameters:
41+
// Parent - parent group name
42+
// Child - child group name
43+
#ifndef GROUP_LINK
44+
#define GROUP_LINK(Parent, Child)
45+
#endif
5446

5547
// Undefine macros
5648
#elif defined(UNDEFINE_DIAGNOSTIC_GROUPS_MACROS) && \
5749
!defined(DEFINE_DIAGNOSTIC_GROUPS_MACROS)
5850

5951
#undef UNDEFINE_DIAGNOSTIC_GROUPS_MACROS
6052

61-
#ifndef GROUP
53+
#ifdef GROUP
54+
#undef GROUP
55+
#else
6256
#error Trying to undefine the diagnostic groups macros, but GROUP macro wasn't defined
6357
#endif
6458

65-
#undef PARENS
66-
#undef EXPAND
67-
#undef EXPAND4
68-
#undef EXPAND3
69-
#undef EXPAND2
70-
#undef EXPAND1
71-
#undef FOR_EACH
72-
#undef FOR_EACH_HELPER
73-
#undef FOR_EACH_AGAIN
74-
#undef GROUP
75-
#undef GROUP_DECL
59+
#ifdef GROUP_LINK
7660
#undef GROUP_LINK
61+
#else
62+
#error Trying to undefine the diagnostic groups macros, but GROUP_LINK macro wasn't defined
63+
#endif
7764

7865
#else
7966
#error Invalid DefineDiagnosticGroupsMacros.h inclusion

include/swift/AST/DiagnosticEngine.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,9 +1109,7 @@ namespace swift {
11091109

11101110
/// Apply rules specifing what warnings should or shouldn't be treated as
11111111
/// errors. For group rules the string is either a group name defined by
1112-
/// DiagnosticGroups.def or a string with format "_id:<diag_id>" where
1113-
/// <diag_id> is one of the diagnostic IDs listed in
1114-
/// include/swift/AST/Diagnostics*.def
1112+
/// DiagnosticGroups.def
11151113
/// Rules are applied in order they appear in the vector.
11161114
/// In case the vector contains rules affecting the same diagnostic ID
11171115
/// the last rule wins.

include/swift/AST/DiagnosticGroups.def

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,24 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
13-
// This file defines diagnostic groups.
13+
// This file defines diagnostic groups and links between them.
1414
//
1515
//===----------------------------------------------------------------------===//
1616

1717
#define DEFINE_DIAGNOSTIC_GROUPS_MACROS
1818
#include "swift/AST/DefineDiagnosticGroupsMacros.h"
1919

20-
#pragma clang diagnostic push
21-
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
20+
// GROUP(Name, DocsFile)
21+
// GROUP_LINK(Parent, Child)
2222

23-
GROUP(no_group, 6.0)
23+
GROUP(no_group, "")
2424

25-
GROUP(deprecated, 6.0, availability_deprecated)
26-
GROUP(availability_deprecated, 6.0)
25+
GROUP(deprecated, "deprecated.md")
26+
GROUP_LINK(deprecated, availability_deprecated)
2727

28-
GROUP(unknown_warning_group, 6.0)
29-
GROUP(error_in_future_swift_version, 6.0)
28+
GROUP(availability_deprecated, "availability_deprecated.md")
3029

31-
#pragma clang diagnostic pop
30+
GROUP(unknown_warning_group, "unknown_warning_group.md")
3231

3332
#define UNDEFINE_DIAGNOSTIC_GROUPS_MACROS
3433
#include "swift/AST/DefineDiagnosticGroupsMacros.h"

include/swift/AST/DiagnosticGroups.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,13 @@
2727
namespace swift {
2828

2929
enum class DiagGroupID : uint16_t {
30-
#define GROUP_DECL(Name, Version) Name,
31-
#define GROUP_LINK(Parent, Child)
30+
#define GROUP(Name, Version) Name,
3231
#include "swift/AST/DiagnosticGroups.def"
3332
};
3433

3534
constexpr const auto DiagGroupsCount = [] {
3635
size_t count = 0;
37-
#define GROUP_DECL(Name, Version) count++;
38-
#define GROUP_LINK(Parent, Child)
36+
#define GROUP(Name, Version) count++;
3937
#include "DiagnosticGroups.def"
4038
return count;
4139
}();
@@ -48,8 +46,8 @@ struct DiagGroupInfo {
4846
llvm::ArrayRef<DiagGroupID> subgroups;
4947
llvm::ArrayRef<DiagID> diagnostics;
5048

51-
void
52-
traverseDepthFirst(std::function<void(const DiagGroupInfo &)> func) const;
49+
void traverseDepthFirst(
50+
llvm::function_ref<void(const DiagGroupInfo &)> func) const;
5351
};
5452

5553
extern const std::array<DiagGroupInfo, DiagGroupsCount> diagnosticGroupsInfo;

include/swift/AST/DiagnosticsCommon.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ ERROR(error_no_group_info,none,
4747
NOTE(brace_stmt_suggest_do,none,
4848
"did you mean to use a 'do' statement?", ())
4949

50-
GROUPED_WARNING(error_in_future_swift_version,error_in_future_swift_version,none,
50+
WARNING(error_in_future_swift_version,none,
5151
"%0; this is an error in the Swift %1 language mode",
5252
(DiagnosticInfo *, unsigned))
5353

lib/AST/DiagnosticEngine.cpp

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,6 @@ static constexpr const char *const diagnosticIDStrings[] = {
145145
"<not a diagnostic>",
146146
};
147147

148-
std::unordered_map<std::string_view, DiagID> diagnosticIDStringToIDMap{
149-
#define DIAG(KIND, ID, Group, Options, Text, Signature) {#ID, DiagID::ID},
150-
#include "swift/AST/DiagnosticsAll.def"
151-
};
152-
153148
static constexpr const char *const fixItStrings[] = {
154149
#define DIAG(KIND, ID, Group, Options, Text, Signature)
155150
#define FIXIT(ID, Text, Signature) Text,
@@ -526,7 +521,6 @@ bool DiagnosticEngine::finishProcessing() {
526521

527522
void DiagnosticEngine::setWarningsAsErrorsRules(
528523
const std::vector<WarningAsErrorRule> &rules) {
529-
const std::string_view idPrefix = "_id:";
530524
std::vector<std::string> unknownGroups;
531525
for (const auto &rule : rules) {
532526
bool isEnabled = [&] {
@@ -540,29 +534,17 @@ void DiagnosticEngine::setWarningsAsErrorsRules(
540534
auto target = rule.getTarget();
541535
if (auto group = std::get_if<WarningAsErrorRule::TargetGroup>(&target)) {
542536
auto name = std::string_view(group->name);
543-
if (name.rfind(idPrefix, 0) == 0) {
544-
// The rule is defined as a prefixed diagID
545-
auto diagIDName = name.substr(idPrefix.size());
546-
auto it = diagnosticIDStringToIDMap.find(diagIDName);
547-
if (it != diagnosticIDStringToIDMap.end()) {
548-
auto diagID = it->second;
549-
state.setWarningAsErrorForDiagID(diagID, isEnabled);
550-
} else {
551-
unknownGroups.push_back(std::string(name));
552-
}
537+
// Validate the group name and set the new behavior for each diagnostic
538+
// associated with the group and all its subgroups.
539+
if (auto groupID = getDiagGroupIDByName(name);
540+
groupID && *groupID != DiagGroupID::no_group) {
541+
getDiagGroupInfoByID(*groupID).traverseDepthFirst([&](auto group) {
542+
for (DiagID diagID : group.diagnostics) {
543+
state.setWarningAsErrorForDiagID(diagID, isEnabled);
544+
}
545+
});
553546
} else {
554-
// The rule is defined as a group name. Apply it to each diagnostic
555-
// associated with the group and all its subgroups.
556-
if (auto groupID = getDiagGroupIDByName(name);
557-
groupID && *groupID != DiagGroupID::no_group) {
558-
getDiagGroupInfoByID(*groupID).traverseDepthFirst([&](auto group) {
559-
for (DiagID diagID : group.diagnostics) {
560-
state.setWarningAsErrorForDiagID(diagID, isEnabled);
561-
}
562-
});
563-
} else {
564-
unknownGroups.push_back(std::string(name));
565-
}
547+
unknownGroups.push_back(std::string(name));
566548
}
567549
} else if (std::holds_alternative<WarningAsErrorRule::TargetAll>(target)) {
568550
state.setAllWarningsAsErrors(isEnabled);

lib/AST/DiagnosticGroups.cpp

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- DiagnosticGroups.h - Diagnostic Groups -----------------*- C++ -*-===//
1+
//===--- DiagnosticGroups.cpp - Diagnostic Groups ---------------*- C++ -*-===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -50,7 +50,6 @@ constexpr const auto diagnosticGroupConnections = [] {
5050
std::array<size_t, DiagGroupsCount> diagnosticsCount{};
5151

5252
// Count edges for each diagnostic group
53-
#define GROUP_DECL(Name, Version)
5453
#define GROUP_LINK(Parent, Child) \
5554
subgroupsCount[(size_t)DiagGroupID::Parent]++; \
5655
supergroupsCount[(size_t)DiagGroupID::Child]++;
@@ -68,54 +67,45 @@ constexpr const auto diagnosticGroupConnections = [] {
6867
constexpr auto diagnosticsCount = std::get<2>(sizes);
6968

7069
// Declare all edges
71-
#pragma clang diagnostic push
72-
#pragma clang diagnostic ignored "-Wunused-variable"
73-
74-
#define GROUP_DECL(Name, Version) \
70+
#define GROUP(Name, Version) \
7571
std::array<DiagGroupID, supergroupsCount[(size_t)DiagGroupID::Name]> \
7672
Name##_supergroups{}; \
7773
std::array<DiagGroupID, subgroupsCount[(size_t)DiagGroupID::Name]> \
7874
Name##_subgroups{}; \
7975
std::array<DiagID, diagnosticsCount[(size_t)DiagGroupID::Name]> \
8076
Name##_diagnostics{}; \
81-
size_t Name##_supergroupsIndex = 0; \
82-
size_t Name##_subgroupsIndex = 0; \
83-
size_t Name##_diagnosticsIndex = 0;
84-
#define GROUP_LINK(Parent, Child)
77+
[[maybe_unused]] size_t Name##_supergroupsIndex = 0; \
78+
[[maybe_unused]] size_t Name##_subgroupsIndex = 0; \
79+
[[maybe_unused]] size_t Name##_diagnosticsIndex = 0;
8580
#include "swift/AST/DiagnosticGroups.def"
8681

8782
// Bind all groups to each other
88-
#define GROUP_DECL(Name, Version)
8983
#define GROUP_LINK(Parent, Child) \
9084
Parent##_subgroups[Parent##_subgroupsIndex++] = DiagGroupID::Child; \
9185
Child##_supergroups[Child##_supergroupsIndex++] = DiagGroupID::Parent;
9286
#include "swift/AST/DiagnosticGroups.def"
9387

94-
#pragma clang diagnostic pop
95-
9688
// Bind all diagnostics to their groups
9789
#define DIAG(KIND, ID, Group, Options, Text, Signature) \
9890
Group##_diagnostics[Group##_diagnosticsIndex++] = DiagID::ID;
9991
#include "swift/AST/DiagnosticsAll.def"
10092

10193
// Produce the resulting structure with all the edges
102-
#define GROUP_DECL(Name, Version) \
94+
#define GROUP(Name, Version) \
10395
GroupConnections(Name##_supergroups, Name##_subgroups, Name##_diagnostics),
104-
#define GROUP_LINK(Parent, Child)
10596
return std::tuple{
10697
#include "swift/AST/DiagnosticGroups.def"
10798
};
10899
}();
109100

110101
std::unordered_map<std::string_view, DiagGroupID> nameToIDMap{
111-
#define GROUP_DECL(Name, Version) {#Name, DiagGroupID::Name},
112-
#define GROUP_LINK(Parent, Child)
102+
#define GROUP(Name, Version) {#Name, DiagGroupID::Name},
113103
#include "swift/AST/DiagnosticGroups.def"
114104
};
115105

116106
void traverseDepthFirst(DiagGroupID id,
117107
std::unordered_set<DiagGroupID> &visited,
118-
std::function<void(const DiagGroupInfo &)> func) {
108+
llvm::function_ref<void(const DiagGroupInfo &)> func) {
119109
if (visited.insert(id).second) {
120110
const auto &info = getDiagGroupInfoByID(id);
121111
func(info);
@@ -128,7 +118,7 @@ void traverseDepthFirst(DiagGroupID id,
128118
} // end anonymous namespace
129119

130120
constexpr const std::array<DiagGroupInfo, DiagGroupsCount> diagnosticGroupsInfo{
131-
#define GROUP_DECL(Name, Version) \
121+
#define GROUP(Name, Version) \
132122
DiagGroupInfo{ \
133123
DiagGroupID::Name, \
134124
#Name, \
@@ -142,7 +132,6 @@ constexpr const std::array<DiagGroupInfo, DiagGroupsCount> diagnosticGroupsInfo{
142132
llvm::ArrayRef<DiagID>( \
143133
std::get<(size_t)DiagGroupID::Name>(diagnosticGroupConnections) \
144134
.diagnostics)},
145-
#define GROUP_LINK(Parent, Child)
146135
#include "swift/AST/DiagnosticGroups.def"
147136
};
148137

@@ -158,7 +147,7 @@ std::optional<DiagGroupID> getDiagGroupIDByName(std::string_view name) {
158147
}
159148

160149
void DiagGroupInfo::traverseDepthFirst(
161-
std::function<void(const DiagGroupInfo &)> func) const {
150+
llvm::function_ref<void(const DiagGroupInfo &)> func) const {
162151
std::unordered_set<DiagGroupID> visited;
163152
::swift::traverseDepthFirst(id, visited, func);
164153
}
Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
// RUN: not %target-swift-frontend -typecheck -diagnostic-style llvm -warnings-as-errors %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-ALL
22
// RUN: not %target-swift-frontend -typecheck -diagnostic-style llvm -warning-as-error availability_deprecated %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-GROUP
33
// RUN: not %target-swift-frontend -typecheck -diagnostic-style llvm -warning-as-error deprecated %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-SUPERGROUP
4-
// RUN: not %target-swift-frontend -typecheck -diagnostic-style llvm -warning-as-error _id:availability_deprecated -warning-as-error _id:availability_deprecated_rename %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-DIAGID
54
// RUN: %target-swift-frontend -typecheck -diagnostic-style llvm -warnings-as-errors -no-warnings-as-errors %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-ALL-NWAE-ALL
65
// RUN: %target-swift-frontend -typecheck -diagnostic-style llvm -warnings-as-errors -no-warning-as-error availability_deprecated %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-ALL-NWAE-GROUP
76
// RUN: %target-swift-frontend -typecheck -diagnostic-style llvm -warnings-as-errors -no-warning-as-error deprecated %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-ALL-NWAE-SUPERGROUP
8-
// RUN: %target-swift-frontend -typecheck -diagnostic-style llvm -warnings-as-errors -no-warning-as-error _id:availability_deprecated -no-warning-as-error _id:availability_deprecated_rename %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-ALL-NWAE-DIAGID
97
// RUN: %target-swift-frontend -typecheck -diagnostic-style llvm -warning-as-error deprecated -no-warning-as-error availability_deprecated %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-SUPERGROUP-NWAE-GROUP
10-
// RUN: not %target-swift-frontend -typecheck -diagnostic-style llvm -warning-as-error availability_deprecated -no-warning-as-error _id:availability_deprecated %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WAE-GROUP-NWAE-DIAGID
118

129

1310
@available(*, deprecated)
@@ -25,20 +22,14 @@ func bar() {
2522
// CHECK-WAE-GROUP-NOT: warning: 'foo()' is deprecated
2623
// CHECK-WAE-SUPERGROUP: error: 'foo()' is deprecated
2724
// CHECK-WAE-SUPERGROUP-NOT: warning: 'foo()' is deprecated
28-
// CHECK-WAE-DIAGID: error: 'foo()' is deprecated
29-
// CHECK-WAE-DIAGID-NOT: warning: 'foo()' is deprecated
3025
// CHECK-WAE-ALL-NWAE-ALL: warning: 'foo()' is deprecated
3126
// CHECK-WAE-ALL-NWAE-ALL-NOT: error: 'foo()' is deprecated
3227
// CHECK-WAE-ALL-NWAE-GROUP: warning: 'foo()' is deprecated
3328
// CHECK-WAE-ALL-NWAE-GROUP-NOT: error: 'foo()' is deprecated
3429
// CHECK-WAE-ALL-NWAE-SUPERGROUP: warning: 'foo()' is deprecated
3530
// CHECK-WAE-ALL-NWAE-SUPERGROUP-NOT: error: 'foo()' is deprecated
36-
// CHECK-WAE-ALL-NWAE-DIAGID: warning: 'foo()' is deprecated
37-
// CHECK-WAE-ALL-NWAE-DIAGID-NOT: error: 'foo()' is deprecated
3831
// CHECK-WAE-SUPERGROUP-NWAE-GROUP: warning: 'foo()' is deprecated
3932
// CHECK-WAE-SUPERGROUP-NWAE-GROUP-NOT: error: 'foo()' is deprecated
40-
// CHECK-WAE-GROUP-NWAE-DIAGID: warning: 'foo()' is deprecated
41-
// CHECK-WAE-GROUP-NWAE-DIAGID-NOT: error: 'foo()' is deprecated
4233
foo()
4334

4435

@@ -48,18 +39,12 @@ foo()
4839
// CHECK-WAE-GROUP-NOT: warning: 'bar()' is deprecated: renamed to 'bar2'
4940
// CHECK-WAE-SUPERGROUP: error: 'bar()' is deprecated: renamed to 'bar2'
5041
// CHECK-WAE-SUPERGROUP-NOT: warning: 'bar()' is deprecated: renamed to 'bar2'
51-
// CHECK-WAE-DIAGID: error: 'bar()' is deprecated: renamed to 'bar2'
52-
// CHECK-WAE-DIAGID-NOT: warning: 'bar()' is deprecated: renamed to 'bar2'
5342
// CHECK-WAE-ALL-NWAE-ALL: warning: 'bar()' is deprecated: renamed to 'bar2'
5443
// CHECK-WAE-ALL-NWAE-ALL-NOT: error: 'bar()' is deprecated: renamed to 'bar2'
5544
// CHECK-WAE-ALL-NWAE-GROUP: warning: 'bar()' is deprecated: renamed to 'bar2'
5645
// CHECK-WAE-ALL-NWAE-GROUP-NOT: error: 'bar()' is deprecated: renamed to 'bar2'
5746
// CHECK-WAE-ALL-NWAE-SUPERGROUP: warning: 'bar()' is deprecated: renamed to 'bar2'
5847
// CHECK-WAE-ALL-NWAE-SUPERGROUP-NOT: error: 'bar()' is deprecated: renamed to 'bar2'
59-
// CHECK-WAE-ALL-NWAE-DIAGID: warning: 'bar()' is deprecated: renamed to 'bar2'
60-
// CHECK-WAE-ALL-NWAE-DIAGID-NOT: error: 'bar()' is deprecated: renamed to 'bar2'
6148
// CHECK-WAE-SUPERGROUP-NWAE-GROUP: warning: 'bar()' is deprecated: renamed to 'bar2'
6249
// CHECK-WAE-SUPERGROUP-NWAE-GROUP-NOT: error: 'bar()' is deprecated: renamed to 'bar2'
63-
// CHECK-WAE-GROUP-NWAE-DIAGID: error: 'bar()' is deprecated: renamed to 'bar2'
64-
// CHECK-WAE-GROUP-NWAE-DIAGID-NOT: warning: 'bar()' is deprecated: renamed to 'bar2'
6550
bar()

0 commit comments

Comments
 (0)