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 @@ -2510,8 +2510,16 @@ if (symbol.has()) { // nothing to do } else if (symbol.has()) { + // These are attributes that a name could have picked up from + // an attribute statement or type declaration statement. + if (symbol.attrs().HasAny({Attr::EXTERNAL, Attr::INTRINSIC})) { + return false; + } symbol.set_details(ObjectEntityDetails{}); } else if (auto *details{symbol.detailsIf()}) { + if (symbol.attrs().HasAny({Attr::EXTERNAL, Attr::INTRINSIC})) { + return false; + } funcResultStack_.CompleteTypeIfFunctionResult(symbol); symbol.set_details(ObjectEntityDetails{std::move(*details)}); } else if (auto *useDetails{symbol.detailsIf()}) { @@ -6970,10 +6978,6 @@ return; } Symbol &ultimate{name.symbol->GetUltimate()}; - if (IsAllocatable(ultimate)) { - Say(name, "Allocatable object '%s' cannot be initialized"_err_en_US); - return; - } // TODO: check C762 - all bounds and type parameters of component // are colons or constant expressions if component is initialized common::visit( @@ -7074,6 +7078,10 @@ "'%s' is a pointer but is not initialized like one"_err_en_US); } else if (auto *details{ultimate.detailsIf()}) { CHECK(!details->init()); + if (IsAllocatable(ultimate)) { + Say(name, "Allocatable object '%s' cannot be initialized"_err_en_US); + return; + } Walk(expr); if (ultimate.owner().IsParameterizedDerivedType()) { // Save the expression for per-instantiation analysis. @@ -7084,6 +7092,8 @@ details->set_init(std::move(*folded)); } } + } else { + Say(name, "'%s' is not an object that can be initialized"_err_en_US); } } } diff --git a/flang/test/Semantics/init01.f90 b/flang/test/Semantics/init01.f90 --- a/flang/test/Semantics/init01.f90 +++ b/flang/test/Semantics/init01.f90 @@ -95,3 +95,14 @@ end block end associate end subroutine + +subroutine notObjects +!ERROR: 'x1' is not an object that can be initialized + real, external :: x1 = 1. +!ERROR: 'x2' is not a pointer but is initialized like one + real, external :: x2 => sin +!ERROR: 'x3' is not an object that can be initialized + real, intrinsic :: x3 = 1. +!ERROR: 'x4' is not a pointer but is initialized like one + real, intrinsic :: x4 => cos +end subroutine