Skip to content

Commit 7c512ce

Browse files
authored
[flang] Disallow references to some IEEE procedures in DO CONCURRENT (#102082)
There's a numbered constraint that prohibits calls to some IEEE arithmetic and exception procedures within the body of a DO CONCURRENT construct. Clean up the implementation to catch missing cases.
1 parent 9390eb9 commit 7c512ce

File tree

3 files changed

+37
-29
lines changed

3 files changed

+37
-29
lines changed

flang/lib/Semantics/check-do-forall.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -285,19 +285,32 @@ class DoConcurrentBodyEnforce {
285285
.Attach(doConcurrentSourcePosition_, GetEnclosingDoMsg());
286286
}
287287

288-
// C1139: call to impure procedure and ...
289-
// C1141: cannot call ieee_get_flag, ieee_[gs]et_halting_mode
290-
// It's not necessary to check the ieee_get* procedures because they're
291-
// not pure, and impure procedures are caught by checks for constraint C1139
288+
// C1145, C1146: cannot call ieee_[gs]et_flag, ieee_[gs]et_halting_mode,
289+
// ieee_[gs]et_status, ieee_set_rounding_mode, or ieee_set_underflow_mode
292290
void Post(const parser::ProcedureDesignator &procedureDesignator) {
293291
if (auto *name{std::get_if<parser::Name>(&procedureDesignator.u)}) {
294-
if (name->symbol &&
295-
fromScope(*name->symbol, "__fortran_ieee_exceptions"s)) {
296-
if (name->source == "ieee_set_halting_mode") {
297-
SayWithDo(context_, currentStatementSourcePosition_,
298-
"IEEE_SET_HALTING_MODE is not allowed in DO "
299-
"CONCURRENT"_err_en_US,
300-
doConcurrentSourcePosition_);
292+
if (name->symbol) {
293+
const Symbol &ultimate{name->symbol->GetUltimate()};
294+
const Scope &scope{ultimate.owner()};
295+
if (const Symbol * module{scope.IsModule() ? scope.symbol() : nullptr};
296+
module &&
297+
(module->name() == "__fortran_ieee_arithmetic" ||
298+
module->name() == "__fortran_ieee_exceptions")) {
299+
std::string s{ultimate.name().ToString()};
300+
static constexpr const char *badName[]{"ieee_get_flag",
301+
"ieee_set_flag", "ieee_get_halting_mode", "ieee_set_halting_mode",
302+
"ieee_get_status", "ieee_set_status", "ieee_set_rounding_mode",
303+
"ieee_set_underflow_mode", nullptr};
304+
for (std::size_t j{0}; badName[j]; ++j) {
305+
if (s.find(badName[j]) != s.npos) {
306+
context_
307+
.Say(name->source,
308+
"'%s' may not be called in DO CONCURRENT"_err_en_US,
309+
badName[j])
310+
.Attach(doConcurrentSourcePosition_, GetEnclosingDoMsg());
311+
break;
312+
}
313+
}
301314
}
302315
}
303316
}
@@ -318,15 +331,6 @@ class DoConcurrentBodyEnforce {
318331
}
319332

320333
private:
321-
bool fromScope(const Symbol &symbol, const std::string &moduleName) {
322-
if (symbol.GetUltimate().owner().IsModule() &&
323-
symbol.GetUltimate().owner().GetName().value().ToString() ==
324-
moduleName) {
325-
return true;
326-
}
327-
return false;
328-
}
329-
330334
std::set<parser::Label> labels_;
331335
parser::CharBlock currentStatementSourcePosition_;
332336
SemanticsContext &context_;

flang/module/__fortran_ieee_exceptions.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ end subroutine ieee_set_modes_0
129129
public :: ieee_set_modes
130130

131131
interface ieee_set_status
132-
subroutine ieee_set_status_0(status)
132+
pure subroutine ieee_set_status_0(status)
133133
import ieee_status_type
134134
type(ieee_status_type), intent(in) :: status
135135
end subroutine ieee_set_status_0

flang/test/Semantics/doconcurrent01.f90

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,22 @@ subroutine do_concurrent_test2(i,j,n,flag)
4848
change team (j)
4949
!ERROR: An image control statement is not allowed in DO CONCURRENT
5050
critical
51-
call ieee_get_status(status) ! ok
52-
!ERROR: IEEE_SET_HALTING_MODE is not allowed in DO CONCURRENT
53-
call ieee_set_halting_mode(flag, halting)
5451
end critical
5552
end team
5653
!ERROR: ADVANCE specifier is not allowed in DO CONCURRENT
5754
write(*,'(a35)',advance='no')
58-
end do
59-
60-
! The following is OK
61-
do concurrent (i = 1:n)
62-
call ieee_set_flag(flag, flagValue)
55+
!ERROR: 'ieee_get_status' may not be called in DO CONCURRENT
56+
call ieee_get_status(status)
57+
!ERROR: 'ieee_set_status' may not be called in DO CONCURRENT
58+
call ieee_set_status(status)
59+
!ERROR: 'ieee_get_halting_mode' may not be called in DO CONCURRENT
60+
call ieee_get_halting_mode(flag, halting)
61+
!ERROR: 'ieee_set_halting_mode' may not be called in DO CONCURRENT
62+
call ieee_set_halting_mode(flag, halting)
63+
!ERROR: 'ieee_get_flag' may not be called in DO CONCURRENT
64+
call ieee_get_flag(flag, flagValue)
65+
!ERROR: 'ieee_set_flag' may not be called in DO CONCURRENT
66+
call ieee_set_flag(flag, flagValue)
6367
end do
6468
end subroutine do_concurrent_test2
6569

0 commit comments

Comments
 (0)