diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -544,6 +544,13 @@ symbol->set_details(std::move(details)); return *symbol; } + if (isSameSymbolNameAllowed(*symbol, details)) { + symbol = &MakeSymbol(name, attrs); + if (symbol->CanReplaceDetails(details)) { + symbol->set_details(std::move(details)); + } + } + if constexpr (std::is_same_v) { if (auto *d{symbol->detailsIf()}) { if (!d->specific()) { @@ -573,6 +580,11 @@ symbol->attrs() |= attrs; return *symbol; } else { + // Skip ContructName vs NonContructName reference check so we could have + // same names in scope. + if (isSameSymbolNameAllowed(*symbol, details)) { + return *symbol; + } if (!CheckPossibleBadForwardRef(*symbol)) { SayAlreadyDeclared(name, *symbol); } @@ -603,6 +615,16 @@ void NotePossibleBadForwardRef(const parser::Name &); std::optional HadForwardRef(const Symbol &) const; bool CheckPossibleBadForwardRef(const Symbol &); + template + bool isSameSymbolNameAllowed(Symbol& symbol, D &&details) { + if constexpr (std::is_same_v) { + if (details.kind() == MiscDetails::Kind::ConstructName && + symbol.has()) { + return true; + } + return false; + } + } bool inExecutionPart_{false}; bool inSpecificationPart_{false}; diff --git a/flang/test/Semantics/resolve35.f90 b/flang/test/Semantics/resolve35.f90 --- a/flang/test/Semantics/resolve35.f90 +++ b/flang/test/Semantics/resolve35.f90 @@ -3,6 +3,13 @@ subroutine s1 real :: foo + foo: block + end block foo +end + +subroutine s1b + foo: block + end block foo !ERROR: 'foo' is already declared in this scoping unit foo: block end block foo @@ -17,6 +24,12 @@ end do foo end +subroutine s2b(x) + logical :: x + x: if (x) then + end if x +end + subroutine s3 real :: a(10,10), b(10,10) type y; end type