Skip to content

Commit 35e8624

Browse files
authored
[flang] Silence impossible error about SMP interface incompatibility (#112054)
It is possible for the compiler to emit an impossible error message about dummy argument character length incompatibility in the case of a MODULE SUBROUTINE or FUNCTION defined later in a submodule with MODULE PROCEDURE, when the character length is defined by USE association in its interface. The checking for separate module procedure interface compatibility needs to use a more flexible check than just operator== on a semantics::ParamValue.
1 parent a70ffe7 commit 35e8624

File tree

6 files changed

+53
-4
lines changed

6 files changed

+53
-4
lines changed

flang/include/flang/Evaluate/tools.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,8 +1252,12 @@ class ArrayConstantBoundChanger {
12521252
// Predicate: should two expressions be considered identical for the purposes
12531253
// of determining whether two procedure interfaces are compatible, modulo
12541254
// naming of corresponding dummy arguments?
1255-
std::optional<bool> AreEquivalentInInterface(
1255+
template <typename T>
1256+
std::optional<bool> AreEquivalentInInterface(const Expr<T> &, const Expr<T> &);
1257+
extern template std::optional<bool> AreEquivalentInInterface<SubscriptInteger>(
12561258
const Expr<SubscriptInteger> &, const Expr<SubscriptInteger> &);
1259+
extern template std::optional<bool> AreEquivalentInInterface<SomeInteger>(
1260+
const Expr<SomeInteger> &, const Expr<SomeInteger> &);
12571261

12581262
bool CheckForCoindexedObject(parser::ContextualMessages &,
12591263
const std::optional<ActualArgument> &, const std::string &procName,

flang/include/flang/Semantics/type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class ParamValue {
110110
return category_ == that.category_ && expr_ == that.expr_;
111111
}
112112
bool operator!=(const ParamValue &that) const { return !(*this == that); }
113+
bool IsEquivalentInInterface(const ParamValue &) const;
113114
std::string AsFortran() const;
114115

115116
private:

flang/lib/Evaluate/tools.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,8 +1320,10 @@ std::optional<Expr<SomeType>> HollerithToBOZ(FoldingContext &context,
13201320

13211321
// Extracts a whole symbol being used as a bound of a dummy argument,
13221322
// possibly wrapped with parentheses or MAX(0, ...).
1323+
// Works with any integer expression.
1324+
template <typename T> const Symbol *GetBoundSymbol(const Expr<T> &);
13231325
template <int KIND>
1324-
static const Symbol *GetBoundSymbol(
1326+
const Symbol *GetBoundSymbol(
13251327
const Expr<Type<TypeCategory::Integer, KIND>> &expr) {
13261328
using T = Type<TypeCategory::Integer, KIND>;
13271329
return common::visit(
@@ -1358,9 +1360,15 @@ static const Symbol *GetBoundSymbol(
13581360
},
13591361
expr.u);
13601362
}
1363+
template <>
1364+
const Symbol *GetBoundSymbol<SomeInteger>(const Expr<SomeInteger> &expr) {
1365+
return common::visit(
1366+
[](const auto &kindExpr) { return GetBoundSymbol(kindExpr); }, expr.u);
1367+
}
13611368

1369+
template <typename T>
13621370
std::optional<bool> AreEquivalentInInterface(
1363-
const Expr<SubscriptInteger> &x, const Expr<SubscriptInteger> &y) {
1371+
const Expr<T> &x, const Expr<T> &y) {
13641372
auto xVal{ToInt64(x)};
13651373
auto yVal{ToInt64(y)};
13661374
if (xVal && yVal) {
@@ -1394,6 +1402,10 @@ std::optional<bool> AreEquivalentInInterface(
13941402
return std::nullopt; // not sure
13951403
}
13961404
}
1405+
template std::optional<bool> AreEquivalentInInterface<SubscriptInteger>(
1406+
const Expr<SubscriptInteger> &, const Expr<SubscriptInteger> &);
1407+
template std::optional<bool> AreEquivalentInInterface<SomeInteger>(
1408+
const Expr<SomeInteger> &, const Expr<SomeInteger> &);
13971409

13981410
bool CheckForCoindexedObject(parser::ContextualMessages &messages,
13991411
const std::optional<ActualArgument> &arg, const std::string &procName,

flang/lib/Evaluate/type.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,10 @@ static bool AreSameDerivedType(
518518

519519
bool DynamicType::IsEquivalentTo(const DynamicType &that) const {
520520
return category_ == that.category_ && kind_ == that.kind_ &&
521-
PointeeComparison(charLengthParamValue_, that.charLengthParamValue_) &&
521+
(charLengthParamValue_ == that.charLengthParamValue_ ||
522+
(charLengthParamValue_ && that.charLengthParamValue_ &&
523+
charLengthParamValue_->IsEquivalentInInterface(
524+
*that.charLengthParamValue_))) &&
522525
knownLength().has_value() == that.knownLength().has_value() &&
523526
(!knownLength() || *knownLength() == *that.knownLength()) &&
524527
AreSameDerivedType(derived_, that.derived_);

flang/lib/Semantics/type.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,12 @@ void ParamValue::SetExplicit(SomeIntExpr &&x) {
758758
expr_ = std::move(x);
759759
}
760760

761+
bool ParamValue::IsEquivalentInInterface(const ParamValue &that) const {
762+
return (category_ == that.category_ &&
763+
expr_.has_value() == that.expr_.has_value() &&
764+
(!expr_ || evaluate::AreEquivalentInInterface(*expr_, *that.expr_)));
765+
}
766+
761767
std::string ParamValue::AsFortran() const {
762768
switch (category_) {
763769
SWITCH_COVERS_ALL_CASES

flang/test/Semantics/smp-def01.f90

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
!RUN: %flang -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
2+
!Ensure no bogus error message about incompatible character length
3+
!CHECK-NOT: error
4+
5+
module m1
6+
integer :: n = 1
7+
end
8+
9+
module m2
10+
interface
11+
module subroutine s(a,b)
12+
use m1
13+
character(n) :: a
14+
character(n) :: b
15+
end
16+
end interface
17+
end
18+
19+
submodule(m2) m2s1
20+
contains
21+
module procedure s
22+
end
23+
end

0 commit comments

Comments
 (0)