diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -93,8 +93,10 @@ * 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) diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h --- a/flang/include/flang/Common/Fortran-features.h +++ b/flang/include/flang/Common/Fortran-features.h @@ -30,7 +30,7 @@ EquivalenceNumericWithCharacter, AdditionalIntrinsics, AnonymousParents, OldLabelDoEndStatements, LogicalIntegerAssignment, EmptySourceFile, ProgramReturn, ImplicitNoneTypeNever, ImplicitNoneTypeAlways, - ForwardRefDummyImplicitNone, OpenAccessAppend) + ForwardRefDummyImplicitNone, OpenAccessAppend, BOZAsDefaultInteger) using LanguageFeatures = EnumSet; diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -1229,6 +1229,19 @@ if (!x) { return; } + if (!type_) { + if (auto *boz{std::get_if(&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( + exprAnalyzer_.GetDefaultKind(TypeCategory::Integer), + std::move(*boz))); + } + } if (auto dyType{x->GetType()}) { DynamicTypeWithLength xType{*dyType}; if (Expr * charExpr{UnwrapExpr>(*x)}) { @@ -3334,7 +3347,7 @@ } // 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(