Skip to content

Commit 594dec2

Browse files
committed
[FLANG] Fix issues in SELECT TYPE construct when intrinsic type specification is specified in TYPE GUARD statement.
Fix of PR46789 and PR46830. Differential Revision: https://reviews.llvm.org/D84290
1 parent 62e4644 commit 594dec2

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

flang/lib/Semantics/check-select-type.cpp

+27-16
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class TypeCaseValues {
3939
if (std::holds_alternative<parser::Default>(guard.u)) {
4040
typeCases_.emplace_back(stmt, std::nullopt);
4141
} else if (std::optional<evaluate::DynamicType> type{GetGuardType(guard)}) {
42-
if (PassesChecksOnGuard(guard, *type)) {
42+
if (PassesChecksOnGuard(stmt, *type)) {
4343
typeCases_.emplace_back(stmt, *type);
4444
} else {
4545
hasErrors_ = true;
@@ -71,35 +71,46 @@ class TypeCaseValues {
7171
guard.u);
7272
}
7373

74-
bool PassesChecksOnGuard(const parser::TypeGuardStmt::Guard &guard,
74+
bool PassesChecksOnGuard(const parser::Statement<parser::TypeGuardStmt> &stmt,
7575
const evaluate::DynamicType &guardDynamicType) {
76+
const parser::TypeGuardStmt &typeGuardStmt{stmt.statement};
77+
const auto &guard{std::get<parser::TypeGuardStmt::Guard>(typeGuardStmt.t)};
7678
return std::visit(
7779
common::visitors{
7880
[](const parser::Default &) { return true; },
7981
[&](const parser::TypeSpec &typeSpec) {
80-
if (const DeclTypeSpec * spec{typeSpec.declTypeSpec}) {
82+
const DeclTypeSpec *spec{typeSpec.declTypeSpec};
83+
CHECK(spec);
84+
CHECK(spec->AsIntrinsic() || spec->AsDerived());
85+
bool typeSpecRetVal{false};
86+
if (spec->AsIntrinsic()) {
87+
typeSpecRetVal = true;
88+
if (!selectorType_.IsUnlimitedPolymorphic()) { // C1162
89+
context_.Say(stmt.source,
90+
"If selector is not unlimited polymorphic, "
91+
"an intrinsic type specification must not be specified "
92+
"in the type guard statement"_err_en_US);
93+
typeSpecRetVal = false;
94+
}
8195
if (spec->category() == DeclTypeSpec::Character &&
8296
!guardDynamicType.IsAssumedLengthCharacter()) { // C1160
8397
context_.Say(parser::FindSourceLocation(typeSpec),
8498
"The type specification statement must have "
8599
"LEN type parameter as assumed"_err_en_US);
86-
return false;
100+
typeSpecRetVal = false;
87101
}
88-
if (const DerivedTypeSpec * derived{spec->AsDerived()}) {
89-
return PassesDerivedTypeChecks(
90-
*derived, parser::FindSourceLocation(typeSpec));
91-
}
92-
return false;
102+
} else {
103+
const DerivedTypeSpec *derived{spec->AsDerived()};
104+
typeSpecRetVal = PassesDerivedTypeChecks(
105+
*derived, parser::FindSourceLocation(typeSpec));
93106
}
94-
return false;
107+
return typeSpecRetVal;
95108
},
96109
[&](const parser::DerivedTypeSpec &x) {
97-
if (const semantics::DerivedTypeSpec *
98-
derived{x.derivedTypeSpec}) {
99-
return PassesDerivedTypeChecks(
100-
*derived, parser::FindSourceLocation(x));
101-
}
102-
return false;
110+
CHECK(x.derivedTypeSpec);
111+
const semantics::DerivedTypeSpec *derived{x.derivedTypeSpec};
112+
return PassesDerivedTypeChecks(
113+
*derived, parser::FindSourceLocation(x));
103114
},
104115
},
105116
guard.u);

flang/test/Semantics/selecttype01.f90

+18
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ subroutine CheckC1159b
119119
integer :: x
120120
!ERROR: Selector 'x' in SELECT TYPE statement must be polymorphic
121121
select type (a => x)
122+
!ERROR: If selector is not unlimited polymorphic, an intrinsic type specification must not be specified in the type guard statement
122123
type is (integer)
123124
print *,'integer ',a
124125
end select
@@ -127,6 +128,7 @@ subroutine CheckC1159b
127128
subroutine CheckC1159c
128129
!ERROR: Selector 'x' in SELECT TYPE statement must be polymorphic
129130
select type (a => x)
131+
!ERROR: If selector is not unlimited polymorphic, an intrinsic type specification must not be specified in the type guard statement
130132
type is (integer)
131133
print *,'integer ',a
132134
end select
@@ -164,6 +166,16 @@ subroutine CheckC1162
164166
type is (extsquare)
165167
!Handle same types
166168
type is (rectangle)
169+
!ERROR: If selector is not unlimited polymorphic, an intrinsic type specification must not be specified in the type guard statement
170+
type is(integer)
171+
!ERROR: If selector is not unlimited polymorphic, an intrinsic type specification must not be specified in the type guard statement
172+
type is(real)
173+
!ERROR: If selector is not unlimited polymorphic, an intrinsic type specification must not be specified in the type guard statement
174+
type is(logical)
175+
!ERROR: If selector is not unlimited polymorphic, an intrinsic type specification must not be specified in the type guard statement
176+
type is(character(len=*))
177+
!ERROR: If selector is not unlimited polymorphic, an intrinsic type specification must not be specified in the type guard statement
178+
type is(complex)
167179
end select
168180

169181
!Unlimited polymorphic objects are allowed.
@@ -187,6 +199,12 @@ subroutine CheckC1163
187199
!ERROR: Type specification 'square' conflicts with previous type specification
188200
class is (square)
189201
end select
202+
select type (unlim_polymorphic)
203+
type is (INTEGER(4))
204+
type is (shape)
205+
!ERROR: Type specification 'INTEGER(4)' conflicts with previous type specification
206+
type is (INTEGER(4))
207+
end select
190208
end
191209

192210
subroutine CheckC1164

flang/test/Semantics/symbol11.f90

+5-3
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,12 @@ subroutine s3
7171
!DEF: /s3/Block1/y TARGET AssocEntity TYPE(t2)
7272
!REF: /s3/t2/a2
7373
i = y%a2
74-
type is (integer(kind=8))
74+
!REF: /s3/t1
75+
type is (t1)
7576
!REF: /s3/i
76-
!DEF: /s3/Block2/y TARGET AssocEntity INTEGER(8)
77-
i = y
77+
!DEF: /s3/Block2/y TARGET AssocEntity TYPE(t1)
78+
!REF: /s3/t1/a1
79+
i = y%a1
7880
class default
7981
!DEF: /s3/Block3/y TARGET AssocEntity CLASS(t1)
8082
print *, y

0 commit comments

Comments
 (0)