Skip to content

Commit 505f6da

Browse files
authored
[flang] Ensure all warning/portability messages are guarded by Should… (llvm#90518)
…Warn() Many warning messages were being emitted unconditionally. Ensure that all warnings are conditional on a true result from a call to common::LanguageFeatureControl::ShouldWarn() so that it is easy for a driver to disable them all, or, in the future, to provide per-warning control over them.
1 parent 37277d8 commit 505f6da

38 files changed

+725
-353
lines changed

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

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,33 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
4141
ActualIntegerConvertedToSmallerKind, HollerithOrCharacterAsBOZ,
4242
BindingAsProcedure, StatementFunctionExtensions,
4343
UseGenericIntrinsicWhenSpecificDoesntMatch, DataStmtExtensions,
44-
RedundantContiguous, InitBlankCommon, EmptyBindCDerivedType,
45-
MiscSourceExtensions, AllocateToOtherLength, LongNames, IntrinsicAsSpecific,
46-
BenignNameClash, BenignRedundancy, NullMoldAllocatableComponentValue,
47-
NopassScalarBase, MiscUseExtensions, ImpliedDoIndexScope,
48-
DistinctCommonSizes, OddIndexVariableRestrictions,
49-
IndistinguishableSpecifics)
44+
RedundantContiguous, RedundantAttribute, InitBlankCommon,
45+
EmptyBindCDerivedType, MiscSourceExtensions, AllocateToOtherLength,
46+
LongNames, IntrinsicAsSpecific, BenignNameClash, BenignRedundancy,
47+
NullMoldAllocatableComponentValue, NopassScalarBase, MiscUseExtensions,
48+
ImpliedDoIndexScope, DistinctCommonSizes, OddIndexVariableRestrictions,
49+
IndistinguishableSpecifics, SubroutineAndFunctionSpecifics,
50+
EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
51+
BadBranchTarget, ConvertedArgument, HollerithPolymorphic, ListDirectedSize)
5052

51-
// Portability and suspicious usage warnings for conforming code
53+
// Portability and suspicious usage warnings
5254
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
5355
NonTargetPassedToTarget, PointerToPossibleNoncontiguous,
54-
ShortCharacterActual, ExprPassedToVolatile, ImplicitInterfaceActual,
55-
PolymorphicTransferArg, PointerComponentTransferArg, TransferSizePresence,
56-
F202XAllocatableBreakingChange, DimMustBePresent, CommonBlockPadding,
57-
LogicalVsCBool, BindCCharLength, ProcDummyArgShapes, ExternalNameConflict)
56+
ShortCharacterActual, ShortArrayActual, ExprPassedToVolatile,
57+
ImplicitInterfaceActual, PolymorphicTransferArg,
58+
PointerComponentTransferArg, TransferSizePresence,
59+
F202XAllocatableBreakingChange, OptionalMustBePresent, CommonBlockPadding,
60+
LogicalVsCBool, BindCCharLength, ProcDummyArgShapes, ExternalNameConflict,
61+
FoldingException, FoldingAvoidsRuntimeCrash, FoldingValueChecks,
62+
FoldingFailure, FoldingLimit, Interoperability, Bounds, Preprocessing,
63+
Scanning, OpenAccUsage, ProcPointerCompatibility, VoidMold,
64+
KnownBadImplicitInterface, EmptyCase, CaseOverflow, CUDAUsage,
65+
IgnoreTKRUsage, ExternalInterfaceMismatch, DefinedOperatorArgs, Final,
66+
ZeroDoStep, UnusedForallIndex, OpenMPUsage, ModuleFile, DataLength,
67+
IgnoredDirective, HomonymousSpecific, HomonymousResult,
68+
IgnoredIntrinsicFunctionType, PreviousScalarUse,
69+
RedeclaredInaccessibleComponent, ImplicitShared, IndexVarRedefinition,
70+
IncompatibleImplicitInterfaces, BadTypeForTarget)
5871

