Skip to content

Commit e4113e9

Browse files
committed
initial commit
1 parent 0ae0b16 commit e4113e9

23 files changed

+450
-573
lines changed

flang/include/flang/Evaluate/common.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,16 @@ class FoldingContext {
255255
const common::LanguageFeatureControl &languageFeatures() const {
256256
return languageFeatures_;
257257
}
258+
template <typename... A>
259+
parser::Message *Warn(common::LanguageFeature feature, A &&...args) {
260+
return messages_.Warn(/*isInModuleFile=*/false, languageFeatures_, feature,
261+
std::forward<A>(args)...);
262+
}
263+
template <typename... A>
264+
parser::Message *Warn(common::UsageWarning warning, A &&...args) {
265+
return messages_.Warn(/*isInModuleFile=*/false, languageFeatures_, warning,
266+
std::forward<A>(args)...);
267+
}
258268
std::optional<parser::CharBlock> moduleFileName() const {
259269
return moduleFileName_;
260270
}

flang/include/flang/Evaluate/tools.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,18 @@ parser::Message *SayWithDeclaration(
11161116
MESSAGES &messages, const Symbol &symbol, A &&...x) {
11171117
return AttachDeclaration(messages.Say(std::forward<A>(x)...), symbol);
11181118
}
1119+
template <typename... A>
1120+
parser::Message *WarnWithDeclaration(FoldingContext context,
1121+
const Symbol &symbol, common::LanguageFeature feature, A &&...x) {
1122+
return AttachDeclaration(
1123+
context.Warn(feature, std::forward<A>(x)...), symbol);
1124+
}
1125+
template <typename... A>
1126+
parser::Message *WarnWithDeclaration(FoldingContext &context,
1127+
const Symbol &symbol, common::UsageWarning warning, A &&...x) {
1128+
return AttachDeclaration(
1129+
context.Warn(warning, std::forward<A>(x)...), symbol);
1130+
}
11191131

11201132
// Check for references to impure procedures; returns the name
11211133
// of one to complain about, if any exist.

flang/include/flang/Parser/message.h

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "flang/Common/reference-counted.h"
2020
#include "flang/Common/restorer.h"
2121
#include "flang/Support/Fortran-features.h"
22+
#include "llvm/Support/ErrorHandling.h"
2223
#include <cstddef>
2324
#include <cstring>
2425
#include <forward_list>
@@ -334,14 +335,36 @@ class Messages {
334335
return messages_.emplace_back(std::forward<A>(args)...);
335336
}
336337

338+
// AddWarning bypasses the language feature control, it is only exposed for
339+
// legacy code that cannot be easily refactored to use Warn().
337340
template <typename... A>
338-
Message &Say(common::LanguageFeature feature, A &&...args) {
339-
return Say(std::forward<A>(args)...).set_languageFeature(feature);
341+
Message &AddWarning(common::UsageWarning warning, A &&...args) {
342+
return messages_.emplace_back(warning, std::forward<A>(args)...);
340343
}
341344

342345
template <typename... A>
343-
Message &Say(common::UsageWarning warning, A &&...args) {
344-
return Say(std::forward<A>(args)...).set_usageWarning(warning);
346+
Message &AddWarning(common::LanguageFeature feature, A &&...args) {
347+
return messages_.emplace_back(feature, std::forward<A>(args)...);
348+
}
349+
350+
template <typename... A>
351+
Message *Warn(bool isInModuleFile,
352+
const common::LanguageFeatureControl &control,
353+
common::LanguageFeature feature, A &&...args) {
354+
if (!isInModuleFile && control.ShouldWarn(feature)) {
355+
return &AddWarning(feature, std::forward<A>(args)...);
356+
}
357+
return nullptr;
358+
}
359+
360+
template <typename... A>
361+
Message *Warn(bool isInModuleFile,
362+
const common::LanguageFeatureControl &control,
363+
common::UsageWarning warning, A &&...args) {
364+
if (!isInModuleFile && control.ShouldWarn(warning)) {
365+
return &AddWarning(warning, std::forward<A>(args)...);
366+
}
367+
return nullptr;
345368
}
346369

347370
void Annex(Messages &&that) {
@@ -422,24 +445,6 @@ class ContextualMessages {
422445
return Say(at.value_or(at_), std::forward<A>(args)...);
423446
}
424447

425-
template <typename... A>
426-
Message *Say(common::LanguageFeature feature, A &&...args) {
427-
Message *msg{Say(std::forward<A>(args)...)};
428-
if (msg) {
429-
msg->set_languageFeature(feature);
430-
}
431-
return msg;
432-
}
433-
434-
template <typename... A>
435-
Message *Say(common::UsageWarning warning, A &&...args) {
436-
Message *msg{Say(std::forward<A>(args)...)};
437-
if (msg) {
438-
msg->set_usageWarning(warning);
439-
}
440-
return msg;
441-
}
442-
443448
Message *Say(Message &&msg) {
444449
if (messages_ != nullptr) {
445450
if (contextMessage_) {
@@ -451,6 +456,39 @@ class ContextualMessages {
451456
}
452457
}
453458

459+
template <typename FeatureOrUsageWarning, typename... A>
460+
Message *Warn(bool isInModuleFile,
461+
const common::LanguageFeatureControl &control,
462+
FeatureOrUsageWarning feature, CharBlock at, A &&...args) {
463+
if (messages_ != nullptr) {
464+
if (Message *
465+
msg{messages_->Warn(isInModuleFile, control, feature, at,
466+
std::forward<A>(args)...)}) {
467+
if (contextMessage_) {
468+
msg->SetContext(contextMessage_.get());
469+
}
470+
return msg;
471+
}
472+
}
473+
return nullptr;
474+
}
475+
476+
template <typename FeatureOrUsageWarning, typename... A>
477+
Message *Warn(bool isInModuleFile,
478+
const common::LanguageFeatureControl &control,
479+
FeatureOrUsageWarning feature, A &&...args) {
480+
return Warn(
481+
isInModuleFile, control, feature, at_, std::forward<A>(args)...);
482+
}
483+
484+
template <typename FeatureOrUsageWarning, typename... A>
485+
Message *Warn(bool isInModuleFile,
486+
const common::LanguageFeatureControl &control,
487+
FeatureOrUsageWarning feature, std::optional<CharBlock> at, A &&...args) {
488+
return Warn(isInModuleFile, control, feature, at.value_or(at_),
489+
std::forward<A>(args)...);
490+
}
491+
454492
private:
455493
CharBlock at_;
456494
Messages *messages_{nullptr};

flang/include/flang/Semantics/semantics.h

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -200,20 +200,59 @@ class SemanticsContext {
200200
return message;
201201
}
202202

203-
template <typename FeatureOrUsageWarning, typename... A>
203+
template <typename... A>
204+
parser::Message *Warn(parser::Messages &messages,
205+
common::LanguageFeature feature, parser::CharBlock at, A &&...args) {
206+
return messages.Warn(IsInModuleFile(at), languageFeatures_, feature, at,
207+
std::forward<A>(args)...);
208+
}
209+
template <typename... A>
210+
parser::Message *Warn(parser::Messages &messages,
211+
common::UsageWarning warning, parser::CharBlock at, A &&...args) {
212+
return messages.Warn(IsInModuleFile(at), languageFeatures_, warning, at,
213+
std::forward<A>(args)...);
214+
}
215+
template <typename... A>
216+
parser::Message *Warn(parser::ContextualMessages &messages,
217+
common::LanguageFeature feature, parser::CharBlock at, A &&...args) {
218+
return messages.Warn(IsInModuleFile(at), languageFeatures_, feature, at,
219+
std::forward<A>(args)...);
220+
}
221+
template <typename... A>
222+
parser::Message *Warn(parser::ContextualMessages &messages,
223+
common::UsageWarning warning, parser::CharBlock at, A &&...args) {
224+
return messages.Warn(IsInModuleFile(at), languageFeatures_, warning, at,
225+
std::forward<A>(args)...);
226+
}
227+
template <typename... A>
228+
parser::Message *Warn(parser::ContextualMessages &messages,
229+
common::LanguageFeature feature, A &&...args) {
230+
return messages.Warn(IsInModuleFile(messages.at()), languageFeatures_,
231+
feature, messages.at(), std::forward<A>(args)...);
232+
}
233+
template <typename... A>
234+
parser::Message *Warn(parser::ContextualMessages &messages,
235+
common::UsageWarning warning, A &&...args) {
236+
return messages.Warn(IsInModuleFile(messages.at()), languageFeatures_,
237+
warning, messages.at(), std::forward<A>(args)...);
238+
}
239+
template <typename... A>
240+
parser::Message *Warn(
241+
common::LanguageFeature feature, parser::CharBlock at, A &&...args) {
242+
return Warn(messages_, feature, at, std::forward<A>(args)...);
243+
}
244+
template <typename... A>
204245
parser::Message *Warn(
205-
FeatureOrUsageWarning warning, parser::CharBlock at, A &&...args) {
206-
if (languageFeatures_.ShouldWarn(warning) && !IsInModuleFile(at)) {
207-
parser::Message &msg{
208-
messages_.Say(warning, at, std::forward<A>(args)...)};
209-
return &msg;
210-
} else {
211-
return nullptr;
212-
}
213-
}
214-
215-
template <typename FeatureOrUsageWarning, typename... A>
216-
parser::Message *Warn(FeatureOrUsageWarning warning, A &&...args) {
246+
common::UsageWarning warning, parser::CharBlock at, A &&...args) {
247+
return Warn(messages_, warning, at, std::forward<A>(args)...);
248+
}
249+
template <typename... A>
250+
parser::Message *Warn(common::LanguageFeature feature, A &&...args) {
251+
CHECK(location_);
252+
return Warn(feature, *location_, std::forward<A>(args)...);
253+
}
254+
template <typename... A>
255+
parser::Message *Warn(common::UsageWarning warning, A &&...args) {
217256
CHECK(location_);
218257
return Warn(warning, *location_, std::forward<A>(args)...);
219258
}

flang/lib/Evaluate/check-expression.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ class SuspiciousRealLiteralFinder
415415
template <int KIND>
416416
bool operator()(const Constant<Type<TypeCategory::Real, KIND>> &x) const {
417417
if (kind_ > KIND && x.result().isFromInexactLiteralConversion()) {
418-
context_.messages().Say(common::UsageWarning::RealConstantWidening,
418+
context_.Warn(common::UsageWarning::RealConstantWidening,
419419
"Default real literal in REAL(%d) context might need a kind suffix, as its rounded value %s is inexact"_warn_en_US,
420420
kind_, x.AsFortran());
421421
return true;
@@ -426,7 +426,7 @@ class SuspiciousRealLiteralFinder
426426
template <int KIND>
427427
bool operator()(const Constant<Type<TypeCategory::Complex, KIND>> &x) const {
428428
if (kind_ > KIND && x.result().isFromInexactLiteralConversion()) {
429-
context_.messages().Say(common::UsageWarning::RealConstantWidening,
429+
context_.Warn(common::UsageWarning::RealConstantWidening,
430430
"Default real literal in COMPLEX(%d) context might need a kind suffix, as its rounded value %s is inexact"_warn_en_US,
431431
kind_, x.AsFortran());
432432
return true;
@@ -504,11 +504,8 @@ std::optional<Expr<SomeType>> NonPointerInitializationExpr(const Symbol &symbol,
504504
symbol.owner().context().IsEnabled(
505505
common::LanguageFeature::LogicalIntegerAssignment)) {
506506
converted = DataConstantConversionExtension(context, symTS->type(), x);
507-
if (converted &&
508-
symbol.owner().context().ShouldWarn(
509-
common::LanguageFeature::LogicalIntegerAssignment)) {
510-
context.messages().Say(
511-
common::LanguageFeature::LogicalIntegerAssignment,
507+
if (converted) {
508+
context.Warn(common::LanguageFeature::LogicalIntegerAssignment,
512509
"nonstandard usage: initialization of %s with %s"_port_en_US,
513510
symTS->type().AsFortran(), x.GetType().value().AsFortran());
514511
}
@@ -663,10 +660,8 @@ class CheckSpecificationExprHelper
663660
// host-associated dummy argument, and that doesn't seem like a
664661
// good idea.
665662
if (!inInquiry_ && hasHostAssociation &&
666-
ultimate.attrs().test(semantics::Attr::INTENT_OUT) &&
667-
context_.languageFeatures().ShouldWarn(
668-
common::UsageWarning::HostAssociatedIntentOutInSpecExpr)) {
669-
context_.messages().Say(
663+
ultimate.attrs().test(semantics::Attr::INTENT_OUT)) {
664+
context_.Warn(common::UsageWarning::HostAssociatedIntentOutInSpecExpr,
670665
"specification expression refers to host-associated INTENT(OUT) dummy argument '%s'"_port_en_US,
671666
ultimate.name());
672667
}
@@ -677,13 +672,9 @@ class CheckSpecificationExprHelper
677672
} else if (isInitialized &&
678673
context_.languageFeatures().IsEnabled(
679674
common::LanguageFeature::SavedLocalInSpecExpr)) {
680-
if (!scope_.IsModuleFile() &&
681-
context_.languageFeatures().ShouldWarn(
682-
common::LanguageFeature::SavedLocalInSpecExpr)) {
683-
context_.messages().Say(common::LanguageFeature::SavedLocalInSpecExpr,
684-
"specification expression refers to local object '%s' (initialized and saved)"_port_en_US,
685-
ultimate.name());
686-
}
675+
context_.Warn(common::LanguageFeature::SavedLocalInSpecExpr,
676+
"specification expression refers to local object '%s' (initialized and saved)"_port_en_US,
677+
ultimate.name());
687678
return std::nullopt;
688679
} else if (const auto *object{
689680
ultimate.detailsIf<semantics::ObjectEntityDetails>()}) {

flang/lib/Evaluate/common.cpp

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,22 @@ namespace Fortran::evaluate {
1616
void RealFlagWarnings(
1717
FoldingContext &context, const RealFlags &flags, const char *operation) {
1818
static constexpr auto warning{common::UsageWarning::FoldingException};
19-
if (context.languageFeatures().ShouldWarn(warning)) {
20-
if (flags.test(RealFlag::Overflow)) {
21-
context.messages().Say(warning, "overflow on %s"_warn_en_US, operation);
22-
}
23-
if (flags.test(RealFlag::DivideByZero)) {
24-
if (std::strcmp(operation, "division") == 0) {
25-
context.messages().Say(warning, "division by zero"_warn_en_US);
26-
} else {
27-
context.messages().Say(
28-
warning, "division by zero on %s"_warn_en_US, operation);
29-
}
30-
}
31-
if (flags.test(RealFlag::InvalidArgument)) {
32-
context.messages().Say(
33-
warning, "invalid argument on %s"_warn_en_US, operation);
34-
}
35-
if (flags.test(RealFlag::Underflow)) {
36-
context.messages().Say(warning, "underflow on %s"_warn_en_US, operation);
19+
if (flags.test(RealFlag::Overflow)) {
20+
context.Warn(warning, "overflow on %s"_warn_en_US, operation);
21+
}
22+
if (flags.test(RealFlag::DivideByZero)) {
23+
if (std::strcmp(operation, "division") == 0) {
24+
context.Warn(warning, "division by zero"_warn_en_US);
25+
} else {
26+
context.Warn(warning, "division by zero on %s"_warn_en_US, operation);
3727
}
3828
}
29+
if (flags.test(RealFlag::InvalidArgument)) {
30+
context.Warn(warning, "invalid argument on %s"_warn_en_US, operation);
31+
}
32+
if (flags.test(RealFlag::Underflow)) {
33+
context.Warn(warning, "underflow on %s"_warn_en_US, operation);
34+
}
3935
}
4036

4137
ConstantSubscript &FoldingContext::StartImpliedDo(

flang/lib/Evaluate/fold-character.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,10 @@ Expr<Type<TypeCategory::Character, KIND>> FoldIntrinsicFunction(
5858
return FoldElementalIntrinsic<T, IntT>(context, std::move(funcRef),
5959
ScalarFunc<T, IntT>([&](const Scalar<IntT> &i) {
6060
if (i.IsNegative() || i.BGE(Scalar<IntT>{0}.IBSET(8 * KIND))) {
61-
if (context.languageFeatures().ShouldWarn(
62-
common::UsageWarning::FoldingValueChecks)) {
63-
context.messages().Say(common::UsageWarning::FoldingValueChecks,
64-
"%s(I=%jd) is out of range for CHARACTER(KIND=%d)"_warn_en_US,
65-
parser::ToUpperCaseLetters(name),
66-
static_cast<std::intmax_t>(i.ToInt64()), KIND);
67-
}
61+
context.Warn(common::UsageWarning::FoldingValueChecks,
62+
"%s(I=%jd) is out of range for CHARACTER(KIND=%d)"_warn_en_US,
63+
parser::ToUpperCaseLetters(name),
64+
static_cast<std::intmax_t>(i.ToInt64()), KIND);
6865
}
6966
return CharacterUtils<KIND>::CHAR(i.ToUInt64());
7067
}));
@@ -106,12 +103,9 @@ Expr<Type<TypeCategory::Character, KIND>> FoldIntrinsicFunction(
106103
static_cast<std::intmax_t>(n));
107104
} else if (static_cast<double>(n) * str.size() >
108105
(1 << 20)) { // sanity limit of 1MiB
109-
if (context.languageFeatures().ShouldWarn(
110-
common::UsageWarning::FoldingLimit)) {
111-
context.messages().Say(common::UsageWarning::FoldingLimit,
112-
"Result of REPEAT() is too large to compute at compilation time (%g characters)"_port_en_US,
113-
static_cast<double>(n) * str.size());
114-
}
106+
context.Warn(common::UsageWarning::FoldingLimit,
107+
"Result of REPEAT() is too large to compute at compilation time (%g characters)"_port_en_US,
108+
static_cast<double>(n) * str.size());
115109
} else {
116110
return Expr<T>{Constant<T>{CharacterUtils<KIND>::REPEAT(str, n)}};
117111
}

flang/lib/Evaluate/fold-complex.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@ Expr<Type<TypeCategory::Complex, KIND>> FoldIntrinsicFunction(
2929
if (auto callable{GetHostRuntimeWrapper<T, T>(name)}) {
3030
return FoldElementalIntrinsic<T, T>(
3131
context, std::move(funcRef), *callable);
32-
} else if (context.languageFeatures().ShouldWarn(
33-
common::UsageWarning::FoldingFailure)) {
34-
context.messages().Say(common::UsageWarning::FoldingFailure,
32+
} else {
33+
context.Warn(common::UsageWarning::FoldingFailure,
3534
"%s(complex(kind=%d)) cannot be folded on host"_warn_en_US, name,
3635
KIND);
3736
}

0 commit comments

Comments
 (0)