@@ -793,16 +793,11 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
793793 DefaultingKIND},
794794 KINDInt},
795795 {" __builtin_ieee_is_nan" , {{" a" , AnyFloating}}, DefaultLogical},
796- {" __builtin_ieee_is_normal" , {{" a" , AnyFloating}}, DefaultLogical},
797796 {" __builtin_ieee_is_negative" , {{" a" , AnyFloating}}, DefaultLogical},
797+ {" __builtin_ieee_is_normal" , {{" a" , AnyFloating}}, DefaultLogical},
798798 {" __builtin_ieee_next_after" , {{" x" , SameReal}, {" y" , AnyReal}}, SameReal},
799799 {" __builtin_ieee_next_down" , {{" x" , SameReal}}, SameReal},
800800 {" __builtin_ieee_next_up" , {{" x" , SameReal}}, SameReal},
801- {" __builtin_ieee_selected_real_kind" , // alias for selected_real_kind
802- {{" p" , AnyInt, Rank::scalar},
803- {" r" , AnyInt, Rank::scalar, Optionality::optional},
804- {" radix" , AnyInt, Rank::scalar, Optionality::optional}},
805- DefaultInt, Rank::scalar, IntrinsicClass::transformationalFunction},
806801 {" __builtin_ieee_support_datatype" ,
807802 {{" x" , AnyReal, Rank::elemental, Optionality::optional}},
808803 DefaultLogical},
@@ -839,7 +834,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
839834// LCOBOUND, UCOBOUND, FAILED_IMAGES, IMAGE_INDEX,
840835// STOPPED_IMAGES, COSHAPE
841836// TODO: Non-standard intrinsic functions
842- // AND, OR, XOR, LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT,
837+ // LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT,
843838// COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT,
844839// QCMPLX, QEXT, QFLOAT, QREAL, DNUM,
845840// INUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN,
@@ -851,6 +846,15 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
851846// LOC, probably others
852847// TODO: Optionally warn on operand promotion extension
853848
849+ // Aliases for a few generic intrinsic functions for legacy
850+ // compatibility and builtins.
851+ static const std::pair<const char *, const char *> genericAlias[]{
852+ {" and" , " iand" },
853+ {" or" , " ior" },
854+ {" xor" , " ieor" },
855+ {" __builtin_ieee_selected_real_kind" , " selected_real_kind" },
856+ };
857+
854858// The following table contains the intrinsic functions listed in
855859// Tables 16.2 and 16.3 in Fortran 2018. The "unrestricted" functions
856860// in Table 16.2 can be used as actual arguments, PROCEDURE() interfaces,
@@ -1897,6 +1901,10 @@ class IntrinsicProcTable::Implementation {
18971901 for (const IntrinsicInterface &f : genericIntrinsicFunction) {
18981902 genericFuncs_.insert (std::make_pair (std::string{f.name }, &f));
18991903 }
1904+ for (const std::pair<const char *, const char *> &a : genericAlias) {
1905+ aliases_.insert (
1906+ std::make_pair (std::string{a.first }, std::string{a.second }));
1907+ }
19001908 for (const SpecificIntrinsicInterface &f : specificIntrinsicFunction) {
19011909 specificFuncs_.insert (std::make_pair (std::string{f.name }, &f));
19021910 }
@@ -1929,16 +1937,22 @@ class IntrinsicProcTable::Implementation {
19291937 SpecificCall HandleNull (ActualArguments &, FoldingContext &) const ;
19301938 std::optional<SpecificCall> HandleC_F_Pointer (
19311939 ActualArguments &, FoldingContext &) const ;
1940+ const std::string &ResolveAlias (const std::string &name) const {
1941+ auto iter{aliases_.find (name)};
1942+ return iter == aliases_.end () ? name : iter->second ;
1943+ }
19321944
19331945 common::IntrinsicTypeDefaultKinds defaults_;
19341946 std::multimap<std::string, const IntrinsicInterface *> genericFuncs_;
19351947 std::multimap<std::string, const SpecificIntrinsicInterface *> specificFuncs_;
19361948 std::multimap<std::string, const IntrinsicInterface *> subroutines_;
19371949 const semantics::Scope *builtinsScope_{nullptr };
1950+ std::map<std::string, std::string> aliases_;
19381951};
19391952
19401953bool IntrinsicProcTable::Implementation::IsIntrinsicFunction (
1941- const std::string &name) const {
1954+ const std::string &name0) const {
1955+ const std::string &name{ResolveAlias (name0)};
19421956 auto specificRange{specificFuncs_.equal_range (name)};
19431957 if (specificRange.first != specificRange.second ) {
19441958 return true ;
@@ -2427,9 +2441,11 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
24272441 return std::nullopt ;
24282442 }};
24292443
2430- // Probe the generic intrinsic function table first.
2444+ // Probe the generic intrinsic function table first; allow for
2445+ // the use of a legacy alias.
24312446 parser::Messages genericBuffer;
2432- auto genericRange{genericFuncs_.equal_range (call.name )};
2447+ const std::string &name{ResolveAlias (call.name )};
2448+ auto genericRange{genericFuncs_.equal_range (name)};
24332449 for (auto iter{genericRange.first }; iter != genericRange.second ; ++iter) {
24342450 if (auto specificCall{
24352451 matchOrBufferMessages (*iter->second , genericBuffer)}) {
0 commit comments