Skip to content

Commit cfc0df9

Browse files
author
git apple-llvm automerger
committed
Merge commit '2780c209e1e2' from llvm.org/main into next
2 parents 68d3077 + 2780c20 commit cfc0df9

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

flang/docs/Extensions.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,17 @@ end
557557
generic intrinsic function's inferred result type does not
558558
match an explicit declaration. This message is a warning.
559559

560+
* There is no restriction in the standard against assigning
561+
to a whole polymorphic allocatable under control of a `WHERE`
562+
construct or statement, but there is no good portable
563+
behavior to implement and the standard isn't entirely clear
564+
what it should mean.
565+
(Other compilers allow it, but the results are never meaningful;
566+
some never change the type, some change the type according to
567+
the value of the last mask element, some treat these
568+
assignment statements as no-ops, and the rest crash during compilation.)
569+
The compiler flags this case as an error.
570+
560571
## Standard features that might as well not be
561572

562573
* f18 supports designators with constant expressions, properly

flang/lib/Semantics/assignment.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class AssignmentContext {
4141
void PopWhereContext();
4242
void Analyze(const parser::AssignmentStmt &);
4343
void Analyze(const parser::PointerAssignmentStmt &);
44-
void Analyze(const parser::ConcurrentControl &);
4544
SemanticsContext &context() { return context_; }
4645

4746
private:
@@ -76,6 +75,11 @@ void AssignmentContext::Analyze(const parser::AssignmentStmt &stmt) {
7675
whole{evaluate::UnwrapWholeSymbolOrComponentDataRef(lhs)}) {
7776
if (IsAllocatable(whole->GetUltimate())) {
7877
flags.set(DefinabilityFlag::PotentialDeallocation);
78+
if (IsPolymorphic(*whole) && whereDepth_ > 0) {
79+
Say(lhsLoc,
80+
"Assignment to whole polymorphic allocatable '%s' may not be nested in a WHERE statement or construct"_err_en_US,
81+
whole->name());
82+
}
7983
}
8084
}
8185
if (auto whyNot{WhyNotDefinable(lhsLoc, scope, flags, lhs)}) {

flang/test/Semantics/bug133669.f90

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
!RUN: %python %S/test_errors.py %s %flang_fc1
2+
module m
3+
contains
4+
subroutine s(x, y, mask)
5+
class(*), allocatable, intent(in out) :: x(:), y(:)
6+
logical, intent(in) :: mask(:)
7+
select type(x)
8+
type is(integer)
9+
print *, 'before, x is integer', x
10+
type is(real)
11+
print *, 'before, x is real', x
12+
class default
13+
print *, 'before, x has some other type'
14+
end select
15+
select type(y)
16+
type is(integer)
17+
print *, 'y is integer', y
18+
type is(real)
19+
print *, 'y is real', y
20+
end select
21+
print *, 'mask', mask
22+
!ERROR: Assignment to whole polymorphic allocatable 'x' may not be nested in a WHERE statement or construct
23+
where(mask) x = y
24+
select type(x)
25+
type is(integer)
26+
print *, 'after, x is integer', x
27+
type is(real)
28+
print *, 'after, x is real', x
29+
class default
30+
print *, 'before, x has some other type'
31+
end select
32+
print *
33+
end
34+
end
35+
36+
program main
37+
use m
38+
class(*), allocatable :: x(:), y(:)
39+
x = [1, 2]
40+
y = [3., 4.]
41+
call s(x, y, [.false., .false.])
42+
x = [1, 2]
43+
y = [3., 4.]
44+
call s(x, y, [.false., .true.])
45+
x = [1, 2]
46+
y = [3., 4.]
47+
call s(x, y, [.true., .false.])
48+
x = [1, 2]
49+
y = [3., 4.]
50+
call s(x, y, [.true., .true.])
51+
end program main

0 commit comments

Comments
 (0)