Skip to content

Commit a1ac5a5

Browse files
authored
[flang] Allow OpenMP declarations before type declarations (llvm#112414)
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 llvm#106021.
1 parent 3764d0f commit a1ac5a5

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) {
@@ -2557,8 +2581,10 @@ void ScopeHandler::ApplyImplicitRules(
25572581
return;
25582582
}
25592583
if (const DeclTypeSpec * type{GetImplicitType(symbol)}) {
2560-
symbol.set(Symbol::Flag::Implicit);
2561-
symbol.SetType(*type);
2584+
if (!skipImplicitTyping_) {
2585+
symbol.set(Symbol::Flag::Implicit);
2586+
symbol.SetType(*type);
2587+
}
25622588
return;
25632589
}
25642590
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)