Skip to content

Commit 14b90d1

Browse files
committed
[flang] Fix generic resolution case
Don't try to convert INTEGER argument expressions to the kind of the dummy argument when performing generic resolution; specific procedures may be distinguished only by their kinds. Differential Revision: https://reviews.llvm.org/D112240
1 parent b8452db commit 14b90d1

File tree

4 files changed

+25
-15
lines changed

4 files changed

+25
-15
lines changed

flang/docs/Extensions.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ accepted if enabled by command-line options.
3131
This conversion allows the results of the intrinsics like
3232
`SIZE` that (as mentioned below) may return non-default
3333
`INTEGER` results by default to be passed. A warning is
34-
emitted when truncation is possible.
34+
emitted when truncation is possible. These conversions
35+
are not applied in calls to non-intrinsic generic procedures.
3536
* We are not strict on the contents of `BLOCK DATA` subprograms
3637
so long as they contain no executable code, no internal subprograms,
3738
and allocate no storage outside a named `COMMON` block. (C1415)

flang/lib/Semantics/check-call.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,15 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
145145
const std::string &dummyName, evaluate::Expr<evaluate::SomeType> &actual,
146146
characteristics::TypeAndShape &actualType, bool isElemental,
147147
evaluate::FoldingContext &context, const Scope *scope,
148-
const evaluate::SpecificIntrinsic *intrinsic) {
148+
const evaluate::SpecificIntrinsic *intrinsic,
149+
bool allowIntegerConversions) {
149150

150151
// Basic type & rank checking
151152
parser::ContextualMessages &messages{context.messages()};
152153
PadShortCharacterActual(actual, dummy.type, actualType, context, messages);
153-
ConvertIntegerActual(actual, dummy.type, actualType, messages);
154+
if (allowIntegerConversions) {
155+
ConvertIntegerActual(actual, dummy.type, actualType, messages);
156+
}
154157
bool typesCompatible{dummy.type.type().IsTkCompatibleWith(actualType.type())};
155158
if (typesCompatible) {
156159
if (isElemental) {
@@ -631,7 +634,8 @@ static void CheckProcedureArg(evaluate::ActualArgument &arg,
631634
static void CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
632635
const characteristics::DummyArgument &dummy,
633636
const characteristics::Procedure &proc, evaluate::FoldingContext &context,
634-
const Scope *scope, const evaluate::SpecificIntrinsic *intrinsic) {
637+
const Scope *scope, const evaluate::SpecificIntrinsic *intrinsic,
638+
bool allowIntegerConversions) {
635639
auto &messages{context.messages()};
636640
std::string dummyName{"dummy argument"};
637641
if (!dummy.name.empty()) {
@@ -646,7 +650,8 @@ static void CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
646650
arg.set_dummyIntent(object.intent);
647651
bool isElemental{object.type.Rank() == 0 && proc.IsElemental()};
648652
CheckExplicitDataArg(object, dummyName, *expr, *type,
649-
isElemental, context, scope, intrinsic);
653+
isElemental, context, scope, intrinsic,
654+
allowIntegerConversions);
650655
} else if (object.type.type().IsTypelessIntrinsicArgument() &&
651656
IsBOZLiteral(*expr)) {
652657
// ok
@@ -779,7 +784,8 @@ static bool CheckElementalConformance(parser::ContextualMessages &messages,
779784
static parser::Messages CheckExplicitInterface(
780785
const characteristics::Procedure &proc, evaluate::ActualArguments &actuals,
781786
const evaluate::FoldingContext &context, const Scope *scope,
782-
const evaluate::SpecificIntrinsic *intrinsic) {
787+
const evaluate::SpecificIntrinsic *intrinsic,
788+
bool allowIntegerConversions) {
783789
parser::Messages buffer;
784790
parser::ContextualMessages messages{context.messages().at(), &buffer};
785791
RearrangeArguments(proc, actuals, messages);
@@ -789,8 +795,8 @@ static parser::Messages CheckExplicitInterface(
789795
for (auto &actual : actuals) {
790796
const auto &dummy{proc.dummyArguments.at(index++)};
791797
if (actual) {
792-
CheckExplicitInterfaceArg(
793-
*actual, dummy, proc, localContext, scope, intrinsic);
798+
CheckExplicitInterfaceArg(*actual, dummy, proc, localContext, scope,
799+
intrinsic, allowIntegerConversions);
794800
} else if (!dummy.IsOptional()) {
795801
if (dummy.name.empty()) {
796802
messages.Say(
@@ -815,13 +821,15 @@ static parser::Messages CheckExplicitInterface(
815821
parser::Messages CheckExplicitInterface(const characteristics::Procedure &proc,
816822
evaluate::ActualArguments &actuals, const evaluate::FoldingContext &context,
817823
const Scope &scope, const evaluate::SpecificIntrinsic *intrinsic) {
818-
return CheckExplicitInterface(proc, actuals, context, &scope, intrinsic);
824+
return CheckExplicitInterface(
825+
proc, actuals, context, &scope, intrinsic, true);
819826
}
820827

821828
bool CheckInterfaceForGeneric(const characteristics::Procedure &proc,
822-
evaluate::ActualArguments &actuals,
823-
const evaluate::FoldingContext &context) {
824-
return !CheckExplicitInterface(proc, actuals, context, nullptr, nullptr)
829+
evaluate::ActualArguments &actuals, const evaluate::FoldingContext &context,
830+
bool allowIntegerConversions) {
831+
return !CheckExplicitInterface(
832+
proc, actuals, context, nullptr, nullptr, allowIntegerConversions)
825833
.AnyFatalError();
826834
}
827835

flang/lib/Semantics/check-call.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ parser::Messages CheckExplicitInterface(
4545

4646
// Checks actual arguments for the purpose of resolving a generic interface.
4747
bool CheckInterfaceForGeneric(const evaluate::characteristics::Procedure &,
48-
evaluate::ActualArguments &, const evaluate::FoldingContext &);
48+
evaluate::ActualArguments &, const evaluate::FoldingContext &,
49+
bool allowIntegerConversions = false);
4950
} // namespace Fortran::semantics
5051
#endif

flang/lib/Semantics/expression.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,8 +2021,8 @@ std::pair<const Symbol *, bool> ExpressionAnalyzer::ResolveGeneric(
20212021
continue;
20222022
}
20232023
}
2024-
if (semantics::CheckInterfaceForGeneric(
2025-
*procedure, localActuals, GetFoldingContext()) &&
2024+
if (semantics::CheckInterfaceForGeneric(*procedure, localActuals,
2025+
GetFoldingContext(), false /* no integer conversions */) &&
20262026
CheckCompatibleArguments(*procedure, localActuals)) {
20272027
if ((procedure->IsElemental() && elemental) ||
20282028
(!procedure->IsElemental() && nonElemental)) {

0 commit comments

Comments
 (0)