Skip to content

[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

Merged
merged 1 commit into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 6 additions & 73 deletions flang/include/flang/Common/Fortran-features.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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); }
Expand Down
90 changes: 88 additions & 2 deletions flang/include/flang/Parser/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand All @@ -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_; }

Expand All @@ -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;
Expand All @@ -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 {
Expand All @@ -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_);
}
Expand Down Expand Up @@ -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)...)};
Expand All @@ -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) {
Expand Down
10 changes: 10 additions & 0 deletions flang/include/flang/Semantics/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
20 changes: 19 additions & 1 deletion flang/include/flang/Semantics/semantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,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);
Expand Down Expand Up @@ -270,7 +288,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 &);

Expand Down
Loading
Loading