Skip to content

Commit 6d2b23c

Browse files
authored
[flang] Fix crash in error recovery (bad binding) (#92800)
A type-bound procedure that's bound to a name that isn't a procedure is caught as an error, but can also lead to a crash in compatibility checking later. Make that code more robust to failure. Fixes #92678.
1 parent 63e8c0a commit 6d2b23c

File tree

3 files changed

+23
-16
lines changed

3 files changed

+23
-16
lines changed

flang/include/flang/Evaluate/characteristics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ struct Procedure {
386386
bool HasExplicitInterface() const {
387387
return !attrs.test(Attr::ImplicitInterface);
388388
}
389-
int FindPassIndex(std::optional<parser::CharBlock>) const;
389+
std::optional<int> FindPassIndex(std::optional<parser::CharBlock>) const;
390390
bool CanBeCalledViaImplicitInterface(std::string *whyNot = nullptr) const;
391391
bool CanOverride(const Procedure &, std::optional<int> passIndex) const;
392392
bool IsCompatibleWith(const Procedure &, bool ignoreImplicitVsExplicit,

flang/lib/Evaluate/characteristics.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,16 +1333,21 @@ bool Procedure::IsCompatibleWith(const Procedure &actual,
13331333
return false;
13341334
}
13351335

1336-
int Procedure::FindPassIndex(std::optional<parser::CharBlock> name) const {
1336+
std::optional<int> Procedure::FindPassIndex(
1337+
std::optional<parser::CharBlock> name) const {
13371338
int argCount{static_cast<int>(dummyArguments.size())};
1338-
int index{0};
13391339
if (name) {
1340-
while (index < argCount && *name != dummyArguments[index].name.c_str()) {
1341-
++index;
1340+
for (int index{0}; index < argCount; ++index) {
1341+
if (*name == dummyArguments[index].name.c_str()) {
1342+
return index;
1343+
}
13421344
}
1345+
return std::nullopt;
1346+
} else if (argCount > 0) {
1347+
return 0;
1348+
} else {
1349+
return std::nullopt;
13431350
}
1344-
CHECK(index < argCount);
1345-
return index;
13461351
}
13471352

13481353
bool Procedure::CanOverride(

flang/lib/Semantics/check-declarations.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2430,16 +2430,18 @@ void CheckHelper::CheckProcBinding(
24302430
"A NOPASS type-bound procedure and its override must have identical interfaces"_err_en_US);
24312431
}
24322432
} else if (!context_.HasError(binding.symbol())) {
2433-
int passIndex{bindingChars->FindPassIndex(binding.passName())};
2434-
int overriddenPassIndex{
2433+
auto passIndex{bindingChars->FindPassIndex(binding.passName())};
2434+
auto overriddenPassIndex{
24352435
overriddenChars->FindPassIndex(overriddenBinding->passName())};
2436-
if (passIndex != overriddenPassIndex) {
2437-
SayWithDeclaration(*overridden,
2438-
"A type-bound procedure and its override must use the same PASS argument"_err_en_US);
2439-
} else if (!bindingChars->CanOverride(
2440-
*overriddenChars, passIndex)) {
2441-
SayWithDeclaration(*overridden,
2442-
"A type-bound procedure and its override must have compatible interfaces"_err_en_US);
2436+
if (passIndex && overriddenPassIndex) {
2437+
if (*passIndex != *overriddenPassIndex) {
2438+
SayWithDeclaration(*overridden,
2439+
"A type-bound procedure and its override must use the same PASS argument"_err_en_US);
2440+
} else if (!bindingChars->CanOverride(
2441+
*overriddenChars, passIndex)) {
2442+
SayWithDeclaration(*overridden,
2443+
"A type-bound procedure and its override must have compatible interfaces"_err_en_US);
2444+
}
24432445
}
24442446
}
24452447
}

0 commit comments

Comments
 (0)