5972
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
6073
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
@@ -77,8 +90,57 @@ class LanguageFeatureControl {
7790
disable_.set(LanguageFeature::LogicalAbbreviations);
7891
disable_.set(LanguageFeature::XOROperator);
7992
disable_.set(LanguageFeature::OldStyleParameter);
93+
// These warnings are enabled by default, but only because they used
94+
// to be unconditional. TODO: prune this list
95+
warnLanguage_.set(LanguageFeature::ExponentMatchingKindParam);
96+
warnLanguage_.set(LanguageFeature::RedundantAttribute);
97+
warnLanguage_.set(LanguageFeature::SubroutineAndFunctionSpecifics);
98+
warnLanguage_.set(LanguageFeature::EmptySequenceType);
99+
warnLanguage_.set(LanguageFeature::NonSequenceCrayPointee);
100+
warnLanguage_.set(LanguageFeature::BranchIntoConstruct);
101+
warnLanguage_.set(LanguageFeature::BadBranchTarget);
102+
warnLanguage_.set(LanguageFeature::ConvertedArgument);
103+
warnLanguage_.set(LanguageFeature::HollerithPolymorphic);
104+
warnLanguage_.set(LanguageFeature::ListDirectedSize);
105+
warnUsage_.set(UsageWarning::ShortArrayActual);
106+
warnUsage_.set(UsageWarning::FoldingException);
107+
warnUsage_.set(UsageWarning::FoldingAvoidsRuntimeCrash);
108+
warnUsage_.set(UsageWarning::FoldingValueChecks);
109+
warnUsage_.set(UsageWarning::FoldingFailure);
110+
warnUsage_.set(UsageWarning::FoldingLimit);
111+
warnUsage_.set(UsageWarning::Interoperability);
112+
warnUsage_.set(UsageWarning::Bounds);
113+
warnUsage_.set(UsageWarning::Preprocessing);
114+
warnUsage_.set(UsageWarning::Scanning);
115+
warnUsage_.set(UsageWarning::OpenAccUsage);
116+
warnUsage_.set(UsageWarning::ProcPointerCompatibility);
117+
warnUsage_.set(UsageWarning::VoidMold);
118+
warnUsage_.set(UsageWarning::KnownBadImplicitInterface);
119+
warnUsage_.set(UsageWarning::EmptyCase);
120+
warnUsage_.set(UsageWarning::CaseOverflow);
121+
warnUsage_.set(UsageWarning::CUDAUsage);
122+
warnUsage_.set(UsageWarning::IgnoreTKRUsage);
123+
warnUsage_.set(UsageWarning::ExternalInterfaceMismatch);
124+
warnUsage_.set(UsageWarning::DefinedOperatorArgs);
125+
warnUsage_.set(UsageWarning::Final);
126+
warnUsage_.set(UsageWarning::ZeroDoStep);
127+
warnUsage_.set(UsageWarning::UnusedForallIndex);
128+
warnUsage_.set(UsageWarning::OpenMPUsage);
129+
warnUsage_.set(UsageWarning::ModuleFile);
130+
warnUsage_.set(UsageWarning::DataLength);
131+
warnUsage_.set(UsageWarning::IgnoredDirective);
132+
warnUsage_.set(UsageWarning::HomonymousSpecific);
133+
warnUsage_.set(UsageWarning::HomonymousResult);
134+
warnUsage_.set(UsageWarning::IgnoredIntrinsicFunctionType);
135+
warnUsage_.set(UsageWarning::PreviousScalarUse);
136+
warnUsage_.set(UsageWarning::RedeclaredInaccessibleComponent);
137+
warnUsage_.set(UsageWarning::ImplicitShared);
138+
warnUsage_.set(UsageWarning::IndexVarRedefinition);
139+
warnUsage_.set(UsageWarning::IncompatibleImplicitInterfaces);
140+
warnUsage_.set(UsageWarning::BadTypeForTarget);
80141
}
81142
LanguageFeatureControl(const LanguageFeatureControl &) = default;
143+
82144
void Enable(LanguageFeature f, bool yes = true) { disable_.set(f, !yes); }
83145
void EnableWarning(LanguageFeature f, bool yes = true) {
84146
warnLanguage_.set(f, yes);
@@ -88,10 +150,19 @@ class LanguageFeatureControl {
88150
}
89151
void WarnOnAllNonstandard(bool yes = true) { warnAllLanguage_ = yes; }
90152
void WarnOnAllUsage(bool yes = true) { warnAllUsage_ = yes; }
153+
void DisableAllNonstandardWarnings() {
154+
warnAllLanguage_ = false;
155+
warnLanguage_.clear();
156+
}
157+
void DisableAllUsageWarnings() {
158+
warnAllUsage_ = false;
159+
warnUsage_.clear();
160+
}
161+
91162
bool IsEnabled(LanguageFeature f) const { return !disable_.test(f); }
92163
bool ShouldWarn(LanguageFeature f) const {
93164
return (warnAllLanguage_ && f != LanguageFeature::OpenMP &&
94-
f != LanguageFeature::OpenACC) ||
165+
f != LanguageFeature::OpenACC && f != LanguageFeature::CUDA) ||
95166
warnLanguage_.test(f);
96167
}
97168
bool ShouldWarn(UsageWarning w) const {

flang/include/flang/Semantics/tools.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ class LabelEnforce {
634634
void Post(const parser::ErrLabel &errLabel);
635635
void Post(const parser::EndLabel &endLabel);
636636
void Post(const parser::EorLabel &eorLabel);
637-
void checkLabelUse(const parser::Label &labelUsed);
637+
void CheckLabelUse(const parser::Label &labelUsed);
638638

639639
private:
640640
SemanticsContext &context_;

flang/lib/Evaluate/common.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,24 @@ namespace Fortran::evaluate {
1515

1616
void RealFlagWarnings(
1717
FoldingContext &context, const RealFlags &flags, const char *operation) {
18-
if (flags.test(RealFlag::Overflow)) {
19-
context.messages().Say("overflow on %s"_warn_en_US, operation);
20-
}
21-
if (flags.test(RealFlag::DivideByZero)) {
22-
if (std::strcmp(operation, "division") == 0) {
23-
context.messages().Say("division by zero"_warn_en_US);
24-
} else {
25-
context.messages().Say("division by zero on %s"_warn_en_US, operation);
18+
if (context.languageFeatures().ShouldWarn(
19+
common::UsageWarning::FoldingException)) {
20+
if (flags.test(RealFlag::Overflow)) {
21+
context.messages().Say("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("division by zero"_warn_en_US);
26+
} else {
27+
context.messages().Say("division by zero on %s"_warn_en_US, operation);
28+
}
29+
}
30+
if (flags.test(RealFlag::InvalidArgument)) {
31+
context.messages().Say("invalid argument on %s"_warn_en_US, operation);
32+
}
33+
if (flags.test(RealFlag::Underflow)) {
34+
context.messages().Say("underflow on %s"_warn_en_US, operation);
2635
}
27-
}
28-
if (flags.test(RealFlag::InvalidArgument)) {
29-
context.messages().Say("invalid argument on %s"_warn_en_US, operation);
30-
}
31-
if (flags.test(RealFlag::Underflow)) {
32-
context.messages().Say("underflow on %s"_warn_en_US, operation);
3336
}
3437
}
3538

flang/lib/Evaluate/fold-character.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,13 @@ 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-
context.messages().Say(
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);
61+
if (context.languageFeatures().ShouldWarn(
62+
common::UsageWarning::FoldingValueChecks)) {
63+
context.messages().Say(
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+
}
6568
}
6669
return CharacterUtils<KIND>::CHAR(i.ToUInt64());
6770
}));
@@ -103,9 +106,12 @@ Expr<Type<TypeCategory::Character, KIND>> FoldIntrinsicFunction(
103106
static_cast<std::intmax_t>(n));
104107
} else if (static_cast<double>(n) * str.size() >
105108
(1 << 20)) { // sanity limit of 1MiB
106-
context.messages().Say(
107-
"Result of REPEAT() is too large to compute at compilation time (%g characters)"_port_en_US,
108-
static_cast<double>(n) * str.size());
109+
if (context.languageFeatures().ShouldWarn(
110+
common::UsageWarning::FoldingLimit)) {
111+
context.messages().Say(
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+
}
109115
} else {
110116
return Expr<T>{Constant<T>{CharacterUtils<KIND>::REPEAT(str, n)}};
111117
}

flang/lib/Evaluate/fold-complex.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +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 {
32+
} else if (context.languageFeatures().ShouldWarn(
33+
common::UsageWarning::FoldingFailure)) {
3334
context.messages().Say(
3435
"%s(complex(kind=%d)) cannot be folded on host"_warn_en_US, name,
3536
KIND);

flang/lib/Evaluate/fold-implementation.h

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,7 +1686,7 @@ Expr<TO> FoldOperation(
16861686
Convert<TO, FROMCAT> &convert;
16871687
} msvcWorkaround{context, convert};
16881688
return common::visit(
1689-
[&msvcWorkaround](auto &kindExpr) -> Expr<TO> {
1689+
[&msvcWorkaround, &context](auto &kindExpr) -> Expr<TO> {
16901690
using Operand = ResultType<decltype(kindExpr)>;
16911691
// This variable is a workaround for msvc which emits an error when
16921692
// using the FROMCAT template parameter below.
@@ -1698,22 +1698,27 @@ Expr<TO> FoldOperation(
16981698
if constexpr (TO::category == TypeCategory::Integer) {
16991699
if constexpr (FromCat == TypeCategory::Integer) {
17001700
auto converted{Scalar<TO>::ConvertSigned(*value)};
1701-
if (converted.overflow) {
1701+
if (converted.overflow &&
1702+
context.languageFeatures().ShouldWarn(
1703+
common::UsageWarning::FoldingException)) {
17021704
ctx.messages().Say(
17031705
"INTEGER(%d) to INTEGER(%d) conversion overflowed"_warn_en_US,
17041706
Operand::kind, TO::kind);
17051707
}
17061708
return ScalarConstantToExpr(std::move(converted.value));
17071709
} else if constexpr (FromCat == TypeCategory::Real) {
17081710
auto converted{value->template ToInteger<Scalar<TO>>()};
1709-
if (converted.flags.test(RealFlag::InvalidArgument)) {
1710-
ctx.messages().Say(
1711-
"REAL(%d) to INTEGER(%d) conversion: invalid argument"_warn_en_US,
1712-
Operand::kind, TO::kind);
1713-
} else if (converted.flags.test(RealFlag::Overflow)) {
1714-
ctx.messages().Say(
1715-
"REAL(%d) to INTEGER(%d) conversion overflowed"_warn_en_US,
1716-
Operand::kind, TO::kind);
1711+
if (context.languageFeatures().ShouldWarn(
1712+
common::UsageWarning::FoldingException)) {
1713+
if (converted.flags.test(RealFlag::InvalidArgument)) {
1714+
ctx.messages().Say(
1715+
"REAL(%d) to INTEGER(%d) conversion: invalid argument"_warn_en_US,
1716+
Operand::kind, TO::kind);
1717+
} else if (converted.flags.test(RealFlag::Overflow)) {
1718+
ctx.messages().Say(
1719+
"REAL(%d) to INTEGER(%d) conversion overflowed"_warn_en_US,
1720+
Operand::kind, TO::kind);
1721+
}
17171722
}
17181723
return ScalarConstantToExpr(std::move(converted.value));
17191724
}
@@ -1822,7 +1827,9 @@ Expr<T> FoldOperation(FoldingContext &context, Negate<T> &&x) {
18221827
} else if (auto value{GetScalarConstantValue<T>(operand)}) {
18231828
if constexpr (T::category == TypeCategory::Integer) {
18241829
auto negated{value->Negate()};
1825-
if (negated.overflow) {
1830+
if (negated.overflow &&
1831+
context.languageFeatures().ShouldWarn(
1832+
common::UsageWarning::FoldingException)) {
18261833
context.messages().Say(
18271834
"INTEGER(%d) negation overflowed"_warn_en_US, T::kind);
18281835
}
@@ -1862,7 +1869,9 @@ Expr<T> FoldOperation(FoldingContext &context, Add<T> &&x) {
18621869
if (auto folded{OperandsAreConstants(x)}) {
18631870
if constexpr (T::category == TypeCategory::Integer) {
18641871
auto sum{folded->first.AddSigned(folded->second)};
1865-
if (sum.overflow) {
1872+
if (sum.overflow &&
1873+
context.languageFeatures().ShouldWarn(
1874+
common::UsageWarning::FoldingException)) {
18661875
context.messages().Say(
18671876
"INTEGER(%d) addition overflowed"_warn_en_US, T::kind);
18681877
}
@@ -1888,7 +1897,9 @@ Expr<T> FoldOperation(FoldingContext &context, Subtract<T> &&x) {
18881897
if (auto folded{OperandsAreConstants(x)}) {
18891898
if constexpr (T::category == TypeCategory::Integer) {
18901899
auto difference{folded->first.SubtractSigned(folded->second)};
1891-
if (difference.overflow) {
1900+
if (difference.overflow &&
1901+
context.languageFeatures().ShouldWarn(
1902+
common::UsageWarning::FoldingException)) {
18921903
context.messages().Say(
18931904
"INTEGER(%d) subtraction overflowed"_warn_en_US, T::kind);
18941905
}
@@ -1914,7 +1925,9 @@ Expr<T> FoldOperation(FoldingContext &context, Multiply<T> &&x) {
19141925
if (auto folded{OperandsAreConstants(x)}) {
19151926
if constexpr (T::category == TypeCategory::Integer) {
19161927
auto product{folded->first.MultiplySigned(folded->second)};
1917-
if (product.SignedMultiplicationOverflowed()) {
1928+
if (product.SignedMultiplicationOverflowed() &&
1929+
context.languageFeatures().ShouldWarn(
1930+
common::UsageWarning::FoldingException)) {
19181931
context.messages().Say(
19191932
"INTEGER(%d) multiplication overflowed"_warn_en_US, T::kind);
19201933
}
@@ -1959,11 +1972,16 @@ Expr<T> FoldOperation(FoldingContext &context, Divide<T> &&x) {
19591972
if constexpr (T::category == TypeCategory::Integer) {
19601973
auto quotAndRem{folded->first.DivideSigned(folded->second)};
19611974
if (quotAndRem.divisionByZero) {
1962-
context.messages().Say(
1963-
"INTEGER(%d) division by zero"_warn_en_US, T::kind);
1975+
if (context.languageFeatures().ShouldWarn(
1976+
common::UsageWarning::FoldingException)) {
1977+
context.messages().Say(
1978+
"INTEGER(%d) division by zero"_warn_en_US, T::kind);
1979+
}
19641980
return Expr<T>{std::move(x)};
19651981
}
1966-
if (quotAndRem.overflow) {
1982+
if (quotAndRem.overflow &&
1983+
context.languageFeatures().ShouldWarn(
1984+
common::UsageWarning::FoldingException)) {
19671985
context.messages().Say(
19681986
"INTEGER(%d) division overflowed"_warn_en_US, T::kind);
19691987
}
@@ -2004,22 +2022,26 @@ Expr<T> FoldOperation(FoldingContext &context, Power<T> &&x) {
20042022
if (auto folded{OperandsAreConstants(x)}) {
20052023
if constexpr (T::category == TypeCategory::Integer) {
20062024
auto power{folded->first.Power(folded->second)};
2007-
if (power.divisionByZero) {
2008-
context.messages().Say(
2009-
"INTEGER(%d) zero to negative power"_warn_en_US, T::kind);
2010-
} else if (power.overflow) {
2011-
context.messages().Say(
2012-
"INTEGER(%d) power overflowed"_warn_en_US, T::kind);
2013-
} else if (power.zeroToZero) {
2014-
context.messages().Say(
2015-
"INTEGER(%d) 0**0 is not defined"_warn_en_US, T::kind);
2025+
if (context.languageFeatures().ShouldWarn(
2026+
common::UsageWarning::FoldingException)) {
2027+
if (power.divisionByZero) {
2028+
context.messages().Say(
2029+
"INTEGER(%d) zero to negative power"_warn_en_US, T::kind);
2030+
} else if (power.overflow) {
2031+
context.messages().Say(
2032+
"INTEGER(%d) power overflowed"_warn_en_US, T::kind);
2033+
} else if (power.zeroToZero) {
2034+
context.messages().Say(
2035+
"INTEGER(%d) 0**0 is not defined"_warn_en_US, T::kind);
2036+
}
20162037
}
20172038
return Expr<T>{Constant<T>{power.power}};
20182039
} else {
20192040
if (auto callable{GetHostRuntimeWrapper<T, T, T>("pow")}) {
20202041
return Expr<T>{
20212042
Constant<T>{(*callable)(context, folded->first, folded->second)}};
2022-
} else {
2043+
} else if (context.languageFeatures().ShouldWarn(
2044+
common::UsageWarning::FoldingFailure)) {
20232045
context.messages().Say(
20242046
"Power for %s cannot be folded on host"_warn_en_US,
20252047
T{}.AsFortran());
@@ -2103,7 +2125,9 @@ Expr<Type<TypeCategory::Real, KIND>> ToReal(
21032125
CHECK(constant);
21042126
Scalar<Result> real{constant->GetScalarValue().value()};
21052127
From converted{From::ConvertUnsigned(real.RawBits()).value};
2106-
if (original != converted) { // C1601
2128+
if (original != converted &&
2129+
context.languageFeatures().ShouldWarn(
2130+
common::UsageWarning::FoldingValueChecks)) { // C1601
21072131
context.messages().Say(
21082132
"Nonzero bits truncated from BOZ literal constant in REAL intrinsic"_warn_en_US);
21092133
}

0 commit comments

Comments
 (0)