Skip to content

Commit

Permalink
[flang] Finer control over warnings
Browse files Browse the repository at this point in the history
Establish a set of optional usage warnings, and enable some
only in "-pedantic" mode that, in our subjective experience
with application codes, seem to issue frequently without
indicating usage that really needs to be corrected.  By default,
with this patch the compiler should appear to be somewhat less
persnickety but not less informative.

Differential Revision: https://reviews.llvm.org/D150710
  • Loading branch information
klausler committed May 16, 2023
1 parent 9d87736 commit 191d487
Show file tree
Hide file tree
Showing 31 changed files with 235 additions and 190 deletions.
34 changes: 27 additions & 7 deletions flang/include/flang/Common/Fortran-features.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

namespace Fortran::common {

// Non-conforming extensions & legacies
ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
FixedFormContinuationWithColumn1Ampersand, LogicalAbbreviations,
XOROperator, PunctuationInNames, OptionalFreeFormSpace, BOZExtensions,
Expand All @@ -34,9 +35,17 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
ProgramReturn, ImplicitNoneTypeNever, ImplicitNoneTypeAlways,
ForwardRefImplicitNone, OpenAccessAppend, BOZAsDefaultInteger,
DistinguishableSpecifics, DefaultSave, PointerInSeqType, NonCharacterFormat,
SaveMainProgram, SaveBigMainProgramVariables)
SaveMainProgram, SaveBigMainProgramVariables,
DistinctArrayConstructorLengths)

// Portability and suspicious usage warnings for conforming code
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
NonTargetPassedToTarget, PointerToPossibleNoncontiguous,
ShortCharacterActual, ExprPassedToVolatile, ImplicitInterfaceActual,
PolymorphicTransferArg, PointerComponentTransferArg, TransferSizePresence)

using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;

