Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion flang/include/flang/Evaluate/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -1252,8 +1252,12 @@ class ArrayConstantBoundChanger {
// Predicate: should two expressions be considered identical for the purposes
// of determining whether two procedure interfaces are compatible, modulo
// naming of corresponding dummy arguments?
std::optional<bool> AreEquivalentInInterface(
template <typename T>
std::optional<bool> AreEquivalentInInterface(const Expr<T> &, const Expr<T> &);
extern template std::optional<bool> AreEquivalentInInterface<SubscriptInteger>(
const Expr<SubscriptInteger> &, const Expr<SubscriptInteger> &);
extern template std::optional<bool> AreEquivalentInInterface<SomeInteger>(
const Expr<SomeInteger> &, const Expr<SomeInteger> &);

bool CheckForCoindexedObject(parser::ContextualMessages &,
const std::optional<ActualArgument> &, const std::string &procName,
Expand Down
1 change: 1 addition & 0 deletions flang/include/flang/Semantics/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class ParamValue {
return category_ == that.category_ && expr_ == that.expr_;
}
bool operator!=(const ParamValue &that) const { return !(*this == that); }
bool IsEquivalentInInterface(const ParamValue &) const;
std::string AsFortran() const;

private:
Expand Down
16 changes: 14 additions & 2 deletions flang/lib/Evaluate/tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1320,8 +1320,10 @@ std::optional<Expr<SomeType>> HollerithToBOZ(FoldingContext &context,

// Extracts a whole symbol being used as a bound of a dummy argument,
// possibly wrapped with parentheses or MAX(0, ...).
// Works with any integer expression.
template <typename T> const Symbol *GetBoundSymbol(const Expr<T> &);
template <int KIND>
static const Symbol *GetBoundSymbol(
const Symbol *GetBoundSymbol(
const Expr<Type<TypeCategory::Integer, KIND>> &expr) {
using T = Type<TypeCategory::Integer, KIND>;
return common::visit(
Expand Down Expand Up @@ -1358,9 +1360,15 @@ static const Symbol *GetBoundSymbol(
},
expr.u);
}
template <>
const Symbol *GetBoundSymbol<SomeInteger>(const Expr<SomeInteger> &expr) {
return common::visit(
[](const auto &kindExpr) { return GetBoundSymbol(kindExpr); }, expr.u);
}

template <typename T>
std::optional<bool> AreEquivalentInInterface(
const Expr<SubscriptInteger> &x, const Expr<SubscriptInteger> &y) {
const Expr<T> &x, const Expr<T> &y) {
auto xVal{ToInt64(x)};
auto yVal{ToInt64(y)};
if (xVal && yVal) {
Expand Down Expand Up @@ -1394,6 +1402,10 @@ std::optional<bool> AreEquivalentInInterface(
return std::nullopt; // not sure
}
}
template std::optional<bool> AreEquivalentInInterface<SubscriptInteger>(
const Expr<SubscriptInteger> &, const Expr<SubscriptInteger> &);
template std::optional<bool> AreEquivalentInInterface<SomeInteger>(
const Expr<SomeInteger> &, const Expr<SomeInteger> &);

bool CheckForCoindexedObject(parser::ContextualMessages &messages,
const std::optional<ActualArgument> &arg, const std::string &procName,
Expand Down
5 changes: 4 additions & 1 deletion flang/lib/Evaluate/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,10 @@ static bool AreSameDerivedType(

bool DynamicType::IsEquivalentTo(const DynamicType &that) const {
return category_ == that.category_ && kind_ == that.kind_ &&
PointeeComparison(charLengthParamValue_, that.charLengthParamValue_) &&
(charLengthParamValue_ == that.charLengthParamValue_ ||
(charLengthParamValue_ && that.charLengthParamValue_ &&
charLengthParamValue_->IsEquivalentInInterface(
*that.charLengthParamValue_))) &&
knownLength().has_value() == that.knownLength().has_value() &&
(!knownLength() || *knownLength() == *that.knownLength()) &&
AreSameDerivedType(derived_, that.derived_);
Expand Down
6 changes: 6 additions & 0 deletions flang/lib/Semantics/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,12 @@ void ParamValue::SetExplicit(SomeIntExpr &&x) {
expr_ = std::move(x);
}

bool ParamValue::IsEquivalentInInterface(const ParamValue &that) const {
return (category_ == that.category_ &&
expr_.has_value() == that.expr_.has_value() &&
(!expr_ || evaluate::AreEquivalentInInterface(*expr_, *that.expr_)));
}

std::string ParamValue::AsFortran() const {
switch (category_) {
SWITCH_COVERS_ALL_CASES
Expand Down
23 changes: 23 additions & 0 deletions flang/test/Semantics/smp-def01.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
!RUN: %flang -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
!Ensure no bogus error message about incompatible character length
!CHECK-NOT: error

module m1
integer :: n = 1
end

module m2
interface
module subroutine s(a,b)
use m1
character(n) :: a
character(n) :: b
end
end interface
end

submodule(m2) m2s1
contains
module procedure s
end
end
Loading