Skip to content

Commit baba204

Browse files
committed
[flang] Allow OpenMP declarations before type declarations
Skip resolving implicit types for OpenMP declarative directives, to allow them to appear before type declarations, which is supported by several compilers. This was discussed in https://discourse.llvm.org/t/rfc-openmp-should-type-declaration-be-allowed-after-threadprivate/81345. This fixes the semantic errors of #106021.
1 parent 73c9ad2 commit baba204

File tree

4 files changed

+84
-7
lines changed

4 files changed

+84
-7
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,7 @@ class ScopeHandler : public ImplicitRulesVisitor {
720720

721721
bool inSpecificationPart_{false};
722722
bool deferImplicitTyping_{false};
723+
bool skipImplicitTyping_{false};
723724
bool inEquivalenceStmt_{false};
724725

725726
// Some information is collected from a specification part for deferred
@@ -758,6 +759,10 @@ class ScopeHandler : public ImplicitRulesVisitor {
758759
}
759760
}
760761

762+
void SkipImplicitTyping(bool skip) {
763+
deferImplicitTyping_ = skipImplicitTyping_ = skip;
764+
}
765+
761766
private:
762767
Scope *currScope_{nullptr};
763768
FuncResultStack funcResultStack_{*this};
@@ -1506,6 +1511,25 @@ class OmpVisitor : public virtual DeclarationVisitor {
15061511
void Post(const parser::OmpEndCriticalDirective &) {
15071512
messageHandler().set_currStmtSource(std::nullopt);
15081513
}
1514+
bool Pre(const parser::OpenMPThreadprivate &) {
1515+
SkipImplicitTyping(true);
1516+
return true;
1517+
}
1518+
void Post(const parser::OpenMPThreadprivate &) { SkipImplicitTyping(false); }
1519+
bool Pre(const parser::OpenMPDeclareTargetConstruct &) {
1520+
SkipImplicitTyping(true);
1521+
return true;
1522+
}
1523+
void Post(const parser::OpenMPDeclareTargetConstruct &) {
1524+
SkipImplicitTyping(false);
1525+
}
1526+
bool Pre(const parser::OpenMPDeclarativeAllocate &) {
1527+
SkipImplicitTyping(true);
1528+
return true;
1529+
}
1530+
void Post(const parser::OpenMPDeclarativeAllocate &) {
1531+
SkipImplicitTyping(false);
1532+
}
15091533
};
15101534

15111535
bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) {
@@ -2556,8 +2580,10 @@ void ScopeHandler::ApplyImplicitRules(
25562580
return;
25572581
}
25582582
if (const DeclTypeSpec * type{GetImplicitType(symbol)}) {
2559-
symbol.set(Symbol::Flag::Implicit);
2560-
symbol.SetType(*type);
2583+
if (!skipImplicitTyping_) {
2584+
symbol.set(Symbol::Flag::Implicit);
2585+
symbol.SetType(*type);
2586+
}
25612587
return;
25622588
}
25632589
if (symbol.has<ProcEntityDetails>() && !symbol.attrs().test(Attr::EXTERNAL)) {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
! RUN: %flang -fsyntax-only -fopenmp %s 2>&1
2+
3+
! Check that OpenMP declarative directives can be used with objects that have
4+
! an incomplete type.
5+
6+
subroutine test_decl
7+
! OMPv5.2 5.2 threadprivate
8+
! OMPv5.2 6.5 allocate
9+
implicit none
10+
save :: x1, y1
11+
!$omp threadprivate(x1)
12+
!$omp allocate(y1)
13+
integer :: x1, y1
14+
15+
! OMPv5.2 7.7 declare-simd
16+
external :: simd_func
17+
!$omp declare simd(simd_func)
18+
logical :: simd_func
19+
20+
! OMPv5.2 7.8.1 declare-target
21+
allocatable :: j
22+
!$omp declare target(j)
23+
save :: j
24+
real(kind=8) :: j(:)
25+
26+
! OMPv5.2 5.5.11 declare-reduction - crashes
27+
!external :: my_add_red
28+
!!$omp declare reduction(my_add_red : integer : my_add_red(omp_out, omp_in)) &
29+
!!$omp& initializer(omp_priv=0)
30+
!integer :: my_add_red
31+
end subroutine
32+
33+
subroutine test_decl2
34+
save x1, y1
35+
!$omp threadprivate(x1)
36+
!$omp allocate(y1)
37+
integer :: x1, y1
38+
39+
! implicit decl
40+
!$omp threadprivate(x2)
41+
!$omp allocate(y2)
42+
save x2, y2
43+
end subroutine
44+
45+
module m1
46+
! implicit decl
47+
!$omp threadprivate(x, y, z)
48+
integer :: y
49+
real :: z
50+
51+
contains
52+
subroutine sub
53+
!$omp parallel copyin(x, y, z)
54+
!$omp end parallel
55+
end subroutine
56+
end module

flang/test/Semantics/OpenMP/declare-target06.f90

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,16 @@
66

77
module test_0
88
implicit none
9-
!ERROR: The given DECLARE TARGET directive clause has an invalid argument
109
!ERROR: No explicit type declared for 'no_implicit_materialization_1'
1110
!$omp declare target(no_implicit_materialization_1)
1211

13-
!ERROR: The given DECLARE TARGET directive clause has an invalid argument
1412
!ERROR: No explicit type declared for 'no_implicit_materialization_2'
1513
!$omp declare target link(no_implicit_materialization_2)
1614

17-
!ERROR: The given DECLARE TARGET directive clause has an invalid argument
1815
!WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
1916
!ERROR: No explicit type declared for 'no_implicit_materialization_3'
2017
!$omp declare target to(no_implicit_materialization_3)
2118

22-
!ERROR: The given DECLARE TARGET directive clause has an invalid argument
23-
!ERROR: No explicit type declared for 'no_implicit_materialization_3'
2419
!$omp declare target enter(no_implicit_materialization_3)
2520

2621
INTEGER :: data_int = 10

0 commit comments

Comments
 (0)