[flang-commits] [flang] 2216c4c - [flang] Catch name conflict between generic TBP and inherited non-generic
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Thu Mar 2 10:21:46 PST 2023
Author: Peter Klausler
Date: 2023-03-02T10:10:37-08:00
New Revision: 2216c4c6a4e29a945af75f02b9a733ac5b016ed7
URL: https://github.com/llvm/llvm-project/commit/2216c4c6a4e29a945af75f02b9a733ac5b016ed7
DIFF: https://github.com/llvm/llvm-project/commit/2216c4c6a4e29a945af75f02b9a733ac5b016ed7.diff
LOG: [flang] Catch name conflict between generic TBP and inherited non-generic
A generic procedure binding in an extended derived type may not have the
same name as a symbol inherited from an ancestor type unless that inherited
symbol is also a generic TBP. Since generic names can be things like
"ASSIGNMENT(=)", name resolution doesn't use OkToAddComponent() for
generic TBPs, which would have caught this error as it does for other
symbols in derived types, so it must be special-cased.
Differential Revision: https://reviews.llvm.org/D145109
Added:
flang/test/Semantics/resolve117.f90
Modified:
flang/lib/Semantics/resolve-names.cpp
Removed:
################################################################################
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index b9aa4c19af9c..774beb60fe78 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -5226,7 +5226,7 @@ bool DeclarationVisitor::Pre(const parser::TypeBoundGenericStmt &x) {
const auto &accessSpec{std::get<std::optional<parser::AccessSpec>>(x.t)};
const auto &genericSpec{std::get<Indirection<parser::GenericSpec>>(x.t)};
const auto &bindingNames{std::get<std::list<parser::Name>>(x.t)};
- auto info{GenericSpecInfo{genericSpec.value()}};
+ GenericSpecInfo info{genericSpec.value()};
SourceName symbolName{info.symbolName()};
bool isPrivate{accessSpec ? accessSpec->v == parser::AccessSpec::Kind::Private
: derivedTypeInfo_.privateBindings};
@@ -5236,17 +5236,19 @@ bool DeclarationVisitor::Pre(const parser::TypeBoundGenericStmt &x) {
genericSymbol = nullptr; // MakeTypeSymbol will report the error below
}
} else {
- // look in parent types:
- Symbol *inheritedSymbol{nullptr};
+ // look in ancestor types for a generic of the same name
for (const auto &name : GetAllNames(context(), symbolName)) {
- inheritedSymbol = currScope().FindComponent(SourceName{name});
- if (inheritedSymbol) {
+ if (Symbol * inherited{currScope().FindComponent(SourceName{name})}) {
+ if (inherited->has<GenericDetails>()) {
+ CheckAccessibility(symbolName, isPrivate, *inherited); // C771
+ } else {
+ Say(symbolName,
+ "Type bound generic procedure '%s' may not have the same name as a non-generic symbol inherited from an ancestor type"_err_en_US)
+ .Attach(inherited->name(), "Inherited symbol"_en_US);
+ }
break;
}
}
- if (inheritedSymbol && inheritedSymbol->has<GenericDetails>()) {
- CheckAccessibility(symbolName, isPrivate, *inheritedSymbol); // C771
- }
}
if (genericSymbol) {
CheckAccessibility(symbolName, isPrivate, *genericSymbol); // C771
diff --git a/flang/test/Semantics/resolve117.f90 b/flang/test/Semantics/resolve117.f90
new file mode 100644
index 000000000000..3e3a813c0921
--- /dev/null
+++ b/flang/test/Semantics/resolve117.f90
@@ -0,0 +1,27 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! Test name conflicts with type-bound generics
+module m
+ type base1(k)
+ integer, kind :: k = 4
+ real x
+ contains
+ procedure, nopass :: tbp => sub
+ generic :: gen => tbp
+ end type
+ type, extends(base1) :: ext1
+ contains
+ procedure, nopass :: sub
+ !ERROR: Type parameter, component, or procedure binding 'base1' already defined in this type
+ generic :: base1 => sub
+ !ERROR: Type bound generic procedure 'k' may not have the same name as a non-generic symbol inherited from an ancestor type
+ generic :: k => sub
+ !ERROR: Type bound generic procedure 'x' may not have the same name as a non-generic symbol inherited from an ancestor type
+ generic :: x => sub
+ !ERROR: Type bound generic procedure 'tbp' may not have the same name as a non-generic symbol inherited from an ancestor type
+ generic :: tbp => sub
+ generic :: gen => sub ! ok
+ end type
+ contains
+ subroutine sub
+ end
+end
More information about the flang-commits
mailing list