[flang-commits] [flang] e1ee20d - [flang] Ignore inaccessible components when extending types or constructing structures
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Tue Aug 9 07:44:14 PDT 2022
Author: Peter Klausler
Date: 2022-08-09T07:44:02-07:00
New Revision: e1ee20d574df8ba6efb01eec3d2fa3c9cd82984d
URL: https://github.com/llvm/llvm-project/commit/e1ee20d574df8ba6efb01eec3d2fa3c9cd82984d
DIFF: https://github.com/llvm/llvm-project/commit/e1ee20d574df8ba6efb01eec3d2fa3c9cd82984d.diff
LOG: [flang] Ignore inaccessible components when extending types or constructing structures
Inaccessible components -- those declared PRIVATE in another module -- should
be allowed to be redeclared in extended types, and should be ignored if
they appear as keywords in structure constructors.
Differential Revision: https://reviews.llvm.org/D131102
Added:
flang/test/Semantics/symbol22.f90
Modified:
flang/lib/Semantics/expression.cpp
flang/lib/Semantics/resolve-names.cpp
Removed:
################################################################################
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 01bfea713e6a7..dacfe796f3627 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1700,10 +1700,12 @@ MaybeExpr ExpressionAnalyzer::Analyze(
source = kw->v.source;
symbol = kw->v.symbol;
if (!symbol) {
- auto componentIter{std::find_if(components.begin(), components.end(),
- [=](const Symbol &symbol) { return symbol.name() == source; })};
- if (componentIter != components.end()) {
- symbol = &*componentIter;
+ // Skip overridden inaccessible parent components in favor of
+ // their later overrides.
+ for (const Symbol &sym : components) {
+ if (sym.name() == source) {
+ symbol = &sym;
+ }
}
}
if (!symbol) { // C7101
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 06694efa66d9d..2c94f57a502eb 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -5787,25 +5787,34 @@ bool DeclarationVisitor::OkToAddComponent(
const parser::Name &name, const Symbol *extends) {
for (const Scope *scope{&currScope()}; scope;) {
CHECK(scope->IsDerivedType());
- if (auto *prev{FindInScope(*scope, name)}) {
- if (!context().HasError(*prev)) {
- parser::MessageFixedText msg;
- if (extends) {
- msg = "Type cannot be extended as it has a component named"
- " '%s'"_err_en_US;
- } else if (prev->test(Symbol::Flag::ParentComp)) {
- msg = "'%s' is a parent type of this type and so cannot be"
- " a component"_err_en_US;
- } else if (scope != &currScope()) {
- msg = "Component '%s' is already declared in a parent of this"
- " derived type"_err_en_US;
- } else {
- msg = "Component '%s' is already declared in this"
- " derived type"_err_en_US;
+ if (auto *prev{FindInScope(*scope, name.source)}) {
+ std::optional<parser::MessageFixedText> msg;
+ if (context().HasError(*prev)) { // don't pile on
+ } else if (extends) {
+ msg = "Type cannot be extended as it has a component named"
+ " '%s'"_err_en_US;
+ } else if (CheckAccessibleComponent(currScope(), *prev)) {
+ // inaccessible component -- redeclaration is ok
+ msg = "Component '%s' is inaccessibly declared in or as a "
+ "parent of this derived type"_warn_en_US;
+ } else if (prev->test(Symbol::Flag::ParentComp)) {
+ msg = "'%s' is a parent type of this type and so cannot be"
+ " a component"_err_en_US;
+ } else if (scope == &currScope()) {
+ msg = "Component '%s' is already declared in this"
+ " derived type"_err_en_US;
+ } else {
+ msg = "Component '%s' is already declared in a parent of this"
+ " derived type"_err_en_US;
+ }
+ if (msg) {
+ Say2(
+ name, std::move(*msg), *prev, "Previous declaration of '%s'"_en_US);
+ if (msg->severity() == parser::Severity::Error) {
+ Resolve(name, *prev);
+ return false;
}
- Say2(name, std::move(msg), *prev, "Previous declaration of '%s'"_en_US);
}
- return false;
}
if (scope == &currScope() && extends) {
// The parent component has not yet been added to the scope.
diff --git a/flang/test/Semantics/symbol22.f90 b/flang/test/Semantics/symbol22.f90
new file mode 100644
index 0000000000000..6a85b37a15aea
--- /dev/null
+++ b/flang/test/Semantics/symbol22.f90
@@ -0,0 +1,55 @@
+! RUN: %python %S/test_symbols.py %s %flang_fc1
+! Allow redeclaration of inherited inaccessible components
+!DEF: /m1 Module
+module m1
+ !DEF: /m1/t0 PRIVATE DerivedType
+ type, private :: t0
+ end type
+ !REF: /m1/t0
+ !DEF: /m1/t1 PUBLIC DerivedType
+ type, extends(t0) :: t1
+ !DEF: /m1/t1/n1a PRIVATE ObjectEntity INTEGER(4)
+ !DEF: /m1/t1/n1b PRIVATE ObjectEntity INTEGER(4)
+ integer, private :: n1a = 1, n1b = 2
+ end type
+end module
+!DEF: /m2 Module
+module m2
+ !REF: /m1
+ use :: m1
+ !DEF: /m2/t1 PUBLIC Use
+ !DEF: /m2/t2 PUBLIC DerivedType
+ type, extends(t1) :: t2
+ !DEF: /m2/t2/t0 ObjectEntity REAL(4)
+ real :: t0
+ !DEF: /m2/t2/n1a ObjectEntity REAL(4)
+ real :: n1a
+ end type
+ !REF: /m2/t2
+ !DEF: /m2/t3 PUBLIC DerivedType
+ type, extends(t2) :: t3
+ !DEF: /m2/t3/n1b ObjectEntity REAL(4)
+ real :: n1b
+ end type
+end module
+!DEF: /test (Subroutine) Subprogram
+subroutine test
+ !REF: /m2
+ use :: m2
+ !DEF: /test/t3 Use
+ !DEF: /test/x ObjectEntity TYPE(t3)
+ type(t3) :: x
+ !REF: /test/x
+ !REF: /m2/t3/n1b
+ x%n1b = 1.
+ !REF: /test/x
+ !DEF: /m2/t3/t2 (ParentComp) ObjectEntity TYPE(t2)
+ !DEF: /test/t2 Use
+ x%t2 = t2(t0=2., n1a=3.)
+ !REF: /test/x
+ !REF: /m2/t2/t0
+ x%t0 = 4.
+ !REF: /test/x
+ !REF: /m2/t2/n1a
+ x%n1a = 5.
+end subroutine
More information about the flang-commits
mailing list