diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -219,10 +219,7 @@ const ProcInterface &interface() const { return interface_; } ProcInterface &interface() { return interface_; } - void set_interface(const ProcInterface &interface) { - CHECK(!IsInterfaceSet()); - interface_ = interface; - } + void set_interface(const ProcInterface &interface) { interface_ = interface; } bool IsInterfaceSet() { return interface_.symbol() != nullptr || interface_.type() != nullptr; } diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp --- a/flang/lib/Semantics/compute-offsets.cpp +++ b/flang/lib/Semantics/compute-offsets.cpp @@ -257,7 +257,7 @@ // TODO: The size of procedure pointers is not yet known // and is independent of rank (and probably also the number // of length type parameters). - if (IsDescriptor(symbol) || IsProcedure(symbol)) { + if (IsDescriptor(symbol) || IsProcedurePointer(symbol)) { int lenParams{0}; if (const DerivedTypeSpec * derived{type->AsDerived()}) { lenParams = CountLenParameters(*derived); @@ -266,6 +266,9 @@ runtime::Descriptor::SizeInBytes(symbol.Rank(), false, lenParams)}; return {size, maxAlignment}; } + if (IsProcedure(symbol)) { + return {}; + } SizeAndAlignment result; if (const IntrinsicTypeSpec * intrinsic{type->AsIntrinsic()}) { if (auto kind{ToInt64(intrinsic->kind())}) { 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 @@ -157,6 +157,9 @@ evaluate::FoldingContext &GetFoldingContext() const { return context_->foldingContext(); } + bool IsIntrinsic(const SourceName &name) const { + return context_->intrinsics().IsIntrinsic(name.ToString()); + } // Make a placeholder symbol for a Name that otherwise wouldn't have one. // It is not in any scope and always has MiscDetails. @@ -2377,14 +2380,14 @@ }, symbol.details()); } + void ScopeHandler::ApplyImplicitRules(Symbol &symbol) { if (NeedsType(symbol)) { if (const DeclTypeSpec * type{GetImplicitType(symbol)}) { symbol.set(Symbol::Flag::Implicit); symbol.SetType(*type); } else if (symbol.has() && - !symbol.attrs().test(Attr::EXTERNAL) && - context().intrinsics().IsIntrinsic(symbol.name().ToString())) { + !symbol.attrs().test(Attr::EXTERNAL) && IsIntrinsic(symbol.name())) { // type will be determined in expression semantics symbol.attrs().set(Attr::INTRINSIC); } else if (!context().HasError(symbol)) { @@ -2393,6 +2396,7 @@ } } } + const DeclTypeSpec *ScopeHandler::GetImplicitType(Symbol &symbol) { const DeclTypeSpec *type{implicitRules().GetType(symbol.name().begin()[0])}; if (type) { @@ -3616,8 +3620,7 @@ } Symbol &DeclarationVisitor::HandleAttributeStmt( Attr attr, const parser::Name &name) { - if (attr == Attr::INTRINSIC && - !context().intrinsics().IsIntrinsic(name.source.ToString())) { + if (attr == Attr::INTRINSIC && !IsIntrinsic(name.source)) { Say(name.source, "'%s' is not a known intrinsic procedure"_err_en_US); } auto *symbol{FindInScope(currScope(), name)}; @@ -6055,7 +6058,7 @@ CHECK(flag == Symbol::Flag::Function || flag == Symbol::Flag::Subroutine); auto *symbol{FindSymbol(NonDerivedTypeScope(), name)}; if (!symbol) { - if (context().intrinsics().IsIntrinsic(name.source.ToString())) { + if (IsIntrinsic(name.source)) { symbol = &MakeSymbol(InclusiveScope(), name.source, Attrs{Attr::INTRINSIC}); } else { @@ -6084,7 +6087,11 @@ // error was reported } else { symbol = &Resolve(name, symbol)->GetUltimate(); - ConvertToProcEntity(*symbol); + if (ConvertToProcEntity(*symbol) && IsIntrinsic(symbol->name())) { + symbol->attrs().set(Attr::INTRINSIC); + // 8.2(3): ignore type from intrinsic in type-declaration-stmt + symbol->get().set_interface(ProcInterface{}); + } if (!SetProcFlag(name, *symbol, flag)) { return; // reported error } diff --git a/flang/test/Semantics/symbol18.f90 b/flang/test/Semantics/symbol18.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/symbol18.f90 @@ -0,0 +1,21 @@ +! RUN: %S/test_symbols.sh %s %t %f18 + +! Intrinsic function in type declaration statement: type is ignored + +!DEF: /p1 MainProgram +program p1 + !DEF: /p1/cos INTRINSIC (Function) ProcEntity + integer cos + !DEF: /p1/y (Implicit) ObjectEntity REAL(4) + !REF: /p1/cos + !DEF: /p1/x (Implicit) ObjectEntity REAL(4) + y = cos(x) + !REF: /p1/y + !DEF: /p1/sin INTRINSIC (Function) ProcEntity + !REF: /p1/x + y = sin(x) + !REF: /p1/y + !DEF: /f EXTERNAL (Function, Implicit) ProcEntity REAL(4) + !REF: /p1/x + y = f(x) +end program