Skip to content

Commit 300370c

Browse files
authored
[flang] Catch I/O statement error (#116647)
Fortran doesn't have unformatted internal I/O, so catch attempts to use internal units without a format or namelist specifier. Fixes #116586.
1 parent 73216cd commit 300370c

File tree

4 files changed

+17
-5
lines changed

4 files changed

+17
-5
lines changed

flang/lib/Semantics/check-io.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,8 @@ void IoChecker::Leave(const parser::WriteStmt &writeStmt) {
860860

861861
void IoChecker::LeaveReadWrite() const {
862862
CheckForRequiredSpecifier(IoSpecKind::Unit); // C1211
863+
CheckForRequiredSpecifier(flags_.test(Flag::InternalUnit),
864+
"UNIT=internal-file", flags_.test(Flag::FmtOrNml), "FMT or NML");
863865
CheckForProhibitedSpecifier(IoSpecKind::Nml, IoSpecKind::Rec); // C1216
864866
CheckForProhibitedSpecifier(IoSpecKind::Nml, IoSpecKind::Fmt); // C1216
865867
CheckForProhibitedSpecifier(

flang/test/Semantics/io03.f90

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@
5858
read(internal_file2, *) jj
5959
read(internal_file4, *) jj
6060

61+
!This is a valid statement but it's not what it looks like; "(internal-file)"
62+
!must be parsed as a format expression, not as an internal unit.
63+
read(internal_file) jj
64+
65+
!ERROR: If UNIT=internal-file appears, FMT or NML must also appear
66+
read(internal_file, iostat=stat1) jj
67+
6168
!ERROR: Internal file must not have a vector subscript
6269
read(internal_fileA(vv), *) jj
6370

@@ -106,11 +113,12 @@
106113
!ERROR: If UNIT=* appears, POS must not appear
107114
read(*, pos=13)
108115

116+
!ERROR: If UNIT=internal-file appears, FMT or NML must also appear
109117
!ERROR: If UNIT=internal-file appears, REC must not appear
110118
read(internal_file, rec=13)
111119

112120
!ERROR: If UNIT=internal-file appears, POS must not appear
113-
read(internal_file, pos=13)
121+
read(internal_file, *, pos=13)
114122

115123
!ERROR: If REC appears, END must not appear
116124
read(10, fmt='(I4)', end=9, rec=13) jj
@@ -135,7 +143,7 @@
135143
read(*, asynchronous='yes')
136144

137145
!ERROR: If ASYNCHRONOUS='YES' appears, UNIT=number must also appear
138-
read(internal_file, asynchronous='y'//'es')
146+
read(internal_file, *, asynchronous='y'//'es')
139147

140148
!ERROR: If ID appears, ASYNCHRONOUS='YES' must also appear
141149
read(10, id=id)

flang/test/Semantics/io04.f90

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
write(unit=10) 'Ok'
3535
write(*, nnn)
3636
write(10, nnn)
37+
!ERROR: If UNIT=internal-file appears, FMT or NML must also appear
3738
write(internal_file)
3839
write(internal_file, *)
3940
write(internal_file, fmt=*)
@@ -55,7 +56,7 @@
5556
allocate(a(8), stat=stat8)
5657

5758
!ERROR: Duplicate UNIT specifier
58-
write(internal_file, unit=*)
59+
write(internal_file, unit=*, fmt=*)
5960

6061
!ERROR: WRITE statement must have a UNIT specifier
6162
write(nml=nnn)
@@ -84,6 +85,7 @@
8485
!ERROR: If UNIT=internal-file appears, POS must not appear
8586
write(internal_file, err=9, pos=n, nml=nnn)
8687

88+
!ERROR: If UNIT=internal-file appears, FMT or NML must also appear
8789
!ERROR: If UNIT=internal-file appears, REC must not appear
8890
write(internal_file, rec=n, err=9)
8991

@@ -106,7 +108,7 @@
106108
write(*, asynchronous='yes')
107109

108110
!ERROR: If ASYNCHRONOUS='YES' appears, UNIT=number must also appear
109-
write(internal_file, asynchronous='yes')
111+
write(internal_file, *, asynchronous='yes')
110112

111113
!ERROR: If ID appears, ASYNCHRONOUS='YES' must also appear
112114
write(10, *, id=id) "Ok"

flang/test/Semantics/undef-result01.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ function defdByNamelist()
117117
end
118118

119119
character(4) function defdByWrite()
120-
write(defdByWrite) 'abcd'
120+
write(defdByWrite,*) 'abcd'
121121
end
122122

123123
integer function defdBySize()

0 commit comments

Comments
 (0)