Skip to content

Commit c851ee3

Browse files
authored
[flang][OpenMP] catch namelist access through equivalence (#130804)
The standard prohibits privatising namelist variables. We also decided in #110671 to prohibit reductions of namelist variables. This commit prevents this rule from being circumvented through the use of equivalence statements. Fixes #122824
1 parent 0165ca3 commit c851ee3

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,24 @@ void OmpAttributeVisitor::ResolveOmpObjectList(
24042404
}
24052405
}
24062406

2407+
/// True if either symbol is in a namelist or some other symbol in the same
2408+
/// equivalence set as symbol is in a namelist.
2409+
static bool SymbolOrEquivalentIsInNamelist(const Symbol &symbol) {
2410+
auto isInNamelist{[](const Symbol &sym) {
2411+
const Symbol &ultimate{sym.GetUltimate()};
2412+
return ultimate.test(Symbol::Flag::InNamelist);
2413+
}};
2414+
2415+
const EquivalenceSet *eqv{FindEquivalenceSet(symbol)};
2416+
if (!eqv) {
2417+
return isInNamelist(symbol);
2418+
}
2419+
2420+
return llvm::any_of(*eqv, [isInNamelist](const EquivalenceObject &obj) {
2421+
return isInNamelist(obj.symbol);
2422+
});
2423+
}
2424+
24072425
void OmpAttributeVisitor::ResolveOmpObject(
24082426
const parser::OmpObject &ompObject, Symbol::Flag ompFlag) {
24092427
common::visit(
@@ -2468,15 +2486,14 @@ void OmpAttributeVisitor::ResolveOmpObject(
24682486
.str()));
24692487
}
24702488
if (ompFlag == Symbol::Flag::OmpReduction) {
2471-
const Symbol &ultimateSymbol{symbol->GetUltimate()};
24722489
// Using variables inside of a namelist in OpenMP reductions
24732490
// is allowed by the standard, but is not allowed for
24742491
// privatisation. This looks like an oversight. If the
24752492
// namelist is hoisted to a global, we cannot apply the
24762493
// mapping for the reduction variable: resulting in incorrect
24772494
// results. Disabling this hoisting could make some real
24782495
// production code go slower. See discussion in #109303
2479-
if (ultimateSymbol.test(Symbol::Flag::InNamelist)) {
2496+
if (SymbolOrEquivalentIsInNamelist(*symbol)) {
24802497
context_.Say(name->source,
24812498
"Variable '%s' in NAMELIST cannot be in a REDUCTION clause"_err_en_US,
24822499
name->ToString());
@@ -2838,7 +2855,7 @@ void OmpAttributeVisitor::CheckObjectIsPrivatizable(
28382855
clauseName = "LASTPRIVATE";
28392856
}
28402857

2841-
if (ultimateSymbol.test(Symbol::Flag::InNamelist)) {
2858+
if (SymbolOrEquivalentIsInNamelist(symbol)) {
28422859
context_.Say(name.source,
28432860
"Variable '%s' in NAMELIST cannot be in a %s clause"_err_en_US,
28442861
name.ToString(), clauseName.str());
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
! RUN: %python %S/../test_errors.py %s %flang -fopenmp
2+
3+
! The openmp standard only dissallows namelist for privatization, but flang
4+
! also does not allow it for reduction as this would be difficult to support.
5+
!
6+
! Variables in equivalence with variables in the namelist pose the same
7+
! implementation problems.
8+
9+
subroutine test01()
10+
integer::va
11+
equivalence (va,vva)
12+
namelist /na1/vva
13+
va=1
14+
15+
!ERROR: Variable 'va' in NAMELIST cannot be in a REDUCTION clause
16+
!$omp parallel reduction(+:va)
17+
write(*,na1)
18+
!$omp end parallel
19+
end subroutine test01
20+
21+
22+
subroutine test02()
23+
integer::va
24+
equivalence (va,vva)
25+
namelist /na1/vva
26+
va=1
27+
28+
!ERROR: Variable 'va' in NAMELIST cannot be in a PRIVATE clause
29+
!$omp parallel private(va)
30+
write(*,na1)
31+
!$omp end parallel
32+
end subroutine test02

0 commit comments

Comments
 (0)