Skip to content

Commit

Permalink
[flang] Fix bogus error from assignment to CLASS(*)
Browse files Browse the repository at this point in the history
Assignment semantics was coughing up bad errors and crashes for
intrinsic assignments to unlimited polymorphic entities while
looking for any (impossible) user defined ASSIGNMENT(=) generic
or intrinsic type conversion.

Differential Revision: https://reviews.llvm.org/D122440
  • Loading branch information
klausler committed Mar 25, 2022
1 parent 3784e8c commit 0363a16
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 6 deletions.
8 changes: 6 additions & 2 deletions flang/lib/Semantics/expression.cpp
Expand Up @@ -3595,7 +3595,8 @@ const Symbol *ArgumentAnalyzer::FindBoundOp(
void ArgumentAnalyzer::AddAssignmentConversion(
const DynamicType &lhsType, const DynamicType &rhsType) {
if (lhsType.category() == rhsType.category() &&
lhsType.kind() == rhsType.kind()) {
(lhsType.category() == TypeCategory::Derived ||
lhsType.kind() == rhsType.kind())) {
// no conversion necessary
} else if (auto rhsExpr{evaluate::ConvertToType(lhsType, MoveExpr(1))}) {
std::optional<parser::CharBlock> source;
Expand Down Expand Up @@ -3684,7 +3685,10 @@ std::string ArgumentAnalyzer::TypeAsFortran(std::size_t i) {
if (i >= actuals_.size() || !actuals_[i]) {
return "missing argument";
} else if (std::optional<DynamicType> type{GetType(i)}) {
return type->category() == TypeCategory::Derived
return type->IsAssumedType() ? "TYPE(*)"s
: type->IsUnlimitedPolymorphic() ? "CLASS(*)"s
: type->IsPolymorphic() ? "CLASS("s + type->AsFortran() + ')'
: type->category() == TypeCategory::Derived
? "TYPE("s + type->AsFortran() + ')'
: type->category() == TypeCategory::Character
? "CHARACTER(KIND="s + std::to_string(type->kind()) + ')'
Expand Down
3 changes: 3 additions & 0 deletions flang/lib/Semantics/tools.cpp
Expand Up @@ -103,6 +103,9 @@ Tristate IsDefinedAssignment(
if (!lhsType || !rhsType) {
return Tristate::No; // error or rhs is untyped
}
if (lhsType->IsUnlimitedPolymorphic() || rhsType->IsUnlimitedPolymorphic()) {
return Tristate::No;
}
TypeCategory lhsCat{lhsType->category()};
TypeCategory rhsCat{rhsType->category()};
if (rhsRank > 0 && lhsRank != rhsRank) {
Expand Down
19 changes: 17 additions & 2 deletions flang/test/Semantics/resolve63.f90
Expand Up @@ -265,9 +265,9 @@ subroutine test(x, y, z)
i = x + y
i = x + i
i = y + i
!ERROR: No intrinsic or user-defined OPERATOR(+) matches operand types TYPE(t2) and TYPE(t1)
!ERROR: No intrinsic or user-defined OPERATOR(+) matches operand types CLASS(t2) and CLASS(t1)
i = y + x
!ERROR: No intrinsic or user-defined OPERATOR(+) matches operand types INTEGER(4) and TYPE(t1)
!ERROR: No intrinsic or user-defined OPERATOR(+) matches operand types INTEGER(4) and CLASS(t1)
i = i + x
end
end
Expand Down Expand Up @@ -344,3 +344,18 @@ subroutine test
call generic(null(), null())
end subroutine
end

! Ensure no bogus errors for assignments to CLASS(*) allocatable
module m10
type :: t1
integer :: n
end type
contains
subroutine test
class(*), allocatable :: poly
poly = 1
poly = 3.14159
poly = 'Il faut imaginer Sisyphe heureux'
poly = t1(1)
end subroutine
end module
4 changes: 2 additions & 2 deletions flang/test/Semantics/selecttype03.f90
Expand Up @@ -99,11 +99,11 @@ function foo(i)
integer :: i
class(t1),DIMENSION(:),allocatable :: foo
integer, dimension(2) :: U
U = (/ 1,2 /)
U = (/ 1,2 /)
if (i>0) then
foo = array1(2,U)
else if (i<0) then
!ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches operand types TYPE(t1) and TYPE(t2)
!ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches operand types CLASS(t1) and CLASS(t2)
foo = array2(2,U)
end if
end function
Expand Down

0 comments on commit 0363a16

Please sign in to comment.