Skip to content

Commit 69f3844

Browse files
authored
[flang] Extension: TRANSFER(boz, integer or real scalar) (#147604)
Interpret TRANSFER(SOURCE=BOZ literal, MOLD=integer or real scalar) as if it had been a reference to the standard INT or REAL intrinsic functions, for which a BOZ literal is an acceptable argument, with a warning about non-conformance. It's a needless extension that has somehow crept into some other compilers and real applications.
1 parent 4dceb25 commit 69f3844

File tree

6 files changed

+43
-1
lines changed

6 files changed

+43
-1
lines changed

flang/docs/Extensions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ end
252252
the type resolution of such BOZ literals usages is highly non portable).
253253
* BOZ literals can also be used as REAL values in some contexts where the
254254
type is unambiguous, such as initializations of REAL parameters.
255+
* `TRANSFER(boz, MOLD=integer or real scalar)` is accepted as an alternate
256+
spelling of `INT(boz, KIND=kind(mold))` or `REAL(boz, KIND=kind(mold))`.
255257
* EQUIVALENCE of numeric and character sequences (a ubiquitous extension),
256258
as well as of sequences of non-default kinds of numeric types
257259
with each other.

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
5555
SavedLocalInSpecExpr, PrintNamelist, AssumedRankPassedToNonAssumedRank,
5656
IgnoreIrrelevantAttributes, Unsigned, AmbiguousStructureConstructor,
5757
ContiguousOkForSeqAssociation, ForwardRefExplicitTypeDummy,
58-
InaccessibleDeferredOverride, CudaWarpMatchFunction, DoConcurrentOffload)
58+
InaccessibleDeferredOverride, CudaWarpMatchFunction, DoConcurrentOffload,
59+
TransferBOZ)
5960

6061
// Portability and suspicious usage warnings
6162
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,

flang/lib/Evaluate/fold.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,16 @@ std::optional<Expr<SomeType>> FoldTransfer(
287287
CHECK(status == InitialImage::NotAConstant);
288288
}
289289
}
290+
} else if (source && moldType) {
291+
if (const auto *boz{std::get_if<BOZLiteralConstant>(&source->u)}) {
292+
// TRANSFER(BOZ, MOLD=integer or real) extension
293+
if (context.languageFeatures().ShouldWarn(
294+
common::LanguageFeature::TransferBOZ)) {
295+
context.messages().Say(common::LanguageFeature::TransferBOZ,
296+
"TRANSFER(BOZ literal) is not standard"_port_en_US);
297+
}
298+
return Fold(context, ConvertToType(*moldType, Expr<SomeType>{*boz}));
299+
}
290300
}
291301
return std::nullopt;
292302
}

flang/lib/Evaluate/intrinsics.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,15 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
10151015
{"mold", SameType, Rank::anyOrAssumedRank},
10161016
{"size", AnyInt, Rank::scalar}},
10171017
SameType, Rank::vector, IntrinsicClass::transformationalFunction},
1018+
// TRANSFER(BOZ, MOLD=integer or real scalar) extension
1019+
{"transfer",
1020+
{{"source", AnyNumeric, Rank::elementalOrBOZ},
1021+
{"mold", SameInt, Rank::scalar}},
1022+
SameInt, Rank::scalar, IntrinsicClass::transformationalFunction},
1023+
{"transfer",
1024+
{{"source", AnyNumeric, Rank::elementalOrBOZ},
1025+
{"mold", SameReal, Rank::scalar}},
1026+
SameReal, Rank::scalar, IntrinsicClass::transformationalFunction},
10181027
{"transpose", {{"matrix", SameType, Rank::matrix}}, SameType, Rank::matrix,
10191028
IntrinsicClass::transformationalFunction},
10201029
{"trim", {{"string", SameCharNoLen, Rank::scalar}}, SameCharNoLen,

flang/lib/Support/Fortran-features.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ LanguageFeatureControl::LanguageFeatureControl() {
103103
warnLanguage_.set(LanguageFeature::ListDirectedSize);
104104
warnLanguage_.set(LanguageFeature::IgnoreIrrelevantAttributes);
105105
warnLanguage_.set(LanguageFeature::AmbiguousStructureConstructor);
106+
warnLanguage_.set(LanguageFeature::TransferBOZ);
106107
warnUsage_.set(UsageWarning::ShortArrayActual);
107108
warnUsage_.set(UsageWarning::FoldingException);
108109
warnUsage_.set(UsageWarning::FoldingAvoidsRuntimeCrash);

flang/test/Evaluate/transfer-boz.f90

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
2+
3+
!CHECK: portability: TRANSFER(BOZ literal) is not standard [-Wtransfer-boz]
4+
!CHECK: portability: TRANSFER(BOZ literal) is not standard [-Wtransfer-boz]
5+
!CHECK: portability: TRANSFER(BOZ literal) is not standard [-Wtransfer-boz]
6+
!CHECK: portability: TRANSFER(BOZ literal) is not standard [-Wtransfer-boz]
7+
!CHECK: portability: TRANSFER(BOZ literal) is not standard [-Wtransfer-boz]
8+
!CHECK: PRINT *, -17_1
9+
!CHECK: PRINT *, -16657_2
10+
!CHECK: PRINT *, -559038737_4
11+
!CHECK: PRINT *, -6.259853398707798016e18_4
12+
!CHECK: PRINT *, 1.8457939563190925445492984919045437485528002903297587499184927815557801644025850059853181797614625558939883606558067941052215743386077465406508281130260792904117042434297523782789810991060595088402505831985608687099349932384478542748214418349497866218005870896526832696740683567118136284392505567470522678176873737470272665943917715636680452977840047387616237048162886116765806372690690621665407240253312632381089695794498069551496558727944808752442655077077609749137334421734380446229972733723471196114034171513283476953482396960122117078210644171413215132537631249069125441199719426016512325803207900875869312966829207468856964517085119314095898691593840972164432952065765882286023532502465793032567186884340163939544586513274992967126308940351009368896484375e-314_8
13+
14+
print *, transfer(z'deadbeef', 1_1)
15+
print *, transfer(z'deadbeef', 1_2)
16+
print *, transfer(z'deadbeef', 1_4)
17+
print *, transfer(z'deadbeef', 1._4)
18+
print *, transfer(z'deadbeef', 1._8)
19+
end

0 commit comments

Comments
 (0)