Skip to content

Commit 83b462a

Browse files
authored
[flang][CLI] Have the CLI hint the flag to disable a warning (llvm#144767)
Adds a hint to the warning message to disable a warning and updates the tests to expect this. Also fixes a bug in the storage of canonical spelling of error flags so that they are not used after free.
1 parent efc561c commit 83b462a

File tree

162 files changed

+664
-625
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

162 files changed

+664
-625
lines changed

flang/include/flang/Parser/message.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,8 @@ class Message : public common::ReferenceCounted<Message> {
292292
std::optional<ProvenanceRange> GetProvenanceRange(
293293
const AllCookedSources &) const;
294294
void Emit(llvm::raw_ostream &, const AllCookedSources &,
295-
bool echoSourceLine = true) const;
295+
bool echoSourceLine = true,
296+
const common::LanguageFeatureControl *hintFlags = nullptr) const;
296297

297298
// If this Message or any of its attachments locates itself via a CharBlock,
298299
// replace its location with the corresponding ProvenanceRange.
@@ -352,7 +353,8 @@ class Messages {
352353
void Copy(const Messages &);
353354
void ResolveProvenances(const AllCookedSources &);
354355
void Emit(llvm::raw_ostream &, const AllCookedSources &,
355-
bool echoSourceLines = true) const;
356+
bool echoSourceLines = true,
357+
const common::LanguageFeatureControl *hintFlags = nullptr) const;
356358
void AttachTo(Message &, std::optional<Severity> = std::nullopt);
357359
bool AnyFatalError() const;
358360

flang/include/flang/Support/Fortran-features.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,13 @@ class LanguageFeatureControl {
156156
private:
157157
// Map from Cli syntax of language features and usage warnings to their enum
158158
// values.
159-
std::unordered_map<std::string, std::variant<LanguageFeature, UsageWarning>>
160-
cliOptions_;
159+
std::unordered_map<std::string, LanguageFeatureOrWarning> cliOptions_;
161160
// These two arrays map the enum values to their cannonical Cli spellings.
162161
// Since each of the CanonicalSpelling is a string in the domain of the map
163162
// above we just use a view of the string instead of another copy.
164-
std::array<std::string_view, LanguageFeature_enumSize>
163+
std::array<std::string, LanguageFeature_enumSize>
165164
languageFeatureCliCanonicalSpelling_;
166-
std::array<std::string_view, UsageWarning_enumSize>
165+
std::array<std::string, UsageWarning_enumSize>
167166
usageWarningCliCanonicalSpelling_;
168167
LanguageFeatures disable_;
169168
LanguageFeatures warnLanguage_;

flang/lib/Frontend/FrontendAction.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,10 @@ bool FrontendAction::runParse(bool emitMessages) {
171171
if (emitMessages) {
172172
// Report any non-fatal diagnostics from getParsing now rather than
173173
// combining them with messages from semantics.
174-
ci.getParsing().messages().Emit(llvm::errs(), ci.getAllCookedSources());
174+
const common::LanguageFeatureControl &features{
175+
ci.getInvocation().getFortranOpts().features};
176+
ci.getParsing().messages().Emit(llvm::errs(), ci.getAllCookedSources(),
177+
/*echoSourceLine=*/true, &features);
175178
}
176179
return true;
177180
}
@@ -223,14 +226,17 @@ bool FrontendAction::generateRtTypeTables() {
223226

224227
template <unsigned N>
225228
bool FrontendAction::reportFatalErrors(const char (&message)[N]) {
229+
const common::LanguageFeatureControl &features{
230+
instance->getInvocation().getFortranOpts().features};
226231
if (!instance->getParsing().messages().empty() &&
227232
(instance->getInvocation().getWarnAsErr() ||
228233
instance->getParsing().messages().AnyFatalError())) {
229234
const unsigned diagID = instance->getDiagnostics().getCustomDiagID(
230235
clang::DiagnosticsEngine::Error, message);
231236
instance->getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();
232237
instance->getParsing().messages().Emit(llvm::errs(),
233-
instance->getAllCookedSources());
238+
instance->getAllCookedSources(),
239+
/*echoSourceLines=*/true, &features);
234240
return true;
235241
}
236242
if (instance->getParsing().parseTree().has_value() &&
@@ -240,7 +246,8 @@ bool FrontendAction::reportFatalErrors(const char (&message)[N]) {
240246
clang::DiagnosticsEngine::Error, message);
241247
instance->getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();
242248
instance->getParsing().messages().Emit(llvm::errs(),
243-
instance->getAllCookedSources());
249+
instance->getAllCookedSources(),
250+
/*echoSourceLine=*/true, &features);
244251
instance->getParsing().EmitMessage(
245252
llvm::errs(), instance->getParsing().finalRestingPlace(),
246253
"parser FAIL (final position)", "error: ", llvm::raw_ostream::RED);

flang/lib/Parser/message.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,36 @@ static llvm::raw_ostream::Colors PrefixColor(Severity severity) {
273273
return llvm::raw_ostream::SAVEDCOLOR;
274274
}
275275

276+
static std::string HintLanguageControlFlag(
277+
const common::LanguageFeatureControl *hintFlagPtr,
278+
std::optional<common::LanguageFeature> feature,
279+
std::optional<common::UsageWarning> warning) {
280+
if (hintFlagPtr) {
281+
std::string flag;
282+
if (warning) {
283+
flag = hintFlagPtr->getDefaultCliSpelling(*warning);
284+
} else if (feature) {
285+
flag = hintFlagPtr->getDefaultCliSpelling(*feature);
286+
}
287+
if (!flag.empty()) {
288+
return " [-W" + flag + "]";
289+
}
290+
}
291+
return "";
292+
}
293+
276294
static constexpr int MAX_CONTEXTS_EMITTED{2};
277295
static constexpr bool OMIT_SHARED_CONTEXTS{true};
278296

279297
void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
280-
bool echoSourceLine) const {
298+
bool echoSourceLine,
299+
const common::LanguageFeatureControl *hintFlagPtr) const {
281300
std::optional<ProvenanceRange> provenanceRange{GetProvenanceRange(allCooked)};
282301
const AllSources &sources{allCooked.allSources()};
283-
sources.EmitMessage(o, provenanceRange, ToString(), Prefix(severity()),
302+
const std::string text{ToString()};
303+
const std::string hint{
304+
HintLanguageControlFlag(hintFlagPtr, languageFeature_, usageWarning_)};
305+
sources.EmitMessage(o, provenanceRange, text + hint, Prefix(severity()),
284306
PrefixColor(severity()), echoSourceLine);
285307
// Refers to whether the attachment in the loop below is a context, but can't
286308
// be declared inside the loop because the previous iteration's
@@ -430,7 +452,8 @@ void Messages::ResolveProvenances(const AllCookedSources &allCooked) {
430452
}
431453

432454
void Messages::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
433-
bool echoSourceLines) const {
455+
bool echoSourceLines,
456+
const common::LanguageFeatureControl *hintFlagPtr) const {
434457
std::vector<const Message *> sorted;
435458
for (const auto &msg : messages_) {
436459
sorted.push_back(&msg);
@@ -443,7 +466,7 @@ void Messages::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
443466
// Don't emit two identical messages for the same location
444467
continue;
445468
}
446-
msg->Emit(o, allCooked, echoSourceLines);
469+
msg->Emit(o, allCooked, echoSourceLines, hintFlagPtr);
447470
lastMsg = msg;
448471
}
449472
}

flang/lib/Semantics/semantics.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,10 @@ bool Semantics::Perform() {
655655
void Semantics::EmitMessages(llvm::raw_ostream &os) {
656656
// Resolve the CharBlock locations of the Messages to ProvenanceRanges
657657
// so messages from parsing and semantics are intermixed in source order.
658+
const common::LanguageFeatureControl &features{context_.languageFeatures()};
658659
context_.messages().ResolveProvenances(context_.allCookedSources());
659-
context_.messages().Emit(os, context_.allCookedSources());
660+
context_.messages().Emit(
661+
os, context_.allCookedSources(), /*echoSourceLine=*/true, &features);
660662
}
661663

662664
void SemanticsContext::DumpSymbols(llvm::raw_ostream &os) {

flang/lib/Support/Fortran-features.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ LanguageFeatureControl::LanguageFeatureControl() {
5959
std::string cliOption{details::CamelCaseToLowerCaseHyphenated(name)};
6060
cliOptions_.insert({cliOption, {feature}});
6161
languageFeatureCliCanonicalSpelling_[EnumToInt(feature)] =
62-
std::string_view{cliOption};
62+
std::move(cliOption);
6363
});
6464

6565
ForEachUsageWarning([&](auto warning) {
6666
std::string_view name{Fortran::common::EnumToString(warning)};
6767
std::string cliOption{details::CamelCaseToLowerCaseHyphenated(name)};
6868
cliOptions_.insert({cliOption, {warning}});
6969
usageWarningCliCanonicalSpelling_[EnumToInt(warning)] =
70-
std::string_view{cliOption};
70+
std::move(cliOption);
7171
});
7272

7373
// These features must be explicitly enabled by command line options.
@@ -174,18 +174,16 @@ bool LanguageFeatureControl::EnableWarning(std::string_view input) {
174174

175175
void LanguageFeatureControl::ReplaceCliCanonicalSpelling(
176176
LanguageFeature f, std::string input) {
177-
std::string_view &old{languageFeatureCliCanonicalSpelling_[EnumToInt(f)]};
178-
cliOptions_.erase(std::string{old});
179-
languageFeatureCliCanonicalSpelling_[EnumToInt(f)] = input;
177+
cliOptions_.erase(languageFeatureCliCanonicalSpelling_[EnumToInt(f)]);
180178
cliOptions_.insert({input, {f}});
179+
languageFeatureCliCanonicalSpelling_[EnumToInt(f)] = std::move(input);
181180
}
182181

183182
void LanguageFeatureControl::ReplaceCliCanonicalSpelling(
184183
UsageWarning w, std::string input) {
185-
std::string_view &old{usageWarningCliCanonicalSpelling_[EnumToInt(w)]};
186-
cliOptions_.erase(std::string{old});
187-
usageWarningCliCanonicalSpelling_[EnumToInt(w)] = input;
184+
cliOptions_.erase(usageWarningCliCanonicalSpelling_[EnumToInt(w)]);
188185
cliOptions_.insert({input, {w}});
186+
usageWarningCliCanonicalSpelling_[EnumToInt(w)] = std::move(input);
189187
}
190188

191189
std::vector<const char *> LanguageFeatureControl::GetNames(

flang/test/Evaluate/fold-dim.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module m
1111
logical, parameter :: test_a3 = dim(2., 1.) == 1.
1212
logical, parameter :: test_a4 = dim(2., -1.) == 3.
1313
logical, parameter :: test_a5 = dim(-1., 2.) == 0.
14-
!WARN: warning: invalid argument on division
14+
!WARN: warning: invalid argument on division [-Wfolding-exception]
1515
real, parameter :: nan = 0./0.
1616
logical, parameter :: test_a6 = dim(nan, 1.) /= dim(nan, 1.)
1717
end module

flang/test/Evaluate/fold-nearest.f90

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ module m1
1919
real, parameter :: negZero = sign(0., -1.)
2020
logical, parameter :: test_12 = nearest(negZero, 1.) == minSubnormal
2121
logical, parameter :: test_13 = nearest(negZero, -1.) == -minSubnormal
22-
!WARN: warning: NEAREST: S argument is zero
22+
!WARN: warning: NEAREST: S argument is zero [-Wfolding-value-checks]
2323
logical, parameter :: test_14 = nearest(0., negZero) == -minSubnormal
24-
!WARN: warning: NEAREST: S argument is zero
24+
!WARN: warning: NEAREST: S argument is zero [-Wfolding-value-checks]
2525
logical, parameter :: test_15 = nearest(negZero, 0.) == minSubnormal
2626
logical, parameter :: test_16 = nearest(tiny(1.),-1.) == 1.1754942E-38
2727
logical, parameter :: test_17 = nearest(tiny(1.),1.) == 1.1754945E-38
2828
contains
2929
subroutine subr(a)
3030
real, intent(in) :: a
31-
!WARN: warning: NEAREST: S argument is zero
31+
!WARN: warning: NEAREST: S argument is zero [-Wfolding-value-checks]
3232
print *, nearest(a, 0.)
3333
end
3434
end module
@@ -42,7 +42,7 @@ module m2
4242
logical, parameter :: test_2 = ieee_next_after(minSubnormal, -1.) == 0
4343
logical, parameter :: test_3 = ieee_next_after(1., 2.) == 1.0000001
4444
logical, parameter :: test_4 = ieee_next_after(1.0000001, -1.) == 1
45-
!WARN: warning: division by zero
45+
!WARN: warning: division by zero [-Wfolding-exception]
4646
real, parameter :: inf = 1. / 0.
4747
logical, parameter :: test_5 = ieee_next_after(inf, inf) == inf
4848
logical, parameter :: test_6 = ieee_next_after(inf, -inf) == h
@@ -54,12 +54,12 @@ module m2
5454
logical, parameter :: test_11 = ieee_next_after(1.9999999999999999999_10, 3.) == 2._10
5555
#endif
5656
logical, parameter :: test_12 = ieee_next_after(1., 1.) == 1.
57-
!WARN: warning: invalid argument on division
57+
!WARN: warning: invalid argument on division [-Wfolding-exception]
5858
real, parameter :: nan = 0. / 0.
59-
!WARN: warning: IEEE_NEXT_AFTER intrinsic folding: arguments are unordered
59+
!WARN: warning: IEEE_NEXT_AFTER intrinsic folding: arguments are unordered [-Wfolding-value-checks]
6060
real, parameter :: x13 = ieee_next_after(nan, nan)
6161
logical, parameter :: test_13 = .not. (x13 == x13)
62-
!WARN: warning: IEEE_NEXT_AFTER intrinsic folding: arguments are unordered
62+
!WARN: warning: IEEE_NEXT_AFTER intrinsic folding: arguments are unordered [-Wfolding-value-checks]
6363
real, parameter :: x14 = ieee_next_after(nan, 0.)
6464
logical, parameter :: test_14 = .not. (x14 == x14)
6565
end module
@@ -72,7 +72,7 @@ module m3
7272
logical, parameter :: test_2 = ieee_next_down(0.d0) == -minSubnormal
7373
logical, parameter :: test_3 = ieee_next_up(1.d0) == 1.0000000000000002d0
7474
logical, parameter :: test_4 = ieee_next_down(1.0000000000000002d0) == 1.d0
75-
!WARN: warning: division by zero
75+
!WARN: warning: division by zero [-Wfolding-exception]
7676
real(kind(0.d0)), parameter :: inf = 1.d0 / 0.d0
7777
logical, parameter :: test_5 = ieee_next_up(huge(0.d0)) == inf
7878
logical, parameter :: test_6 = ieee_next_down(-huge(0.d0)) == -inf
@@ -82,12 +82,12 @@ module m3
8282
logical, parameter :: test_10 = ieee_next_down(-inf) == -inf
8383
logical, parameter :: test_11 = ieee_next_up(1.9999999999999997d0) == 2.d0
8484
logical, parameter :: test_12 = ieee_next_down(2.d0) == 1.9999999999999997d0
85-
!WARN: warning: invalid argument on division
85+
!WARN: warning: invalid argument on division [-Wfolding-exception]
8686
real(kind(0.d0)), parameter :: nan = 0.d0 / 0.d0
87-
!WARN: warning: IEEE_NEXT_UP intrinsic folding: argument is NaN
87+
!WARN: warning: IEEE_NEXT_UP intrinsic folding: argument is NaN [-Wfolding-exception]
8888
real(kind(0.d0)), parameter :: x13 = ieee_next_up(nan)
8989
logical, parameter :: test_13 = .not. (x13 == x13)
90-
!WARN: warning: IEEE_NEXT_DOWN intrinsic folding: argument is NaN
90+
!WARN: warning: IEEE_NEXT_DOWN intrinsic folding: argument is NaN [-Wfolding-exception]
9191
real(kind(0.d0)), parameter :: x14 = ieee_next_down(nan)
9292
logical, parameter :: test_14 = .not. (x14 == x14)
9393
end module

0 commit comments

Comments
 (0)