[flang] Accept BOZ in array constructors w/o types

As a benign extension common to other Fortran compilers,
accept BOZ literals in array constructors w/o explicit
types, treating them as integers.

Differential Revision: https://reviews.llvm.org/D103569
This commit is contained in:
peter klausler 2021-06-02 17:02:43 -07:00
parent cd9e1a020c
commit e7a53f1e04
3 changed files with 19 additions and 4 deletions

View file

@ -93,8 +93,10 @@ accepted if enabled by command-line options.
* BOZ literals can be used as INTEGER values in contexts where the type is
unambiguous: the right hand sides of assigments and initializations
of INTEGER entities, and as actual arguments to a few intrinsic functions
(ACHAR, BTEST, CHAR). But they cannot be used if the type would not
be known (e.g., `IAND(X'1',X'2')`).
(ACHAR, BTEST, CHAR). BOZ literals are interpreted as default INTEGER
when they appear as the first items of array constructors with no
explicit type. Otherwise, they generally cannot be used if the type would
not be known (e.g., `IAND(X'1',X'2')`).
* BOZ literals can also be used as REAL values in some contexts where the
type is unambiguous, such as initializations of REAL parameters.
* EQUIVALENCE of numeric and character sequences (a ubiquitous extension)

View file

@ -30,7 +30,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
EquivalenceNumericWithCharacter, AdditionalIntrinsics, AnonymousParents,
OldLabelDoEndStatements, LogicalIntegerAssignment, EmptySourceFile,
ProgramReturn, ImplicitNoneTypeNever, ImplicitNoneTypeAlways,
ForwardRefDummyImplicitNone, OpenAccessAppend)
ForwardRefDummyImplicitNone, OpenAccessAppend, BOZAsDefaultInteger)
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;

View file

@ -1229,6 +1229,19 @@ void ArrayConstructorContext::Push(MaybeExpr &&x) {
if (!x) {
return;
}
if (!type_) {
if (auto *boz{std::get_if<BOZLiteralConstant>(&x->u)}) {
// Treat an array constructor of BOZ as if default integer.
if (exprAnalyzer_.context().ShouldWarn(
common::LanguageFeature::BOZAsDefaultInteger)) {
exprAnalyzer_.Say(
"BOZ literal in array constructor without explicit type is assumed to be default INTEGER"_en_US);
}
x = AsGenericExpr(ConvertToKind<TypeCategory::Integer>(
exprAnalyzer_.GetDefaultKind(TypeCategory::Integer),
std::move(*boz)));
}
}
if (auto dyType{x->GetType()}) {
DynamicTypeWithLength xType{*dyType};
if (Expr<SomeCharacter> * charExpr{UnwrapExpr<Expr<SomeCharacter>>(*x)}) {
@ -3334,7 +3347,7 @@ int ArgumentAnalyzer::GetRank(std::size_t i) const {
}
// If the argument at index i is a BOZ literal, convert its type to match the
// otherType. It it's REAL convert to REAL, otherwise convert to INTEGER.
// otherType. If it's REAL convert to REAL, otherwise convert to INTEGER.
// Note that IBM supports comparing BOZ literals to CHARACTER operands. That
// is not currently supported.
void ArgumentAnalyzer::ConvertBOZ(