[flang-commits] [flang] [flang] Fix bogus error on aliased derived type (PR #69959)
via flang-commits
flang-commits at lists.llvm.org
Mon Oct 23 11:45:52 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
When a derived type definition is visible by two or more names in the same scope due to USE renaming, any generic ASSIGNMENT(=) or OPERATOR() bindings in the type will produce incorrect error messages about indistinguishable specific procedures. This is due to the use of a std::vector<> to hold a sequence of symbols and some derived information for the specific procedures of the generic name. Change to a std::map<> indexed by the ultimate symbol of each specific so that duplicates cannot arise.
---
Full diff: https://github.com/llvm/llvm-project/pull/69959.diff
2 Files Affected:
- (modified) flang/lib/Semantics/check-declarations.cpp (+13-13)
- (modified) flang/test/Semantics/generic07.f90 (+23-3)
``````````diff
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 2c2866d590ae5a4..45fd9dc28fe560c 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -198,10 +198,10 @@ class DistinguishabilityHelper {
SemanticsContext &context_;
struct ProcedureInfo {
GenericKind kind;
- const Symbol &symbol;
const Procedure &procedure;
};
- std::map<SourceName, std::vector<ProcedureInfo>> nameToInfo_;
+ std::map<SourceName, std::map<const Symbol *, ProcedureInfo>>
+ nameToSpecifics_;
};
void CheckHelper::Check(const ParamValue &value, bool canBeAssumed) {
@@ -3441,26 +3441,26 @@ evaluate::Shape SubprogramMatchHelper::FoldShape(const evaluate::Shape &shape) {
}
void DistinguishabilityHelper::Add(const Symbol &generic, GenericKind kind,
- const Symbol &specific, const Procedure &procedure) {
- if (!context_.HasError(specific)) {
- nameToInfo_[generic.name()].emplace_back(
- ProcedureInfo{kind, specific, procedure});
+ const Symbol &ultimateSpecific, const Procedure &procedure) {
+ if (!context_.HasError(ultimateSpecific)) {
+ nameToSpecifics_[generic.name()].emplace(
+ &ultimateSpecific, ProcedureInfo{kind, procedure});
}
}
void DistinguishabilityHelper::Check(const Scope &scope) {
- for (const auto &[name, info] : nameToInfo_) {
- auto count{info.size()};
- for (std::size_t i1{0}; i1 < count - 1; ++i1) {
- const auto &[kind, symbol, proc]{info[i1]};
- for (std::size_t i2{i1 + 1}; i2 < count; ++i2) {
+ for (const auto &[name, info] : nameToSpecifics_) {
+ for (auto iter1{info.begin()}; iter1 != info.end(); ++iter1) {
+ const auto &[ultimate, procInfo]{*iter1};
+ const auto &[kind, proc]{procInfo};
+ for (auto iter2{iter1}; ++iter2 != info.end();) {
auto distinguishable{kind.IsName()
? evaluate::characteristics::Distinguishable
: evaluate::characteristics::DistinguishableOpOrAssign};
if (!distinguishable(
- context_.languageFeatures(), proc, info[i2].procedure)) {
+ context_.languageFeatures(), proc, iter2->second.procedure)) {
SayNotDistinguishable(GetTopLevelUnitContaining(scope), name, kind,
- symbol, info[i2].symbol);
+ *ultimate, *iter2->first);
}
}
}
diff --git a/flang/test/Semantics/generic07.f90 b/flang/test/Semantics/generic07.f90
index 885697e4b5a9783..e7486c02a7d2ba1 100644
--- a/flang/test/Semantics/generic07.f90
+++ b/flang/test/Semantics/generic07.f90
@@ -1,5 +1,5 @@
! RUN: %python %S/test_errors.py %s %flang_fc1
-module m
+module m1
type :: t1
sequence
real :: x
@@ -29,8 +29,28 @@ subroutine s4a(x)
end
end
+module m2
+ type t10
+ integer n
+ contains
+ procedure :: f
+ generic:: operator(+) => f
+ end type
+ contains
+ elemental type(t10) function f(x,y)
+ class(t10), intent(in) :: x, y
+ f%n = x%n + y%n
+ end
+end
+
+module m3
+ use m2, only: rt10 => t10
+end
+
program test
- use m, only: s1a, s2a, s3a, s4a
+ use m1, only: s1a, s2a, s3a, s4a
+ use m2, only: t10
+ use m3, only: rt10 ! alias for t10, ensure no distinguishability error
type :: t1
sequence
integer :: x ! distinct type
@@ -54,7 +74,7 @@ program test
interface distinguishable3
procedure :: s1a, s1b
end interface
- !ERROR: Generic 'indistinguishable' may not have specific procedures 's2a' and 's2b' as their interfaces are not distinguishable
+ !ERROR: Generic 'indistinguishable' may not have specific procedures 's2b' and 's2a' as their interfaces are not distinguishable
interface indistinguishable
procedure :: s2a, s2b
end interface
``````````
</details>
https://github.com/llvm/llvm-project/pull/69959
More information about the flang-commits
mailing list