-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] Tag warnings with LanguageFeature or UsageWarning #110304
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
@llvm/pr-subscribers-flang-parser @llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) ChangesAllow a parser::Message for a warning to be marked with the common::LanguageFeature or common::UsageWarning that controls it. This will allow a later patch to add hooks whereby a driver will be able to decorate warning messages with the names of its options that enable each particular warning, and to add hooks whereby a driver can map those enumerators by name to command-line options that enable/disable the language feature and enable/disable the messages. Hooks for a driver to use to map the name of a feature or warning to its enumerator were also added. To simplify the tagging of warnings with their corresponding language feature or usage warning, to ensure that they are properly controlled by ShouldWarn(), and to ensure that warnings never issue at code sites in module files, two new Warn() member function templates were added to SemanticsContext and other contextual frameworks. Warn() can't be used before source locations can be mapped to scopes, but the bulk of existing code blocks testing ShouldWarn() and FindModuleFile() before calling Say() were convertible into calls to Warn(). The ones that were not convertible were extended with explicit calls to Message::set_languageFeature() and set_usageWarning(). Patch is 206.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110304.diff 44 Files Affected:
diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index 86c6e02b0f2ffd..f813cbae40a57e 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -12,6 +12,7 @@
#include "flang/Common/Fortran.h"
#include "flang/Common/enum-set.h"
#include "flang/Common/idioms.h"
+#include <optional>
#include <vector>
namespace Fortran::common {
@@ -48,7 +49,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
ImpliedDoIndexScope, DistinctCommonSizes, OddIndexVariableRestrictions,
IndistinguishableSpecifics, SubroutineAndFunctionSpecifics,
EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
- BadBranchTarget, ConvertedArgument, HollerithPolymorphic, ListDirectedSize,
+ BadBranchTarget, HollerithPolymorphic, ListDirectedSize,
NonBindCInteroperability, CudaManaged, CudaUnified,
PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr,
@@ -76,80 +77,12 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
+std::optional<LanguageFeature> FindLanguageFeature(const char *);
+std::optional<UsageWarning> FindUsageWarning(const char *);
+
class LanguageFeatureControl {
public:
- LanguageFeatureControl() {
- // These features must be explicitly enabled by command line options.
- disable_.set(LanguageFeature::OldDebugLines);
- disable_.set(LanguageFeature::OpenACC);
- disable_.set(LanguageFeature::OpenMP);
- disable_.set(LanguageFeature::CUDA); // !@cuf
- disable_.set(LanguageFeature::CudaManaged);
- disable_.set(LanguageFeature::CudaUnified);
- disable_.set(LanguageFeature::ImplicitNoneTypeNever);
- disable_.set(LanguageFeature::ImplicitNoneTypeAlways);
- disable_.set(LanguageFeature::DefaultSave);
- disable_.set(LanguageFeature::SaveMainProgram);
- // These features, if enabled, conflict with valid standard usage,
- // so there are disabled here by default.
- disable_.set(LanguageFeature::BackslashEscapes);
- disable_.set(LanguageFeature::LogicalAbbreviations);
- disable_.set(LanguageFeature::XOROperator);
- disable_.set(LanguageFeature::OldStyleParameter);
- // These warnings are enabled by default, but only because they used
- // to be unconditional. TODO: prune this list
- warnLanguage_.set(LanguageFeature::ExponentMatchingKindParam);
- warnLanguage_.set(LanguageFeature::RedundantAttribute);
- warnLanguage_.set(LanguageFeature::SubroutineAndFunctionSpecifics);
- warnLanguage_.set(LanguageFeature::EmptySequenceType);
- warnLanguage_.set(LanguageFeature::NonSequenceCrayPointee);
- warnLanguage_.set(LanguageFeature::BranchIntoConstruct);
- warnLanguage_.set(LanguageFeature::BadBranchTarget);
- warnLanguage_.set(LanguageFeature::ConvertedArgument);
- warnLanguage_.set(LanguageFeature::HollerithPolymorphic);
- warnLanguage_.set(LanguageFeature::ListDirectedSize);
- warnUsage_.set(UsageWarning::ShortArrayActual);
- warnUsage_.set(UsageWarning::FoldingException);
- warnUsage_.set(UsageWarning::FoldingAvoidsRuntimeCrash);
- warnUsage_.set(UsageWarning::FoldingValueChecks);
- warnUsage_.set(UsageWarning::FoldingFailure);
- warnUsage_.set(UsageWarning::FoldingLimit);
- warnUsage_.set(UsageWarning::Interoperability);
- warnUsage_.set(UsageWarning::Bounds);
- warnUsage_.set(UsageWarning::Preprocessing);
- warnUsage_.set(UsageWarning::Scanning);
- warnUsage_.set(UsageWarning::OpenAccUsage);
- warnUsage_.set(UsageWarning::ProcPointerCompatibility);
- warnUsage_.set(UsageWarning::VoidMold);
- warnUsage_.set(UsageWarning::KnownBadImplicitInterface);
- warnUsage_.set(UsageWarning::EmptyCase);
- warnUsage_.set(UsageWarning::CaseOverflow);
- warnUsage_.set(UsageWarning::CUDAUsage);
- warnUsage_.set(UsageWarning::IgnoreTKRUsage);
- warnUsage_.set(UsageWarning::ExternalInterfaceMismatch);
- warnUsage_.set(UsageWarning::DefinedOperatorArgs);
- warnUsage_.set(UsageWarning::Final);
- warnUsage_.set(UsageWarning::ZeroDoStep);
- warnUsage_.set(UsageWarning::UnusedForallIndex);
- warnUsage_.set(UsageWarning::OpenMPUsage);
- warnUsage_.set(UsageWarning::ModuleFile);
- warnUsage_.set(UsageWarning::DataLength);
- warnUsage_.set(UsageWarning::IgnoredDirective);
- warnUsage_.set(UsageWarning::HomonymousSpecific);
- warnUsage_.set(UsageWarning::HomonymousResult);
- warnUsage_.set(UsageWarning::IgnoredIntrinsicFunctionType);
- warnUsage_.set(UsageWarning::PreviousScalarUse);
- warnUsage_.set(UsageWarning::RedeclaredInaccessibleComponent);
- warnUsage_.set(UsageWarning::ImplicitShared);
- warnUsage_.set(UsageWarning::IndexVarRedefinition);
- warnUsage_.set(UsageWarning::IncompatibleImplicitInterfaces);
- warnUsage_.set(UsageWarning::BadTypeForTarget);
- warnUsage_.set(UsageWarning::VectorSubscriptFinalization);
- warnUsage_.set(UsageWarning::UndefinedFunctionResult);
- warnUsage_.set(UsageWarning::UselessIomsg);
- // New warnings, on by default
- warnLanguage_.set(LanguageFeature::SavedLocalInSpecExpr);
- }
+ LanguageFeatureControl();
LanguageFeatureControl(const LanguageFeatureControl &) = default;
void Enable(LanguageFeature f, bool yes = true) { disable_.set(f, !yes); }
diff --git a/flang/include/flang/Parser/message.h b/flang/include/flang/Parser/message.h
index 668559aeec9478..bc38f571ca3df4 100644
--- a/flang/include/flang/Parser/message.h
+++ b/flang/include/flang/Parser/message.h
@@ -15,6 +15,7 @@
#include "char-block.h"
#include "char-set.h"
#include "provenance.h"
+#include "flang/Common/Fortran-features.h"
#include "flang/Common/idioms.h"
#include "flang/Common/reference-counted.h"
#include "flang/Common/restorer.h"
@@ -202,6 +203,26 @@ class Message : public common::ReferenceCounted<Message> {
Message(ProvenanceRange pr, const MessageExpectedText &t)
: location_{pr}, text_{t} {}
+ Message(common::LanguageFeature feature, ProvenanceRange pr,
+ const MessageFixedText &t)
+ : location_{pr}, text_{t}, languageFeature_{feature} {}
+ Message(common::LanguageFeature feature, ProvenanceRange pr,
+ const MessageFormattedText &s)
+ : location_{pr}, text_{s}, languageFeature_{feature} {}
+ Message(common::LanguageFeature feature, ProvenanceRange pr,
+ MessageFormattedText &&s)
+ : location_{pr}, text_{std::move(s)}, languageFeature_{feature} {}
+
+ Message(common::UsageWarning warning, ProvenanceRange pr,
+ const MessageFixedText &t)
+ : location_{pr}, text_{t}, usageWarning_{warning} {}
+ Message(common::UsageWarning warning, ProvenanceRange pr,
+ const MessageFormattedText &s)
+ : location_{pr}, text_{s}, usageWarning_{warning} {}
+ Message(common::UsageWarning warning, ProvenanceRange pr,
+ MessageFormattedText &&s)
+ : location_{pr}, text_{std::move(s)}, usageWarning_{warning} {}
+
Message(CharBlock csr, const MessageFixedText &t)
: location_{csr}, text_{t} {}
Message(CharBlock csr, const MessageFormattedText &s)
@@ -211,10 +232,41 @@ class Message : public common::ReferenceCounted<Message> {
Message(CharBlock csr, const MessageExpectedText &t)
: location_{csr}, text_{t} {}
+ Message(
+ common::LanguageFeature feature, CharBlock csr, const MessageFixedText &t)
+ : location_{csr}, text_{t}, languageFeature_{feature} {}
+ Message(common::LanguageFeature feature, CharBlock csr,
+ const MessageFormattedText &s)
+ : location_{csr}, text_{s}, languageFeature_{feature} {}
+ Message(
+ common::LanguageFeature feature, CharBlock csr, MessageFormattedText &&s)
+ : location_{csr}, text_{std::move(s)}, languageFeature_{feature} {}
+
+ Message(
+ common::UsageWarning warning, CharBlock csr, const MessageFixedText &t)
+ : location_{csr}, text_{t}, usageWarning_{warning} {}
+ Message(common::UsageWarning warning, CharBlock csr,
+ const MessageFormattedText &s)
+ : location_{csr}, text_{s}, usageWarning_{warning} {}
+ Message(common::UsageWarning warning, CharBlock csr, MessageFormattedText &&s)
+ : location_{csr}, text_{std::move(s)}, usageWarning_{warning} {}
+
template <typename RANGE, typename A, typename... As>
Message(RANGE r, const MessageFixedText &t, A &&x, As &&...xs)
: location_{r}, text_{MessageFormattedText{
t, std::forward<A>(x), std::forward<As>(xs)...}} {}
+ template <typename RANGE, typename A, typename... As>
+ Message(common::LanguageFeature feature, RANGE r, const MessageFixedText &t,
+ A &&x, As &&...xs)
+ : location_{r}, text_{MessageFormattedText{
+ t, std::forward<A>(x), std::forward<As>(xs)...}},
+ languageFeature_{feature} {}
+ template <typename RANGE, typename A, typename... As>
+ Message(common::UsageWarning warning, RANGE r, const MessageFixedText &t,
+ A &&x, As &&...xs)
+ : location_{r}, text_{MessageFormattedText{
+ t, std::forward<A>(x), std::forward<As>(xs)...}},
+ usageWarning_{warning} {}
Reference attachment() const { return attachment_; }
@@ -232,6 +284,10 @@ class Message : public common::ReferenceCounted<Message> {
bool IsFatal() const;
Severity severity() const;
Message &set_severity(Severity);
+ std::optional<common::LanguageFeature> languageFeature() const;
+ Message &set_languageFeature(common::LanguageFeature);
+ std::optional<common::UsageWarning> usageWarning() const;
+ Message &set_usageWarning(common::UsageWarning);
std::string ToString() const;
std::optional<ProvenanceRange> GetProvenanceRange(
const AllCookedSources &) const;
@@ -256,6 +312,8 @@ class Message : public common::ReferenceCounted<Message> {
text_;
bool attachmentIsContext_{false};
Reference attachment_;
+ std::optional<common::LanguageFeature> languageFeature_;
+ std::optional<common::UsageWarning> usageWarning_;
};
class Messages {
@@ -275,6 +333,16 @@ class Messages {
return messages_.emplace_back(std::forward<A>(args)...);
}
+ template <typename... A>
+ Message &Say(common::LanguageFeature feature, A &&...args) {
+ return Say(std::forward<A>(args)...).set_languageFeature(feature);
+ }
+
+ template <typename... A>
+ Message &Say(common::UsageWarning warning, A &&...args) {
+ return Say(std::forward<A>(args)...).set_usageWarning(warning);
+ }
+
void Annex(Messages &&that) {
messages_.splice(messages_.end(), that.messages_);
}
@@ -330,6 +398,10 @@ class ContextualMessages {
return common::ScopedSet(messages_, nullptr);
}
+ template <typename... A> Message *Say(A &&...args) {
+ return Say(at_, std::forward<A>(args)...);
+ }
+
template <typename... A> Message *Say(CharBlock at, A &&...args) {
if (messages_ != nullptr) {
auto &msg{messages_->Say(at, std::forward<A>(args)...)};
@@ -347,8 +419,22 @@ class ContextualMessages {
return Say(at.value_or(at_), std::forward<A>(args)...);
}
- template <typename... A> Message *Say(A &&...args) {
- return Say(at_, std::forward<A>(args)...);
+ template <typename... A>
+ Message *Say(common::LanguageFeature feature, A &&...args) {
+ Message *msg{Say(std::forward<A>(args)...)};
+ if (msg) {
+ msg->set_languageFeature(feature);
+ }
+ return msg;
+ }
+
+ template <typename... A>
+ Message *Say(common::UsageWarning warning, A &&...args) {
+ Message *msg{Say(std::forward<A>(args)...)};
+ if (msg) {
+ msg->set_usageWarning(warning);
+ }
+ return msg;
}
Message *Say(Message &&msg) {
diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h
index c90c8c4b3cc70f..a90801db7338cc 100644
--- a/flang/include/flang/Semantics/expression.h
+++ b/flang/include/flang/Semantics/expression.h
@@ -123,6 +123,16 @@ class ExpressionAnalyzer {
template <typename... A> parser::Message *Say(A &&...args) {
return GetContextualMessages().Say(std::forward<A>(args)...);
}
+ template <typename FeatureOrUsageWarning, typename... A>
+ parser::Message *Warn(
+ FeatureOrUsageWarning warning, parser::CharBlock at, A &&...args) {
+ return context_.Warn(warning, at, std::forward<A>(args)...);
+ }
+ template <typename FeatureOrUsageWarning, typename... A>
+ parser::Message *Warn(FeatureOrUsageWarning warning, A &&...args) {
+ return Warn(
+ warning, GetContextualMessages().at(), std::forward<A>(args)...);
+ }
template <typename T, typename... A>
parser::Message *SayAt(const T &parsed, A &&...args) {
diff --git a/flang/include/flang/Semantics/semantics.h b/flang/include/flang/Semantics/semantics.h
index e73f9d2e85d589..a9b9e9f3031b57 100644
--- a/flang/include/flang/Semantics/semantics.h
+++ b/flang/include/flang/Semantics/semantics.h
@@ -185,6 +185,24 @@ class SemanticsContext {
return message;
}
+ template <typename FeatureOrUsageWarning, typename... A>
+ parser::Message *Warn(
+ FeatureOrUsageWarning warning, parser::CharBlock at, A &&...args) {
+ if (languageFeatures_.ShouldWarn(warning) && !IsInModuleFile(at)) {
+ parser::Message &msg{
+ messages_.Say(warning, at, std::forward<A>(args)...)};
+ return &msg;
+ } else {
+ return nullptr;
+ }
+ }
+
+ template <typename FeatureOrUsageWarning, typename... A>
+ parser::Message *Warn(FeatureOrUsageWarning warning, A &&...args) {
+ CHECK(location_);
+ return Warn(warning, *location_, std::forward<A>(args)...);
+ }
+
const Scope &FindScope(parser::CharBlock) const;
Scope &FindScope(parser::CharBlock);
void UpdateScopeIndex(Scope &, parser::CharBlock);
@@ -267,7 +285,7 @@ class SemanticsContext {
std::multimap<parser::CharBlock, Scope &, ScopeIndexComparator>;
ScopeIndex::iterator SearchScopeIndex(parser::CharBlock);
- void CheckIndexVarRedefine(
+ parser::Message *CheckIndexVarRedefine(
const parser::CharBlock &, const Symbol &, parser::MessageFixedText &&);
void CheckError(const Symbol &);
diff --git a/flang/lib/Common/Fortran-features.cpp b/flang/lib/Common/Fortran-features.cpp
index 25a948818e6560..8f2a96095ab853 100644
--- a/flang/lib/Common/Fortran-features.cpp
+++ b/flang/lib/Common/Fortran-features.cpp
@@ -9,9 +9,103 @@
#include "flang/Common/Fortran-features.h"
#include "flang/Common/Fortran.h"
#include "flang/Common/idioms.h"
+#include <strings.h>
namespace Fortran::common {
+LanguageFeatureControl::LanguageFeatureControl() {
+ // These features must be explicitly enabled by command line options.
+ disable_.set(LanguageFeature::OldDebugLines);
+ disable_.set(LanguageFeature::OpenACC);
+ disable_.set(LanguageFeature::OpenMP);
+ disable_.set(LanguageFeature::CUDA); // !@cuf
+ disable_.set(LanguageFeature::CudaManaged);
+ disable_.set(LanguageFeature::CudaUnified);
+ disable_.set(LanguageFeature::ImplicitNoneTypeNever);
+ disable_.set(LanguageFeature::ImplicitNoneTypeAlways);
+ disable_.set(LanguageFeature::DefaultSave);
+ disable_.set(LanguageFeature::SaveMainProgram);
+ // These features, if enabled, conflict with valid standard usage,
+ // so there are disabled here by default.
+ disable_.set(LanguageFeature::BackslashEscapes);
+ disable_.set(LanguageFeature::LogicalAbbreviations);
+ disable_.set(LanguageFeature::XOROperator);
+ disable_.set(LanguageFeature::OldStyleParameter);
+ // These warnings are enabled by default, but only because they used
+ // to be unconditional. TODO: prune this list
+ warnLanguage_.set(LanguageFeature::ExponentMatchingKindParam);
+ warnLanguage_.set(LanguageFeature::RedundantAttribute);
+ warnLanguage_.set(LanguageFeature::SubroutineAndFunctionSpecifics);
+ warnLanguage_.set(LanguageFeature::EmptySequenceType);
+ warnLanguage_.set(LanguageFeature::NonSequenceCrayPointee);
+ warnLanguage_.set(LanguageFeature::BranchIntoConstruct);
+ warnLanguage_.set(LanguageFeature::BadBranchTarget);
+ warnLanguage_.set(LanguageFeature::HollerithPolymorphic);
+ warnLanguage_.set(LanguageFeature::ListDirectedSize);
+ warnUsage_.set(UsageWarning::ShortArrayActual);
+ warnUsage_.set(UsageWarning::FoldingException);
+ warnUsage_.set(UsageWarning::FoldingAvoidsRuntimeCrash);
+ warnUsage_.set(UsageWarning::FoldingValueChecks);
+ warnUsage_.set(UsageWarning::FoldingFailure);
+ warnUsage_.set(UsageWarning::FoldingLimit);
+ warnUsage_.set(UsageWarning::Interoperability);
+ warnUsage_.set(UsageWarning::Bounds);
+ warnUsage_.set(UsageWarning::Preprocessing);
+ warnUsage_.set(UsageWarning::Scanning);
+ warnUsage_.set(UsageWarning::OpenAccUsage);
+ warnUsage_.set(UsageWarning::ProcPointerCompatibility);
+ warnUsage_.set(UsageWarning::VoidMold);
+ warnUsage_.set(UsageWarning::KnownBadImplicitInterface);
+ warnUsage_.set(UsageWarning::EmptyCase);
+ warnUsage_.set(UsageWarning::CaseOverflow);
+ warnUsage_.set(UsageWarning::CUDAUsage);
+ warnUsage_.set(UsageWarning::IgnoreTKRUsage);
+ warnUsage_.set(UsageWarning::ExternalInterfaceMismatch);
+ warnUsage_.set(UsageWarning::DefinedOperatorArgs);
+ warnUsage_.set(UsageWarning::Final);
+ warnUsage_.set(UsageWarning::ZeroDoStep);
+ warnUsage_.set(UsageWarning::UnusedForallIndex);
+ warnUsage_.set(UsageWarning::OpenMPUsage);
+ warnUsage_.set(UsageWarning::ModuleFile);
+ warnUsage_.set(UsageWarning::DataLength);
+ warnUsage_.set(UsageWarning::IgnoredDirective);
+ warnUsage_.set(UsageWarning::HomonymousSpecific);
+ warnUsage_.set(UsageWarning::HomonymousResult);
+ warnUsage_.set(UsageWarning::IgnoredIntrinsicFunctionType);
+ warnUsage_.set(UsageWarning::PreviousScalarUse);
+ warnUsage_.set(UsageWarning::RedeclaredInaccessibleComponent);
+ warnUsage_.set(UsageWarning::ImplicitShared);
+ warnUsage_.set(UsageWarning::IndexVarRedefinition);
+ warnUsage_.set(UsageWarning::IncompatibleImplicitInterfaces);
+ warnUsage_.set(UsageWarning::BadTypeForTarget);
+ warnUsage_.set(UsageWarning::VectorSubscriptFinalization);
+ warnUsage_.set(UsageWarning::UndefinedFunctionResult);
+ warnUsage_.set(UsageWarning::UselessIomsg);
+ // New warnings, on by default
+ warnLanguage_.set(LanguageFeature::SavedLocalInSpecExpr);
+}
+
+template <typename ENUM, std::size_t N>
+std::optional<ENUM> ScanEnum(const char *name) {
+ if (name) {
+ for (std::size_t j{0}; j < N; ++j) {
+ auto feature{static_cast<ENUM>(j)};
+ if (::strcasecmp(name, EnumToString(feature).data()) == 0) {
+ return feature;
+ }
+ }
+ }
+ return std::nullopt;
+}
+
+std::optional<LanguageFeature> FindLanguageFeature(const char *name) {
+ return ScanEnum<LanguageFeature, LanguageFeature_enumSize>(name);
+}
+
+std::optional<UsageWarning> FindUsageWarning(const char *name) {
+ return ScanEnum<UsageWarning, UsageWarning_enumSize>(name);
+}
+
std::vector<const char *> LanguageFeatureControl::GetNames(
LogicalOperator opr) const {
std::vector<const char *> result;
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index a1ede7d7553bf6..38794a2d8aacc7 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -412,6 +412,7 @@ std::optional<Expr<SomeType>> NonPointerInitializationExpr(const Symbol &symbol,
symbol.owner().context().ShouldWarn(
common::LanguageFeature::LogicalIntegerAssignment)) {
context.messages().Say(
+ common::LanguageFeature::LogicalIntegerAssignment,
"nonstandard usage: initialization of %s with %s"_port_en_US,
symTS->type().AsFortran(), x.GetType().value().AsFortran());
}
@@ -565,7 +566,7 @@ class CheckSpecificationExprHelper
if (!scope_.IsModuleFile() &&
context_.languageFeatures().ShouldWarn(
common::LanguageFeature::SavedLocalInSpecExpr)) {
- context_.messages().Say(
+ context_.messages().Say(common::LanguageFeature::SavedLocalInSpecExpr,
"specification expression refers to local object '%s' (initialized and saved)"_port_en_US,
ultimate.name().ToString());
}
@@ -1102,44 +1103,53 @@ class StmtFunctionChecker
public:
using Result = std::optional<parser::Me...
[truncated]
|
7d407f5
to
7383943
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Thanks Peter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, looks great!
@@ -565,7 +566,7 @@ class CheckSpecificationExprHelper | |||
if (!scope_.IsModuleFile() && | |||
context_.languageFeatures().ShouldWarn( | |||
common::LanguageFeature::SavedLocalInSpecExpr)) { | |||
context_.messages().Say( | |||
context_.messages().Say(common::LanguageFeature::SavedLocalInSpecExpr, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it too soon to use Warn here and folding, or is it a matter of going through them again and updating them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warn() is in Semantics and can't be used in Evaluate.
f8650db
to
a14f7c8
Compare
It's a great addition to Flang, thank you! I'm not really qualified to review this, but I do support this kind of development.
How about integrating this with the driver so that we can see how this works in practice? |
That'll come next. This patch was already too large, and adds the infrastructure that will be needed for any driver work later, however that looks. And that's going to be complicated. |
(This is a big patch, but it's nearly an NFC. No test results have changed and all Fortran tests in the LLVM test suites work as expected.) Allow a parser::Message for a warning to be marked with the common::LanguageFeature or common::UsageWarning that controls it. This will allow a later patch to add hooks whereby a driver will be able to decorate warning messages with the names of its options that enable each particular warning, and to add hooks whereby a driver can map those enumerators by name to command-line options that enable/disable the language feature and enable/disable the messages. The default settings in the constructor for LanguageFeatureControl were moved from its header file into its C++ source file. Hooks for a driver to use to map the name of a feature or warning to its enumerator were also added. To simplify the tagging of warnings with their corresponding language feature or usage warning, to ensure that they are properly controlled by ShouldWarn(), and to ensure that warnings never issue at code sites in module files, two new Warn() member function templates were added to SemanticsContext and other contextual frameworks. Warn() can't be used before source locations can be mapped to scopes, but the bulk of existing code blocks testing ShouldWarn() and FindModuleFile() before calling Say() were convertible into calls to Warn(). The ones that were not convertible were extended with explicit calls to Message::set_languageFeature() and set_usageWarning().
a14f7c8
to
c730d57
Compare
(This is a big patch, but it's nearly an NFC. No test results have changed and all Fortran tests in the LLVM test suites work as expected.) Allow a parser::Message for a warning to be marked with the common::LanguageFeature or common::UsageWarning that controls it. This will allow a later patch to add hooks whereby a driver will be able to decorate warning messages with the names of its options that enable each particular warning, and to add hooks whereby a driver can map those enumerators by name to command-line options that enable/disable the language feature and enable/disable the messages. The default settings in the constructor for LanguageFeatureControl were moved from its header file into its C++ source file. Hooks for a driver to use to map the name of a feature or warning to its enumerator were also added. To simplify the tagging of warnings with their corresponding language feature or usage warning, to ensure that they are properly controlled by ShouldWarn(), and to ensure that warnings never issue at code sites in module files, two new Warn() member function templates were added to SemanticsContext and other contextual frameworks. Warn() can't be used before source locations can be mapped to scopes, but the bulk of existing code blocks testing ShouldWarn() and FindModuleFile() before calling Say() were convertible into calls to Warn(). The ones that were not convertible were extended with explicit calls to Message::set_languageFeature() and set_usageWarning().
@klausler This commit moves the following program to an error from a warning. Is it intentional? program main
procedure(rfunc), pointer :: ptr
ptr => null()
if (associated(ptr, ifunc)) then
print *, "bad"
end if
contains
function ifunc(x)
integer, intent(in) :: x
integer :: ifunc
ifunc = x
end function
function rfunc(x)
real, intent(in) :: x
real :: rfunc
rfunc = x
end function
end Before this commit:
After this commit:
(This is just a confirmation. No objection to making it an error.) |
Yes, an error is appropriate, and many other Fortran compilers emit one for this case. |
(This is a big patch, but it's nearly an NFC. No test results have changed and all Fortran tests in the LLVM test suites work as expected.)
Allow a parser::Message for a warning to be marked with the common::LanguageFeature or common::UsageWarning that controls it. This will allow a later patch to add hooks whereby a driver will be able to decorate warning messages with the names of its options that enable each particular warning, and to add hooks whereby a driver can map those enumerators by name to command-line options that enable/disable the language feature and enable/disable the messages.
The default settings in the constructor for LanguageFeatureControl were moved from its header file into its C++ source file.
Hooks for a driver to use to map the name of a feature or warning to its enumerator were also added.
To simplify the tagging of warnings with their corresponding language feature or usage warning, to ensure that they are properly controlled by ShouldWarn(), and to ensure that warnings never issue at code sites in module files, two new Warn() member function templates were added to SemanticsContext and other contextual frameworks. Warn() can't be used before source locations can be mapped to scopes, but the bulk of existing code blocks testing ShouldWarn() and FindModuleFile() before calling Say() were convertible into calls to Warn(). The ones that were not convertible were extended with explicit calls to Message::set_languageFeature() and set_usageWarning().