Index: flang/lib/Semantics/expression.cpp =================================================================== --- flang/lib/Semantics/expression.cpp +++ flang/lib/Semantics/expression.cpp @@ -249,17 +249,13 @@ } return std::nullopt; } else if (Component * component{ref.base().UnwrapComponent()}) { - int baseRank{component->base().Rank()}; - if (baseRank > 0) { - int subscriptRank{0}; + if (component->base().Rank() > 0) { for (const auto &expr : ref.subscript()) { - subscriptRank += expr.Rank(); - } - if (subscriptRank > 0) { // C919a - Say("Subscripts of component '%s' of rank-%d derived type " - "array have rank %d but must all be scalar"_err_en_US, - symbol.name(), baseRank, subscriptRank); - return std::nullopt; + if (expr.Rank() > 0) { // C919 + Say("A derived type accessbility cannot have more than one component " + "references with nonzero rank"_err_en_US); + return std::nullopt; + } } } } else if (const auto *object{ @@ -308,15 +304,10 @@ // Top-level checks for data references. MaybeExpr ExpressionAnalyzer::TopLevelChecks(DataRef &&dataRef) { if (Component * component{std::get_if(&dataRef.u)}) { - const Symbol &symbol{component->GetLastSymbol()}; - int componentRank{symbol.Rank()}; - if (componentRank > 0) { - int baseRank{component->base().Rank()}; - if (baseRank > 0) { // C919a - Say("Reference to whole rank-%d component '%%%s' of " - "rank-%d array of derived type is not allowed"_err_en_US, - componentRank, symbol.name(), baseRank); - } + if (component->GetLastSymbol().Rank() > 0 && + component->base().Rank() > 0) { // C919 + Say("A derived type accessbility cannot have more than one component " + "references with nonzero rank"_err_en_US); } } return Designate(std::move(dataRef)); @@ -1054,6 +1045,16 @@ return std::nullopt; } else if (std::optional dataRef{ ExtractDataRef(std::move(*dtExpr))}) { + const DataRef *ref{&*dataRef}; + while (const Component * component{std::get_if(&ref->u)}) { + if (component->base().Rank() > 0 && ref->Rank() > 0) { // C919 + Say(name, + "A derived type accessbility cannot have more than one component " + "references with nonzero rank"_err_en_US); + return std::nullopt; + } + ref = &component->base(); + } if (auto component{ CreateComponent(std::move(*dataRef), *sym, *dtSpec->scope())}) { return Designate(DataRef{std::move(*component)}); Index: flang/test/Semantics/expr-errors04.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/expr-errors04.f90 @@ -0,0 +1,62 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +! Regression test for more than one part-ref with nonzero rank + +program m + type mt + integer :: x(2,2) + character(10) :: s(2,2) + end type + type mt2 + type(mt) :: t1(2) + end type + type mt3 + type(mt2) :: t2(2,2) + end type + type mt4 + type(mt3) :: t3(2,2) + end type + type(mt4) :: t(2,2) + + call sub(t(1,1)%t3(1,1)%t2(1,1)%t1(1)%s) ! no error + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t%t3%t2%t1%s) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,1)%t3%t2%t1%s) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,1)%t3(1,1)%t2%t1%s) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,1)%t3(1,1)%t2(1,1)%t1%s) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,:)%t3(1,1)%t2(1,1)%t1(1)%s) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,:)%t3(1,1)%t2(1,1)%t1(1)%s(1,:)) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,:)%t3(1,1)%t2(1,1)%t1(1)%s(1,:)(1:2)) + + call sub(t(1,1)%t3(1,1)%t2(1,1)%t1(1)%x) ! no error + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t%t3%t2%t1%x) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,1)%t3%t2%t1%x) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,1)%t3(1,1)%t2%t1%x) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,1)%t3(1,1)%t2(1,1)%t1%x) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,:)%t3(1,1)%t2(1,1)%t1(1)%x) + + !ERROR: A derived type accessbility cannot have more than one component references with nonzero rank + call sub(t(1,:)%t3(1,1)%t2(1,1)%t1(1)%s(1,:)) +end