class LanguageFeatureControl {
public:
Expand All @@ -58,22 +67,33 @@ class LanguageFeatureControl {
}
LanguageFeatureControl(const LanguageFeatureControl &) = default;
void Enable(LanguageFeature f, bool yes = true) { disable_.set(f, !yes); }
void EnableWarning(LanguageFeature f, bool yes = true) { warn_.set(f, yes); }
void WarnOnAllNonstandard(bool yes = true) { warnAll_ = yes; }
void EnableWarning(LanguageFeature f, bool yes = true) {
warnLanguage_.set(f, yes);
}
void EnableWarning(UsageWarning w, bool yes = true) {
warnUsage_.set(w, yes);
}
void WarnOnAllNonstandard(bool yes = true) { warnAllLanguage_ = yes; }
void WarnOnAllUsage(bool yes = true) { warnAllUsage_ = yes; }
bool IsEnabled(LanguageFeature f) const { return !disable_.test(f); }
bool ShouldWarn(LanguageFeature f) const {
return (warnAll_ && f != LanguageFeature::OpenMP &&
return (warnAllLanguage_ && f != LanguageFeature::OpenMP &&
f != LanguageFeature::OpenACC) ||
warn_.test(f);
warnLanguage_.test(f);
}
bool ShouldWarn(UsageWarning w) const {
return warnAllUsage_ || warnUsage_.test(w);
}
// Return all spellings of operators names, depending on features enabled
std::vector<const char *> GetNames(LogicalOperator) const;
std::vector<const char *> GetNames(RelationalOperator) const;

private:
LanguageFeatures disable_;
LanguageFeatures warn_;
bool warnAll_{false};
LanguageFeatures warnLanguage_;
bool warnAllLanguage_{false};
UsageWarnings warnUsage_;
bool warnAllUsage_{false};
};
} // namespace Fortran::common
#endif // FORTRAN_COMMON_FORTRAN_FEATURES_H_
7 changes: 7 additions & 0 deletions flang/include/flang/Frontend/CompilerInvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class CompilerInvocation : public CompilerInvocationBase {
Fortran::common::IntrinsicTypeDefaultKinds defaultKinds;

bool enableConformanceChecks = false;
bool enableUsageChecks = false;

/// Used in e.g. unparsing to dump the analyzed rather than the original
/// parse-tree objects.
Expand Down Expand Up @@ -184,6 +185,9 @@ class CompilerInvocation : public CompilerInvocationBase {
return enableConformanceChecks;
}

bool &getEnableUsageChecks() { return enableUsageChecks; }
const bool &getEnableUsageChecks() const { return enableUsageChecks; }

Fortran::parser::AnalyzedObjectsAsFortran &getAsFortran() {
return asFortran;
}
Expand All @@ -209,6 +213,9 @@ class CompilerInvocation : public CompilerInvocationBase {
// Enables the std=f2018 conformance check
void setEnableConformanceChecks() { enableConformanceChecks = true; }

// Enables the usage checks
void setEnableUsageChecks() { enableUsageChecks = true; }

/// Useful setters
void setModuleDir(std::string &dir) { moduleDir = dir; }

Expand Down
5 changes: 2 additions & 3 deletions flang/include/flang/Semantics/semantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ class SemanticsContext {
bool IsEnabled(common::LanguageFeature feature) const {
return languageFeatures_.IsEnabled(feature);
}
bool ShouldWarn(common::LanguageFeature feature) const {
return languageFeatures_.ShouldWarn(feature);
template <typename A> bool ShouldWarn(A x) const {
return languageFeatures_.ShouldWarn(x);
}
const std::optional<parser::CharBlock> &location() const { return location_; }
const std::vector<std::string> &searchDirectories() const {
Expand All @@ -93,7 +93,6 @@ class SemanticsContext {
}
const std::string &moduleDirectory() const { return moduleDirectory_; }
const std::string &moduleFileSuffix() const { return moduleFileSuffix_; }
bool warnOnNonstandardUsage() const { return warnOnNonstandardUsage_; }
bool warningsAreErrors() const { return warningsAreErrors_; }
bool debugModuleWriter() const { return debugModuleWriter_; }
const evaluate::IntrinsicProcTable &intrinsics() const { return intrinsics_; }
Expand Down
10 changes: 6 additions & 4 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,8 +774,9 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
// -pedantic
if (args.hasArg(clang::driver::options::OPT_pedantic)) {
res.setEnableConformanceChecks();
res.setEnableUsageChecks();
}
// -std=f2018 (currently this implies -pedantic)
// -std=f2018
// TODO: Set proper options when more fortran standards
// are supported.
if (args.hasArg(clang::driver::options::OPT_std_EQ)) {
Expand Down Expand Up @@ -1045,9 +1046,11 @@ void CompilerInvocation::setFortranOpts() {
if (frontendOptions.needProvenanceRangeToCharBlockMappings)
fortranOptions.needProvenanceRangeToCharBlockMappings = true;

if (getEnableConformanceChecks()) {
if (getEnableConformanceChecks())
fortranOptions.features.WarnOnAllNonstandard();
}

if (getEnableUsageChecks())
fortranOptions.features.WarnOnAllUsage();
}

void CompilerInvocation::setSemanticsOpts(
Expand All @@ -1060,7 +1063,6 @@ void CompilerInvocation::setSemanticsOpts(
semanticsContext->set_moduleDirectory(getModuleDir())
.set_searchDirectories(fortranOptions.searchDirectories)
.set_intrinsicModuleDirectories(fortranOptions.intrinsicModuleDirectories)
.set_warnOnNonstandardUsage(getEnableConformanceChecks())
.set_warningsAreErrors(getWarnAsErr())
.set_moduleFileSuffix(getModuleFileSuffix());

Expand Down
3 changes: 1 addition & 2 deletions flang/lib/Semantics/assignment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ void AssignmentContext::Analyze(const parser::PointerAssignmentStmt &stmt) {
if (const evaluate::Assignment * assignment{GetAssignment(stmt)}) {
parser::CharBlock at{context_.location().value()};
auto restorer{foldingContext().messages().SetLocation(at)};
CheckPointerAssignment(
foldingContext(), *assignment, context_.FindScope(at));
CheckPointerAssignment(context_, *assignment, context_.FindScope(at));
}
}

Expand Down

0 comments on commit 191d487

Please sign in to comment.