Skip to content

Commit 2c662f3

Browse files
committed
[flang] Fix bug with intrinsic in type declaration stmt
When an instrinsic function is declared in a type declaration statement we need to set the INTRINSIC attribute and (per 8.2(3)) ignore the specified type. To simplify the check, add IsIntrinsic utility to BaseVisitor. Also, intrinsics and external procedures were getting assigned a size and offset and they shouldn't be. Differential Revision: https://reviews.llvm.org/D84702
1 parent 672df0f commit 2c662f3

File tree

4 files changed

+39
-11
lines changed

4 files changed

+39
-11
lines changed

flang/include/flang/Semantics/symbol.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,7 @@ class ProcEntityDetails : public EntityDetails, public WithPassArg {
219219

220220
const ProcInterface &interface() const { return interface_; }
221221
ProcInterface &interface() { return interface_; }
222-
void set_interface(const ProcInterface &interface) {
223-
CHECK(!IsInterfaceSet());
224-
interface_ = interface;
225-
}
222+
void set_interface(const ProcInterface &interface) { interface_ = interface; }
226223
bool IsInterfaceSet() {
227224
return interface_.symbol() != nullptr || interface_.type() != nullptr;
228225
}

flang/lib/Semantics/compute-offsets.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ auto ComputeOffsetsHelper::GetElementSize(const Symbol &symbol)
257257
// TODO: The size of procedure pointers is not yet known
258258
// and is independent of rank (and probably also the number
259259
// of length type parameters).
260-
if (IsDescriptor(symbol) || IsProcedure(symbol)) {
260+
if (IsDescriptor(symbol) || IsProcedurePointer(symbol)) {
261261
int lenParams{0};
262262
if (const DerivedTypeSpec * derived{type->AsDerived()}) {
263263
lenParams = CountLenParameters(*derived);
@@ -266,6 +266,9 @@ auto ComputeOffsetsHelper::GetElementSize(const Symbol &symbol)
266266
runtime::Descriptor::SizeInBytes(symbol.Rank(), false, lenParams)};
267267
return {size, maxAlignment};
268268
}
269+
if (IsProcedure(symbol)) {
270+
return {};
271+
}
269272
SizeAndAlignment result;
270273
if (const IntrinsicTypeSpec * intrinsic{type->AsIntrinsic()}) {
271274
if (auto kind{ToInt64(intrinsic->kind())}) {

flang/lib/Semantics/resolve-names.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ class BaseVisitor {
156156
evaluate::FoldingContext &GetFoldingContext() const {
157157
return context_->foldingContext();
158158
}
159+
bool IsIntrinsic(const SourceName &name) const {
160+
return context_->intrinsics().IsIntrinsic(name.ToString());
161+
}
159162

160163
// Make a placeholder symbol for a Name that otherwise wouldn't have one.
161164
// It is not in any scope and always has MiscDetails.
@@ -2046,14 +2049,14 @@ static bool NeedsType(const Symbol &symbol) {
20462049
},
20472050
symbol.details());
20482051
}
2052+
20492053
void ScopeHandler::ApplyImplicitRules(Symbol &symbol) {
20502054
if (NeedsType(symbol)) {
20512055
if (const DeclTypeSpec * type{GetImplicitType(symbol)}) {
20522056
symbol.set(Symbol::Flag::Implicit);
20532057
symbol.SetType(*type);
20542058
} else if (symbol.has<ProcEntityDetails>() &&
2055-
!symbol.attrs().test(Attr::EXTERNAL) &&
2056-
context().intrinsics().IsIntrinsic(symbol.name().ToString())) {
2059+
!symbol.attrs().test(Attr::EXTERNAL) && IsIntrinsic(symbol.name())) {
20572060
// type will be determined in expression semantics
20582061
symbol.attrs().set(Attr::INTRINSIC);
20592062
} else if (!context().HasError(symbol)) {
@@ -2062,6 +2065,7 @@ void ScopeHandler::ApplyImplicitRules(Symbol &symbol) {
20622065
}
20632066
}
20642067
}
2068+
20652069
const DeclTypeSpec *ScopeHandler::GetImplicitType(Symbol &symbol) {
20662070
const DeclTypeSpec *type{implicitRules().GetType(symbol.name().begin()[0])};
20672071
if (type) {
@@ -3284,8 +3288,7 @@ bool DeclarationVisitor::HandleAttributeStmt(
32843288
}
32853289
Symbol &DeclarationVisitor::HandleAttributeStmt(
32863290
Attr attr, const parser::Name &name) {
3287-
if (attr == Attr::INTRINSIC &&
3288-
!context().intrinsics().IsIntrinsic(name.source.ToString())) {
3291+
if (attr == Attr::INTRINSIC && !IsIntrinsic(name.source)) {
32893292
Say(name.source, "'%s' is not a known intrinsic procedure"_err_en_US);
32903293
}
32913294
auto *symbol{FindInScope(currScope(), name)};
@@ -5700,7 +5703,7 @@ void ResolveNamesVisitor::HandleProcedureName(
57005703
CHECK(flag == Symbol::Flag::Function || flag == Symbol::Flag::Subroutine);
57015704
auto *symbol{FindSymbol(NonDerivedTypeScope(), name)};
57025705
if (!symbol) {
5703-
if (context().intrinsics().IsIntrinsic(name.source.ToString())) {
5706+
if (IsIntrinsic(name.source)) {
57045707
symbol =
57055708
&MakeSymbol(InclusiveScope(), name.source, Attrs{Attr::INTRINSIC});
57065709
} else {
@@ -5729,7 +5732,11 @@ void ResolveNamesVisitor::HandleProcedureName(
57295732
// error was reported
57305733
} else {
57315734
symbol = &Resolve(name, symbol)->GetUltimate();
5732-
ConvertToProcEntity(*symbol);
5735+
if (ConvertToProcEntity(*symbol) && IsIntrinsic(symbol->name())) {
5736+
symbol->attrs().set(Attr::INTRINSIC);
5737+
// 8.2(3): ignore type from intrinsic in type-declaration-stmt
5738+
symbol->get<ProcEntityDetails>().set_interface(ProcInterface{});
5739+
}
57335740
if (!SetProcFlag(name, *symbol, flag)) {
57345741
return; // reported error
57355742
}

flang/test/Semantics/symbol18.f90

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
! RUN: %S/test_symbols.sh %s %t %f18
2+
3+
! Intrinsic function in type declaration statement: type is ignored
4+
5+
!DEF: /p1 MainProgram
6+
program p1
7+
!DEF: /p1/cos INTRINSIC (Function) ProcEntity
8+
integer cos
9+
!DEF: /p1/y (Implicit) ObjectEntity REAL(4)
10+
!REF: /p1/cos
11+
!DEF: /p1/x (Implicit) ObjectEntity REAL(4)
12+
y = cos(x)
13+
!REF: /p1/y
14+
!DEF: /p1/sin INTRINSIC (Function) ProcEntity
15+
!REF: /p1/x
16+
y = sin(x)
17+
!REF: /p1/y
18+
!DEF: /f EXTERNAL (Function, Implicit) ProcEntity REAL(4)
19+
!REF: /p1/x
20+
y = f(x)
21+
end program

0 commit comments

Comments
 (0)