@@ -198,6 +198,7 @@ struct IntrinsicDummyArgument {
198
198
TypePattern typePattern;
199
199
Rank rank{Rank::elemental};
200
200
Optionality optionality{Optionality::required};
201
+ common::Intent intent{common::Intent::In};
201
202
llvm::raw_ostream &Dump (llvm::raw_ostream &) const ;
202
203
};
203
204
@@ -935,68 +936,103 @@ static const SpecificIntrinsicInterface specificIntrinsicFunction[]{
935
936
};
936
937
937
938
static const IntrinsicInterface intrinsicSubroutine[]{
938
- {" cpu_time" , {{" time" , AnyReal, Rank::scalar}}, {}, Rank::elemental,
939
- IntrinsicClass::impureSubroutine},
939
+ {" cpu_time" ,
940
+ {{" time" , AnyReal, Rank::scalar, Optionality::required,
941
+ common::Intent::Out}},
942
+ {}, Rank::elemental, IntrinsicClass::impureSubroutine},
940
943
{" date_and_time" ,
941
- {{" date" , DefaultChar, Rank::scalar, Optionality::optional},
942
- {" time" , DefaultChar, Rank::scalar, Optionality::optional},
943
- {" zone" , DefaultChar, Rank::scalar, Optionality::optional},
944
- {" values" , AnyInt, Rank::vector, Optionality::optional}},
944
+ {{" date" , DefaultChar, Rank::scalar, Optionality::optional,
945
+ common::Intent::Out},
946
+ {" time" , DefaultChar, Rank::scalar, Optionality::optional,
947
+ common::Intent::Out},
948
+ {" zone" , DefaultChar, Rank::scalar, Optionality::optional,
949
+ common::Intent::Out},
950
+ {" values" , AnyInt, Rank::vector, Optionality::optional,
951
+ common::Intent::Out}},
945
952
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
946
953
{" execute_command_line" ,
947
954
{{" command" , DefaultChar, Rank::scalar},
948
955
{" wait" , AnyLogical, Rank::scalar, Optionality::optional},
949
- {" exitstat" , AnyInt, Rank::scalar, Optionality::optional},
950
- {" cmdstat" , AnyInt, Rank::scalar, Optionality::optional},
951
- {" cmdmsg" , DefaultChar, Rank::scalar, Optionality::optional}},
956
+ {" exitstat" , AnyInt, Rank::scalar, Optionality::optional,
957
+ common::Intent::InOut},
958
+ {" cmdstat" , AnyInt, Rank::scalar, Optionality::optional,
959
+ common::Intent::Out},
960
+ {" cmdmsg" , DefaultChar, Rank::scalar, Optionality::optional,
961
+ common::Intent::InOut}},
952
962
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
953
963
{" get_command" ,
954
- {{" command" , DefaultChar, Rank::scalar, Optionality::optional},
955
- {" length" , AnyInt, Rank::scalar, Optionality::optional},
956
- {" status" , AnyInt, Rank::scalar, Optionality::optional},
957
- {" errmsg" , DefaultChar, Rank::scalar, Optionality::optional}},
964
+ {{" command" , DefaultChar, Rank::scalar, Optionality::optional,
965
+ common::Intent::Out},
966
+ {" length" , AnyInt, Rank::scalar, Optionality::optional,
967
+ common::Intent::Out},
968
+ {" status" , AnyInt, Rank::scalar, Optionality::optional,
969
+ common::Intent::Out},
970
+ {" errmsg" , DefaultChar, Rank::scalar, Optionality::optional,
971
+ common::Intent::InOut}},
958
972
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
959
973
{" get_command_argument" ,
960
974
{{" number" , AnyInt, Rank::scalar},
961
- {" value" , DefaultChar, Rank::scalar, Optionality::optional},
962
- {" length" , AnyInt, Rank::scalar, Optionality::optional},
963
- {" status" , AnyInt, Rank::scalar, Optionality::optional},
964
- {" errmsg" , DefaultChar, Rank::scalar, Optionality::optional}},
975
+ {" value" , DefaultChar, Rank::scalar, Optionality::optional,
976
+ common::Intent::Out},
977
+ {" length" , AnyInt, Rank::scalar, Optionality::optional,
978
+ common::Intent::Out},
979
+ {" status" , AnyInt, Rank::scalar, Optionality::optional,
980
+ common::Intent::Out},
981
+ {" errmsg" , DefaultChar, Rank::scalar, Optionality::optional,
982
+ common::Intent::InOut}},
965
983
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
966
984
{" get_environment_variable" ,
967
985
{{" name" , DefaultChar, Rank::scalar},
968
- {" value" , DefaultChar, Rank::scalar, Optionality::optional},
969
- {" length" , AnyInt, Rank::scalar, Optionality::optional},
970
- {" status" , AnyInt, Rank::scalar, Optionality::optional},
986
+ {" value" , DefaultChar, Rank::scalar, Optionality::optional,
987
+ common::Intent::Out},
988
+ {" length" , AnyInt, Rank::scalar, Optionality::optional,
989
+ common::Intent::Out},
990
+ {" status" , AnyInt, Rank::scalar, Optionality::optional,
991
+ common::Intent::Out},
971
992
{" trim_name" , AnyLogical, Rank::scalar, Optionality::optional},
972
- {" errmsg" , DefaultChar, Rank::scalar, Optionality::optional}},
993
+ {" errmsg" , DefaultChar, Rank::scalar, Optionality::optional,
994
+ common::Intent::InOut}},
973
995
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
974
996
{" move_alloc" ,
975
- {{" from" , SameType, Rank::known}, {" to" , SameType, Rank::known},
976
- {" stat" , AnyInt, Rank::scalar, Optionality::optional},
977
- {" errmsg" , DefaultChar, Rank::scalar, Optionality::optional}},
997
+ {{" from" , SameType, Rank::known, Optionality::required,
998
+ common::Intent::InOut},
999
+ {" to" , SameType, Rank::known, Optionality::required,
1000
+ common::Intent::Out},
1001
+ {" stat" , AnyInt, Rank::scalar, Optionality::optional,
1002
+ common::Intent::Out},
1003
+ {" errmsg" , DefaultChar, Rank::scalar, Optionality::optional,
1004
+ common::Intent::InOut}},
978
1005
{}, Rank::elemental, IntrinsicClass::pureSubroutine},
979
1006
{" mvbits" ,
980
1007
{{" from" , SameInt}, {" frompos" , AnyInt}, {" len" , AnyInt},
981
- {" to" , SameInt}, {" topos" , AnyInt}},
1008
+ {" to" , SameInt, Rank::elemental, Optionality::required,
1009
+ common::Intent::Out},
1010
+ {" topos" , AnyInt}},
982
1011
{}, Rank::elemental, IntrinsicClass::elementalSubroutine}, // elemental
983
1012
{" random_init" ,
984
1013
{{" repeatable" , AnyLogical, Rank::scalar},
985
1014
{" image_distinct" , AnyLogical, Rank::scalar}},
986
1015
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
987
- {" random_number" , {{" harvest" , AnyReal, Rank::known}}, {}, Rank::elemental,
988
- IntrinsicClass::impureSubroutine},
1016
+ {" random_number" ,
1017
+ {{" harvest" , AnyReal, Rank::known, Optionality::required,
1018
+ common::Intent::Out}},
1019
+ {}, Rank::elemental, IntrinsicClass::impureSubroutine},
989
1020
{" random_seed" ,
990
- {{" size" , DefaultInt, Rank::scalar, Optionality::optional},
1021
+ {{" size" , DefaultInt, Rank::scalar, Optionality::optional,
1022
+ common::Intent::Out},
991
1023
{" put" , DefaultInt, Rank::vector, Optionality::optional},
992
- {" get" , DefaultInt, Rank::vector, Optionality::optional}},
1024
+ {" get" , DefaultInt, Rank::vector, Optionality::optional,
1025
+ common::Intent::Out}},
993
1026
{}, Rank::elemental,
994
1027
IntrinsicClass::impureSubroutine}, // TODO: at most one argument can be
995
1028
// present
996
1029
{" system_clock" ,
997
- {{" count" , AnyInt, Rank::scalar, Optionality::optional},
998
- {" count_rate" , AnyIntOrReal, Rank::scalar, Optionality::optional},
999
- {" count_max" , AnyInt, Rank::scalar, Optionality::optional}},
1030
+ {{" count" , AnyInt, Rank::scalar, Optionality::optional,
1031
+ common::Intent::Out},
1032
+ {" count_rate" , AnyIntOrReal, Rank::scalar, Optionality::optional,
1033
+ common::Intent::Out},
1034
+ {" count_max" , AnyInt, Rank::scalar, Optionality::optional,
1035
+ common::Intent::Out}},
1000
1036
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
1001
1037
};
1002
1038
@@ -1542,6 +1578,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1542
1578
}
1543
1579
dummyArgs.back ().SetOptional ();
1544
1580
}
1581
+ dummyArgs.back ().SetIntent (d.intent );
1545
1582
}
1546
1583
characteristics::Procedure::Attrs attrs;
1547
1584
if (elementalRank > 0 ) {
@@ -2148,7 +2185,7 @@ IntrinsicProcTable::Implementation::IsSpecificIntrinsicFunction(
2148
2185
for (int j{0 }; j < dummies; ++j) {
2149
2186
characteristics::DummyDataObject dummy{
2150
2187
GetSpecificType (specific.dummy [j].typePattern )};
2151
- dummy.intent = common::Intent::In ;
2188
+ dummy.intent = specific. dummy [j]. intent ;
2152
2189
args.emplace_back (
2153
2190
std::string{specific.dummy [j].keyword }, std::move (dummy));
2154
2191
}
@@ -2230,7 +2267,8 @@ llvm::raw_ostream &IntrinsicDummyArgument::Dump(llvm::raw_ostream &o) const {
2230
2267
o << keyword << ' =' ;
2231
2268
}
2232
2269
return typePattern.Dump (o)
2233
- << ' ' << EnumToString (rank) << ' ' << EnumToString (optionality);
2270
+ << ' ' << EnumToString (rank) << ' ' << EnumToString (optionality)
2271
+ << EnumToString (intent);
2234
2272
}
2235
2273
2236
2274
llvm::raw_ostream &IntrinsicInterface::Dump (llvm::raw_ostream &o) const {
@@ -2273,4 +2311,15 @@ llvm::raw_ostream &IntrinsicProcTable::Implementation::Dump(
2273
2311
llvm::raw_ostream &IntrinsicProcTable::Dump (llvm::raw_ostream &o) const {
2274
2312
return impl_->Dump (o);
2275
2313
}
2314
+
2315
+ // In general C846 prohibits allocatable coarrays to be passed to INTENT(OUT)
2316
+ // dummy arguments. This rule does not apply to intrinsics in general.
2317
+ // Some intrinsic explicitly allow coarray allocatable in their description.
2318
+ // It is assumed that unless explicitly allowed for an intrinsic,
2319
+ // this is forbidden.
2320
+ // Since there are very few intrinsic identified that allow this, they are
2321
+ // listed here instead of adding a field in the table.
2322
+ bool AcceptsIntentOutAllocatableCoarray (const std::string &intrinsic) {
2323
+ return intrinsic == " move_alloc" ;
2324
+ }
2276
2325
} // namespace Fortran::evaluate
0 commit comments