Hello

I have now backported a number of OpenMP-related patches from master to devel/omp/gcc-10. These are:

- Fortran: Fix character-kind=4 substring resolution (PR95837) (commit f48bffe70cba310461ec19ffcd07c573a6b86575) - libgomp.fortran/struct-elem-map-1.f90: Add char kind=4 tests (commit e0685fadb6aa7c9cc895bc14cbbe2b9026fa3a94) - OpenMP: Fixes for omp critical + hint (commit c7c24828cfa4983ebc6744be3f913d0da6ff7163) - critical-hint-*.{c,f90}: Move from gcc/testsuite to libgomp/testsuite (commit ade6e7204ce4d179cd9fa4637ddee85ba1fa12d9) - openmp: Handle clauses with gimple sequences in convert_nonlocal_omp_clauses properly (commit 676b5525e8333005bdc1c596ed086f1da27a450f) - Fortran/OpenMP: Fix detecting not perfectly nested loops (commit 57dd9f3bfca8bb752c630431dc033c761e2ad382)

Kwok
From 1e3e1fb54ace591926e80fccbf39d518a9dd7ca6 Mon Sep 17 00:00:00 2001
From: Kwok Cheung Yeung <k...@codesourcery.com>
Date: Tue, 18 Aug 2020 04:35:43 -0700
Subject: [PATCH 1/6] Fortran: Fix character-kind=4 substring resolution
 (PR95837)

This is a backport from master of commit
f48bffe70cba310461ec19ffcd07c573a6b86575.

Testing showed that it is always set and its value matches
always ts->kind (if available) or otherwise, if it is a variable,
the sym->ts.kind.

gcc/fortran/ChangeLog:

        PR fortran/95837
        * resolve.c (gfc_resolve_substring_charlen): Remove
        bogus ts.kind setting for the expression.

gcc/testsuite/ChangeLog:

        PR fortran/95837
        * gfortran.dg/char4-subscript.f90: New test.
---
 gcc/fortran/ChangeLog.omp                     |  9 ++++++++
 gcc/fortran/resolve.c                         |  3 ---
 gcc/testsuite/ChangeLog.omp                   |  8 +++++++
 gcc/testsuite/gfortran.dg/char4-subscript.f90 | 30 +++++++++++++++++++++++++++
 4 files changed, 47 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/char4-subscript.f90

diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index 00c6be0..a6b7452 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -1,3 +1,12 @@
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
+       2020-06-25  Tobias Burnus  <tob...@codesourcery.com>
+
+       PR fortran/95837
+       * resolve.c (gfc_resolve_substring_charlen): Remove
+       bogus ts.kind setting for the expression.
+
 2020-08-14  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 3166cc3..c05be55 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5140,9 +5140,6 @@ gfc_resolve_substring_charlen (gfc_expr *e)
        return;
     }
 
-  e->ts.type = BT_CHARACTER;
-  e->ts.kind = gfc_default_character_kind;
-
   if (!e->ts.u.cl)
     e->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
 
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 8f652f4..e9d589f 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,11 @@
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
+       2020-06-25  Tobias Burnus  <tob...@codesourcery.com>
+
+       PR fortran/95837
+       * gfortran.dg/char4-subscript.f90: New test.
+
 2020-08-14  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
diff --git a/gcc/testsuite/gfortran.dg/char4-subscript.f90 
b/gcc/testsuite/gfortran.dg/char4-subscript.f90
new file mode 100644
index 0000000..f1f915c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/char4-subscript.f90
@@ -0,0 +1,30 @@
+! { dg-do run }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/95837
+!
+type t
+  character(len=:, kind=4), pointer :: str2
+end type t
+type(t) :: var
+
+allocate(character(len=5, kind=4) :: var%str2)
+
+var%str2(1:1) = 4_"d"
+var%str2(2:3) = 4_"ef"
+var%str2(4:4) = achar(int(Z'1F600'), kind=4)
+var%str2(5:5) = achar(int(Z'1F608'), kind=4)
+
+if (var%str2(1:3) /= 4_"def") stop 1
+if (ichar(var%str2(4:4)) /= int(Z'1F600')) stop 2
+if (ichar(var%str2(5:5)) /= int(Z'1F608')) stop 2
+
+deallocate(var%str2)
+end
+
+! Note: the last '\x00' is regarded as string terminator, hence, the tailing 
\0 byte is not in the dump
+
+! { dg-final { scan-tree-dump "  \\(\\*var\\.str2\\)\\\[1\\\]{lb: 1 sz: 4} = 
.d\\\\x00\\\\x00.\\\[1\\\]{lb: 1 sz: 4};" "original" } }
+! { dg-final { scan-tree-dump "  __builtin_memmove \\(\\(void \\*\\) 
&\\(\\*var.str2\\)\\\[2\\\]{lb: 1 sz: 4}, \\(void \\*\\) 
&.e\\\\x00\\\\x00\\\\x00f\\\\x00\\\\x00.\\\[1\\\]{lb: 1 sz: 4}, 8\\);" 
"original" } }
+! { dg-final { scan-tree-dump "  \\(\\*var.str2\\)\\\[4\\\]{lb: 1 sz: 4} = 
.\\\\x00\\\\xf6\\\\x01.\\\[1\\\]{lb: 1 sz: 4};" "original" } }
+! { dg-final { scan-tree-dump "  \\(\\*var.str2\\)\\\[5\\\]{lb: 1 sz: 4} = 
.\\\\b\\\\xf6\\\\x01.\\\[1\\\]{lb: 1 sz: 4};" "original" } }
-- 
2.8.1

From 4120e9973c6989ae7787776371aa1b3aff856d03 Mon Sep 17 00:00:00 2001
From: Kwok Cheung Yeung <k...@codesourcery.com>
Date: Tue, 18 Aug 2020 04:39:49 -0700
Subject: [PATCH 2/6] libgomp.fortran/struct-elem-map-1.f90: Add char kind=4
 tests

This is a backport from master of commit
e0685fadb6aa7c9cc895bc14cbbe2b9026fa3a94.

As the Fortran PR 95837 has been fixed, the test could be be added.

libgomp/ChangeLog:

        * testsuite/libgomp.fortran/struct-elem-map-1.f90: Remove unused
        variables; add character(kind=4) tests; update TODO comment.
---
 libgomp/ChangeLog.omp                              |   8 ++
 .../libgomp.fortran/struct-elem-map-1.f90          | 160 +++++++++++++++------
 2 files changed, 128 insertions(+), 40 deletions(-)

diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index ce7d7f5..ffdfc75 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,3 +1,11 @@
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
+       2020-07-15  Tobias Burnus  <tob...@codesourcery.com>
+
+       * testsuite/libgomp.fortran/struct-elem-map-1.f90: Remove unused
+       variables; add character(kind=4) tests; update TODO comment.
+
 2020-08-14  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
diff --git a/libgomp/testsuite/libgomp.fortran/struct-elem-map-1.f90 
b/libgomp/testsuite/libgomp.fortran/struct-elem-map-1.f90
index f18eeb9..58550c7 100644
--- a/libgomp/testsuite/libgomp.fortran/struct-elem-map-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/struct-elem-map-1.f90
@@ -2,11 +2,9 @@
 !
 ! Test OpenMP 4.5 structure-element mapping
 
-! TODO: character(kind=4,...) needs to be tested, but depends on
-!       PR fortran/95837
-! TODO: ...%str4 should be tested but that currently fails due to
+! TODO: ...%str4 + %uni4 should be tested but that currently fails due to
 !       PR fortran/95868 (see commented lined)
-! TODO: Test also array-valued var, nested derived types,
+! TODO: Test also 'var' as array and/or pointer; nested derived types,
 !       type-extended types.
 
 program main
@@ -22,6 +20,10 @@ program main
     character(len=5) :: str2(4)
     character(len=:), pointer :: str3 => null()
     character(len=:), pointer :: str4(:) => null()
+    character(kind=4, len=5) :: uni1
+    character(kind=4, len=5) :: uni2(4)
+    character(kind=4, len=:), pointer :: uni3 => null()
+    character(kind=4, len=:), pointer :: uni4(:) => null()
   end type t2
 
   integer :: i
@@ -38,8 +40,7 @@ program main
 contains
   ! Implicitly mapped – but no pointers are mapped
   subroutine one() 
-    type(t2) :: var, var2(4)
-    type(t2), pointer :: var3, var4(:)
+    type(t2) :: var
 
     print '(g0)', '==== TESTCASE "one" ===='
 
@@ -47,11 +48,15 @@ contains
              b = 2, c = cmplx(-1.0_8, 2.0_8,kind=8), &
              d = [(-3*i, i = 1, 10)], &
              str1 = "abcde", &
-             str2 = ["12345", "67890", "ABCDE", "FGHIJ"])
+             str2 = ["12345", "67890", "ABCDE", "FGHIJ"], &
+             uni1 = 4_"abcde", &
+             uni2 = [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])
     allocate (var%e, source=99)
     allocate (var%f, source=[22, 33, 44, 55])
     allocate (var%str3, source="HelloWorld")
     allocate (var%str4, source=["Let's", "Go!!!"])
+    allocate (var%uni3, source=4_"HelloWorld")
+    allocate (var%uni4, source=[4_"Let's", 4_"Go!!!"])
 
     !$omp target map(tofrom:var)
       if (var%a /= 1) stop 1
@@ -60,15 +65,16 @@ contains
       if (any (var%d /= [(-3*i, i = 1, 10)])) stop 4
       if (var%str1 /= "abcde") stop 5
       if (any (var%str2 /= ["12345", "67890", "ABCDE", "FGHIJ"])) stop 6
+      if (var%uni1 /= 4_"abcde") stop 7
+      if (any (var%uni2 /= [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])) stop 
8
     !$omp end target
 
-    deallocate(var%e, var%f, var%str3, var%str4)
+    deallocate(var%e, var%f, var%str3, var%str4, var%uni3, var%uni4)
   end subroutine one
 
   ! Explicitly mapped – all and full arrays
   subroutine two() 
-    type(t2) :: var, var2(4)
-    type(t2), pointer :: var3, var4(:)
+    type(t2) :: var
 
     print '(g0)', '==== TESTCASE "two" ===='
 
@@ -76,14 +82,19 @@ contains
              b = 2, c = cmplx(-1.0_8, 2.0_8,kind=8), &
              d = [(-3*i, i = 1, 10)], &
              str1 = "abcde", &
-             str2 = ["12345", "67890", "ABCDE", "FGHIJ"])
+             str2 = ["12345", "67890", "ABCDE", "FGHIJ"], &
+             uni1 = 4_"abcde", &
+             uni2 = [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])
     allocate (var%e, source=99)
     allocate (var%f, source=[22, 33, 44, 55])
     allocate (var%str3, source="HelloWorld")
     allocate (var%str4, source=["Let's", "Go!!!"])
+    allocate (var%uni3, source=4_"HelloWorld")
+    allocate (var%uni4, source=[4_"Let's", 4_"Go!!!"])
 
     !$omp target map(tofrom: var%a, var%b, var%c, var%d, var%e, var%f, &
-    !$omp&                   var%str1, var%str2, var%str3, var%str4)
+    !$omp&                   var%str1, var%str2, var%str3, var%str4,   &
+    !$omp&                   var%uni1, var%uni2, var%uni3, var%uni4)
       if (var%a /= 1) stop 1
       if (var%b /= 2)  stop 2
       if (var%c%re /= -1.0_8 .or. var%c%im /= 2.0_8) stop 3
@@ -103,15 +114,24 @@ contains
       if (len (var%str4) /= 5) stop 16
       if (size (var%str4) /= 2) stop 17
       if (any (var%str4 /= ["Let's", "Go!!!"])) stop 18
+
+      if (var%uni1 /= 4_"abcde") stop 19
+      if (any (var%uni2 /= [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])) stop 
20
+      if (.not. associated (var%uni3)) stop 21
+      if (len (var%uni3) /= len (4_"HelloWorld")) stop 22
+      if (var%uni3 /= 4_"HelloWorld") stop 23
+      if (.not. associated (var%uni4)) stop 24
+      if (len (var%uni4) /= 5) stop 25
+      if (size (var%uni4) /= 2) stop 26
+      if (any (var%uni4 /= [4_"Let's", 4_"Go!!!"])) stop 27
     !$omp end target
 
-    deallocate(var%e, var%f, var%str3, var%str4)
+    deallocate(var%e, var%f, var%str3, var%str4, var%uni3, var%uni4)
   end subroutine two
 
   ! Explicitly mapped – one by one but full arrays
   subroutine three() 
-    type(t2) :: var, var2(4)
-    type(t2), pointer :: var3, var4(:)
+    type(t2) :: var
 
     print '(g0)', '==== TESTCASE "three" ===='
 
@@ -119,11 +139,15 @@ contains
              b = 2, c = cmplx(-1.0_8, 2.0_8,kind=8), &
              d = [(-3*i, i = 1, 10)], &
              str1 = "abcde", &
-             str2 = ["12345", "67890", "ABCDE", "FGHIJ"])
+             str2 = ["12345", "67890", "ABCDE", "FGHIJ"], &
+             uni1 = 4_"abcde", &
+             uni2 = [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])
     allocate (var%e, source=99)
     allocate (var%f, source=[22, 33, 44, 55])
     allocate (var%str3, source="HelloWorld")
     allocate (var%str4, source=["Let's", "Go!!!"])
+    allocate (var%uni3, source=4_"HelloWorld")
+    allocate (var%uni4, source=[4_"Let's", 4_"Go!!!"])
 
     !$omp target map(tofrom: var%a)
       if (var%a /= 1) stop 1
@@ -165,13 +189,30 @@ contains
       if (any (var%str4 /= ["Let's", "Go!!!"])) stop 18
     !$omp end target
 
-    deallocate(var%e, var%f, var%str3, var%str4)
+    !$omp target map(tofrom: var%uni1)
+      if (var%uni1 /= 4_"abcde") stop 19
+    !$omp end target
+    !$omp target map(tofrom: var%uni2)
+      if (any (var%uni2 /= [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])) stop 
20
+    !$omp end target
+    !$omp target map(tofrom: var%uni3)
+      if (.not. associated (var%uni3)) stop 21
+      if (len (var%uni3) /= len (4_"HelloWorld")) stop 22
+      if (var%uni3 /= 4_"HelloWorld") stop 23
+    !$omp end target
+    !$omp target map(tofrom: var%uni4)
+      if (.not. associated (var%uni4)) stop 24
+      if (len (var%uni4) /= 5) stop 25
+      if (size (var%uni4) /= 2) stop 26
+      if (any (var%uni4 /= [4_"Let's", 4_"Go!!!"])) stop 27
+    !$omp end target
+
+    deallocate(var%e, var%f, var%str3, var%str4, var%uni3, var%uni4)
   end subroutine three
 
   ! Explicitly mapped – all but only subarrays
   subroutine four() 
-    type(t2) :: var, var2(4)
-    type(t2), pointer :: var3, var4(:)
+    type(t2) :: var
 
     print '(g0)', '==== TESTCASE "four" ===='
 
@@ -179,12 +220,16 @@ contains
              b = 2, c = cmplx(-1.0_8, 2.0_8,kind=8), &
              d = [(-3*i, i = 1, 10)], &
              str1 = "abcde", &
-             str2 = ["12345", "67890", "ABCDE", "FGHIJ"])
+             str2 = ["12345", "67890", "ABCDE", "FGHIJ"], &
+             uni1 = 4_"abcde", &
+             uni2 = [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])
     allocate (var%f, source=[22, 33, 44, 55])
     allocate (var%str4, source=["Let's", "Go!!!"])
+    allocate (var%uni4, source=[4_"Let's", 4_"Go!!!"])
 
-!   !$omp target map(tofrom: var%d(4:7), var%f(2:3), var%str2(2:3), 
var%str4(2:2))
-    !$omp target map(tofrom: var%d(4:7), var%f(2:3), var%str2(2:3))
+!   !$omp target map(tofrom: var%d(4:7), var%f(2:3), var%str2(2:3)) &
+!   !$omp&       map(tofrom: var%str4(2:2), var%uni2(2:3), var%uni4(2:2))
+    !$omp target map(tofrom: var%d(4:7), var%f(2:3), var%str2(2:3), 
var%uni2(2:3))
       if (any (var%d(4:7) /= [(-3*i, i = 4, 7)])) stop 4
       if (any (var%str2(2:3) /= ["67890", "ABCDE"])) stop 6
 
@@ -195,6 +240,12 @@ contains
 !     if (len (var%str4) /= 5) stop 16
 !     if (size (var%str4) /= 2) stop 17
 !     if (var%str4(2) /= "Go!!!") stop 18
+
+      if (any (var%uni2(2:3) /= [4_"67890", 4_"ABCDE"])) stop 19
+!     if (.not. associated (var%uni4)) stop 20
+!     if (len (var%uni4) /= 5) stop 21
+!     if (size (var%uni4) /= 2) stop 22
+!     if (var%uni4(2) /= "Go!!!") stop 23
     !$omp end target
 
     deallocate(var%f, var%str4)
@@ -202,8 +253,7 @@ contains
 
   ! Explicitly mapped – all but only subarrays and one by one
   subroutine five() 
-    type(t2) :: var, var2(4)
-    type(t2), pointer :: var3, var4(:)
+    type(t2) :: var
 
     print '(g0)', '==== TESTCASE "five" ===='
 
@@ -211,7 +261,9 @@ contains
              b = 2, c = cmplx(-1.0_8, 2.0_8,kind=8), &
              d = [(-3*i, i = 1, 10)], &
              str1 = "abcde", &
-             str2 = ["12345", "67890", "ABCDE", "FGHIJ"])
+             str2 = ["12345", "67890", "ABCDE", "FGHIJ"], &
+             uni1 = 4_"abcde", &
+             uni2 = [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])
     allocate (var%f, source=[22, 33, 44, 55])
     allocate (var%str4, source=["Let's", "Go!!!"])
 
@@ -232,6 +284,12 @@ contains
 !     if (len (var%str4) /= 5) stop 16
 !     if (size (var%str4) /= 2) stop 17
 !     if (var%str4(2) /= "Go!!!") stop 18
+!   !$omp end target
+!  !$omp target map(tofrom: var%uni4(2:2))
+!     if (.not. associated (var%uni4)) stop 15
+!     if (len (var%uni4) /= 5) stop 16
+!     if (size (var%uni4) /= 2) stop 17
+!     if (var%uni4(2) /= 4_"Go!!!") stop 18
 !  !$omp end target
 
     deallocate(var%f, var%str4)
@@ -239,8 +297,7 @@ contains
 
   ! Explicitly mapped – all but only array elements
   subroutine six() 
-    type(t2) :: var, var2(4)
-    type(t2), pointer :: var3, var4(:)
+    type(t2) :: var
 
     print '(g0)', '==== TESTCASE "six" ===='
 
@@ -248,14 +305,19 @@ contains
              b = 2, c = cmplx(-1.0_8, 2.0_8,kind=8), &
              d = [(-3*i, i = 1, 10)], &
              str1 = "abcde", &
-             str2 = ["12345", "67890", "ABCDE", "FGHIJ"])
+             str2 = ["12345", "67890", "ABCDE", "FGHIJ"], &
+             uni1 = 4_"abcde", &
+             uni2 = [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])
     allocate (var%f, source=[22, 33, 44, 55])
     allocate (var%str4, source=["Let's", "Go!!!"])
+    allocate (var%uni4, source=[4_"Let's", 4_"Go!!!"])
 
-!   !$omp target map(tofrom: var%d(5), var%f(3), var%str2(3), var%str4(2))
-    !$omp target map(tofrom: var%d(5), var%f(3), var%str2(3))
+!   !$omp target map(tofrom: var%d(5), var%f(3), var%str2(3), &
+!   !$omp                    var%str4(2), var%uni2(3), var%uni4(2))
+    !$omp target map(tofrom: var%d(5), var%f(3), var%str2(3), var%uni2(3))
       if (var%d(5) /= -3*5) stop 4
       if (var%str2(3) /= "ABCDE") stop 6
+      if (var%uni2(3) /= 4_"ABCDE") stop 7
 
      if (.not. associated (var%f)) stop 9
      if (size (var%f) /= 4) stop 10
@@ -264,15 +326,18 @@ contains
 !     if (len (var%str4) /= 5) stop 16
 !     if (size (var%str4) /= 2) stop 17
 !     if (var%str4(2) /= "Go!!!") stop 18
+!     if (.not. associated (var%uni4)) stop 19
+!     if (len (var%uni4) /= 5) stop 20
+!     if (size (var%uni4) /= 2) stop 21
+!     if (var%uni4(2) /= 4_"Go!!!") stop 22
     !$omp end target
 
-    deallocate(var%f, var%str4)
+    deallocate(var%f, var%str4, var%uni4)
   end subroutine six
 
   ! Explicitly mapped – all but only array elements and one by one
   subroutine seven() 
-    type(t2) :: var, var2(4)
-    type(t2), pointer :: var3, var4(:)
+    type(t2) :: var
 
     print '(g0)', '==== TESTCASE "seven" ===='
 
@@ -280,9 +345,12 @@ contains
              b = 2, c = cmplx(-1.0_8, 2.0_8,kind=8), &
              d = [(-3*i, i = 1, 10)], &
              str1 = "abcde", &
-             str2 = ["12345", "67890", "ABCDE", "FGHIJ"])
+             str2 = ["12345", "67890", "ABCDE", "FGHIJ"], &
+             uni1 = 4_"abcde", &
+             uni2 = [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])
     allocate (var%f, source=[22, 33, 44, 55])
     allocate (var%str4, source=["Let's", "Go!!!"])
+    allocate (var%uni4, source=[4_"Let's", 4_"Go!!!"])
 
     !$omp target map(tofrom: var%d(5))
       if (var%d(5) /= (-3*5)) stop 4
@@ -290,6 +358,9 @@ contains
     !$omp target map(tofrom: var%str2(2:3))
       if (any (var%str2(2:3) /= ["67890", "ABCDE"])) stop 6
     !$omp end target
+    !$omp target map(tofrom: var%uni2(2:3))
+      if (any (var%uni2(2:3) /= [4_"67890", 4_"ABCDE"])) stop 7
+    !$omp end target
 
     !$omp target map(tofrom: var%f(2:3))
      if (.not. associated (var%f)) stop 9
@@ -302,14 +373,19 @@ contains
 !     if (size (var%str4) /= 2) stop 17
 !     if (var%str4(2) /= "Go!!!") stop 18
 !   !$omp end target
+!   !$omp target map(tofrom: var%uni4(2:2))
+!     if (.not. associated (var%uni4)) stop 15
+!     if (len (var%uni4) /= 5) stop 16
+!     if (size (var%uni4) /= 2) stop 17
+!     if (var%uni4(2) /= 4_"Go!!!") stop 18
+!   !$omp end target
 
-    deallocate(var%f, var%str4)
+    deallocate(var%f, var%str4, var%uni4)
   end subroutine seven
 
   ! Check mapping of NULL pointers
   subroutine eight() 
-    type(t2) :: var, var2(4)
-    type(t2), pointer :: var3, var4(:)
+    type(t2) :: var
 
     print '(g0)', '==== TESTCASE "eight" ===='
 
@@ -317,14 +393,18 @@ contains
              b = 2, c = cmplx(-1.0_8, 2.0_8,kind=8), &
              d = [(-3*i, i = 1, 10)], &
              str1 = "abcde", &
-             str2 = ["12345", "67890", "ABCDE", "FGHIJ"])
+             str2 = ["12345", "67890", "ABCDE", "FGHIJ"], &
+             uni1 = 4_"abcde", &
+             uni2 = [4_"12345", 4_"67890", 4_"ABCDE", 4_"FGHIJ"])
 
-!    !$omp target map(tofrom: var%e, var%f, var%str3, var%str4)
-    !$omp target map(tofrom: var%e, var%str3)
+!    !$omp target map(tofrom: var%e, var%f, var%str3, var%str4, var%uni3, 
var%uni4)
+    !$omp target map(tofrom: var%e, var%str3, var%uni3)
       if (associated (var%e)) stop 1
 !      if (associated (var%f)) stop 2
       if (associated (var%str3)) stop 3
 !      if (associated (var%str4)) stop 4
+      if (associated (var%uni3)) stop 5
+!      if (associated (var%uni4)) stop 6
     !$omp end target
   end subroutine eight
 
-- 
2.8.1

From acde0a5f92ed516f149aa0c2654864b8e54ffe3b Mon Sep 17 00:00:00 2001
From: Kwok Cheung Yeung <k...@codesourcery.com>
Date: Tue, 18 Aug 2020 08:44:30 -0700
Subject: [PATCH 3/6] OpenMP: Fixes for omp critical + hint

This is a backport from master of commit
c7c24828cfa4983ebc6744be3f913d0da6ff7163.

gcc/c-family/ChangeLog:

        * c-omp.c (c_finish_omp_critical): Check for no name but
        nonzero hint provided.

gcc/c/ChangeLog:

        * c-parser.c (c_parser_omp_clause_hint): Require nonnegative hint 
clause.
        (c_parser_omp_critical): Permit hint(0) clause without named critical.
        (c_parser_omp_construct): Don't assert if error_mark_node is returned.

gcc/cp/ChangeLog:

        * parser.c (cp_parser_omp_clause_hint): Require nonnegative hint.
        (cp_parser_omp_critical): Permit hint(0) clause without named critical.
        * pt.c (tsubst_expr): Re-check the latter for templates.

gcc/fortran/ChangeLog:

        * openmp.c (gfc_match_omp_critical): Fix handling hints; permit
        hint clause without named critical.
        (resolve_omp_clauses): Require nonnegative constant integer
        for the hint clause.
        (gfc_resolve_omp_directive): Check for no name but
        nonzero value for hint clause.
        * parse.c (parse_omp_structured_block): Fix same-name check
        for critical.
        * trans-openmp.c (gfc_trans_omp_critical): Handle hint clause properly.

libgomp/ChangeLog:

        * omp_lib.f90.in: Add omp_sync_hint_* and omp_sync_hint_kind.
        * omp_lib.h.in: Likewise.

gcc/testsuite/ChangeLog:

        * g++.dg/gomp/critical-3.C: Add nameless critical with hint testcase.
        * c-c++-common/gomp/critical-hint-1.c: New test.
        * c-c++-common/gomp/critical-hint-2.c: New test.
        * gfortran.dg/gomp/critical-hint-1.f90: New test.
        * gfortran.dg/gomp/critical-hint-2.f90: New test.
---
 gcc/c-family/ChangeLog.omp                         |  8 ++
 gcc/c-family/c-omp.c                               | 11 +++
 gcc/c/ChangeLog.omp                                |  9 +++
 gcc/c/c-parser.c                                   | 26 ++----
 gcc/cp/ChangeLog.omp                               |  9 +++
 gcc/cp/parser.c                                    | 20 +++--
 gcc/cp/pt.c                                        |  9 +++
 gcc/fortran/ChangeLog.omp                          | 15 ++++
 gcc/fortran/openmp.c                               | 33 +++++---
 gcc/fortran/parse.c                                |  3 +-
 gcc/fortran/trans-openmp.c                         | 18 +++--
 gcc/testsuite/ChangeLog.omp                        | 11 +++
 gcc/testsuite/c-c++-common/gomp/critical-hint-1.c  | 47 +++++++++++
 gcc/testsuite/c-c++-common/gomp/critical-hint-2.c  | 36 +++++++++
 gcc/testsuite/g++.dg/gomp/critical-3.C             | 31 ++++++-
 gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90 | 94 ++++++++++++++++++++++
 gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90 | 65 +++++++++++++++
 libgomp/ChangeLog.omp                              |  8 ++
 libgomp/omp_lib.f90.in                             | 27 +++++--
 libgomp/omp_lib.h.in                               | 16 +++-
 20 files changed, 445 insertions(+), 51 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/critical-hint-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/critical-hint-2.c
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90

diff --git a/gcc/c-family/ChangeLog.omp b/gcc/c-family/ChangeLog.omp
index 0402b81..92ffa85 100644
--- a/gcc/c-family/ChangeLog.omp
+++ b/gcc/c-family/ChangeLog.omp
@@ -1,3 +1,11 @@
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
+       2020-07-21  Tobias Burnus  <tob...@codesourcery.com>
+
+       * c-omp.c (c_finish_omp_critical): Check for no name but
+       nonzero hint provided.
+
 2020-03-27  Sandra Loosemore  <san...@codesourcery.com>
 
        * c-common.h (c_oacc_annotate_loops_in_kernels_regions): Declare.
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index a04f9bc..c1d6afa 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -105,6 +105,17 @@ c_finish_omp_taskgroup (location_t loc, tree body, tree 
clauses)
 tree
 c_finish_omp_critical (location_t loc, tree body, tree name, tree clauses)
 {
+  gcc_assert (!clauses || OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_HINT);
+  if (name == NULL_TREE
+      && clauses != NULL_TREE
+      && integer_nonzerop (OMP_CLAUSE_HINT_EXPR (clauses)))
+    {
+      error_at (OMP_CLAUSE_LOCATION (clauses),
+               "%<#pragma omp critical%> with %<hint%> clause requires "
+               "a name, except when %<omp_sync_hint_none%> is used");
+      return error_mark_node;
+    }
+
   tree stmt = make_node (OMP_CRITICAL);
   TREE_TYPE (stmt) = void_type_node;
   OMP_CRITICAL_BODY (stmt) = body;
diff --git a/gcc/c/ChangeLog.omp b/gcc/c/ChangeLog.omp
index ea7af89..7eff6ab 100644
--- a/gcc/c/ChangeLog.omp
+++ b/gcc/c/ChangeLog.omp
@@ -1,3 +1,12 @@
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
+       2020-07-21  Tobias Burnus  <tob...@codesourcery.com>
+
+       * c-parser.c (c_parser_omp_clause_hint): Require nonnegative hint 
clause.
+       (c_parser_omp_critical): Permit hint(0) clause without named critical.
+       (c_parser_omp_construct): Don't assert if error_mark_node is returned.
+
 2020-03-27  Sandra Loosemore  <san...@codesourcery.com>
 
        * c-decl.c (c_unwrap_for_init): New.
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 1fba9a0..b7ed742 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -13874,16 +13874,15 @@ c_parser_omp_clause_hint (c_parser *parser, tree list)
       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
       tree c, t = expr.value;
       t = c_fully_fold (t, false, NULL);
-
-      parens.skip_until_found_close (parser);
-
       if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
-         || TREE_CODE (t) != INTEGER_CST)
+         || TREE_CODE (t) != INTEGER_CST
+         || tree_int_cst_sgn (t) == -1)
        {
-         c_parser_error (parser, "expected constant integer expression");
+         c_parser_error (parser, "expected constant integer expression "
+                                 "with valid sync-hint value");
          return list;
        }
-
+      parens.skip_until_found_close (parser);
       check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
 
       c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
@@ -17769,18 +17768,9 @@ c_parser_omp_critical (location_t loc, c_parser 
*parser, bool *if_p)
       if (c_parser_next_token_is (parser, CPP_COMMA)
          && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
        c_parser_consume_token (parser);
-
-      clauses = c_parser_omp_all_clauses (parser,
-                                         OMP_CRITICAL_CLAUSE_MASK,
-                                         "#pragma omp critical");
     }
-  else
-    {
-      if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
-       c_parser_error (parser, "expected %<(%> or end of line");
-      c_parser_skip_to_pragma_eol (parser);
-    }
-
+  clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
+                                     "#pragma omp critical");
   stmt = c_parser_omp_structured_block (parser, if_p);
   return c_finish_omp_critical (loc, stmt, name, clauses);
 }
@@ -21472,7 +21462,7 @@ c_parser_omp_construct (c_parser *parser, bool *if_p)
       gcc_unreachable ();
     }
 
-  if (stmt)
+  if (stmt && stmt != error_mark_node)
     gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
 }
 
diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp
index d9bfa5e..023321a 100644
--- a/gcc/cp/ChangeLog.omp
+++ b/gcc/cp/ChangeLog.omp
@@ -1,3 +1,12 @@
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
+       2020-07-21  Tobias Burnus  <tob...@codesourcery.com>
+
+       * parser.c (cp_parser_omp_clause_hint): Require nonnegative hint.
+       (cp_parser_omp_critical): Permit hint(0) clause without named critical.
+       * pt.c (tsubst_expr): Re-check the latter for templates.
+
 2020-03-31  Sandra Loosemore  <san...@codesourcery.com>
 
        * semantics.c (handle_omp_array_sections_1): Call STRIP_NOPS
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 9f3d8ac..437253e 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -35322,12 +35322,21 @@ cp_parser_omp_clause_hint (cp_parser *parser, tree 
list, location_t location)
 
   t = cp_parser_assignment_expression (parser);
 
+  if (t != error_mark_node)
+    {
+      t = fold_non_dependent_expr (t);
+      if (!value_dependent_expression_p (t)
+         && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
+             || !tree_fits_shwi_p (t)
+             || tree_int_cst_sgn (t) == -1))
+       error_at (location, "expected constant integer expression with "
+                           "valid sync-hint value");
+    }
   if (t == error_mark_node
       || !parens.require_close (parser))
     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                           /*or_comma=*/false,
                                           /*consume_paren=*/true);
-
   check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint", location);
 
   c = build_omp_clause (location, OMP_CLAUSE_HINT);
@@ -38146,13 +38155,10 @@ cp_parser_omp_critical (cp_parser *parser, cp_token 
*pragma_tok, bool *if_p)
       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
          && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
        cp_lexer_consume_token (parser->lexer);
-
-      clauses = cp_parser_omp_all_clauses (parser,
-                                          OMP_CRITICAL_CLAUSE_MASK,
-                                          "#pragma omp critical", pragma_tok);
     }
-  else
-    cp_parser_require_pragma_eol (parser, pragma_tok);
+
+  clauses = cp_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
+                                      "#pragma omp critical", pragma_tok);
 
   stmt = cp_parser_omp_structured_block (parser, if_p);
   return c_finish_omp_critical (input_location, stmt, name, clauses);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 383ad17..dfa9b9c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -18506,6 +18506,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl,
          stmt = pop_stmt_list (stmt);
        }
 
+      if (TREE_CODE (t) == OMP_CRITICAL
+         && tmp != NULL_TREE
+         && integer_nonzerop (OMP_CLAUSE_HINT_EXPR (tmp)))
+       {
+         error_at (OMP_CLAUSE_LOCATION (tmp),
+                   "%<#pragma omp critical%> with %<hint%> clause requires "
+                   "a name, except when %<omp_sync_hint_none%> is used");
+         RETURN (error_mark_node);
+       }
       t = copy_node (t);
       OMP_BODY (t) = stmt;
       OMP_CLAUSES (t) = tmp;
diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index a6b7452..d68db5b 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -1,6 +1,21 @@
 2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
+       2020-07-21  Tobias Burnus  <tob...@codesourcery.com>
+
+       * openmp.c (gfc_match_omp_critical): Fix handling hints; permit
+       hint clause without named critical.
+       (resolve_omp_clauses): Require nonnegative constant integer
+       for the hint clause.
+       (gfc_resolve_omp_directive): Check for no name but
+       nonzero value for hint clause.
+       * parse.c (parse_omp_structured_block): Fix same-name check
+       for critical.
+       * trans-openmp.c (gfc_trans_omp_critical): Handle hint clause properly.
+
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
        2020-06-25  Tobias Burnus  <tob...@codesourcery.com>
 
        PR fortran/95837
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 5c384ca..d9b110f 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -2643,15 +2643,10 @@ gfc_match_omp_critical (void)
   gfc_omp_clauses *c = NULL;
 
   if (gfc_match (" ( %n )", n) != MATCH_YES)
-    {
-      n[0] = '\0';
-      if (gfc_match_omp_eos () != MATCH_YES)
-       {
-         gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
-         return MATCH_ERROR;
-       }
-    }
-  else if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_HINT)) != MATCH_YES)
+    n[0] = '\0';
+
+  if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_HINT),
+                            /* first = */ n[0] == '\0') != MATCH_YES)
     return MATCH_ERROR;
 
   new_st.op = EXEC_OMP_CRITICAL;
@@ -5005,7 +5000,14 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses 
*omp_clauses,
   if (omp_clauses->device)
     resolve_nonnegative_int_expr (omp_clauses->device, "DEVICE");
   if (omp_clauses->hint)
-    resolve_scalar_int_expr (omp_clauses->hint, "HINT");
+    {
+      resolve_scalar_int_expr (omp_clauses->hint, "HINT");
+    if (omp_clauses->hint->ts.type != BT_INTEGER
+       || omp_clauses->hint->expr_type != EXPR_CONSTANT
+       || mpz_sgn (omp_clauses->hint->value.integer) < 0)
+      gfc_error ("Value of HINT clause at %L shall be a valid "
+                "constant hint expression", &omp_clauses->hint->where);
+    }
   if (omp_clauses->priority)
     resolve_nonnegative_int_expr (omp_clauses->priority, "PRIORITY");
   if (omp_clauses->dist_chunk_size)
@@ -6551,6 +6553,17 @@ gfc_resolve_omp_directive (gfc_code *code, gfc_namespace 
*ns ATTRIBUTE_UNUSED)
     case EXEC_OMP_ATOMIC:
       resolve_omp_atomic (code);
       break;
+    case EXEC_OMP_CRITICAL:
+      if (code->ext.omp_clauses)
+       resolve_omp_clauses (code, code->ext.omp_clauses, NULL);
+      if (!code->ext.omp_clauses->critical_name
+         && code->ext.omp_clauses->hint
+         && code->ext.omp_clauses->hint->ts.type == BT_INTEGER
+         && code->ext.omp_clauses->hint->expr_type == EXPR_CONSTANT
+         && mpz_sgn (code->ext.omp_clauses->hint->value.integer) != 0)
+       gfc_error ("OMP CRITICAL at %L with HINT clause requires a NAME, "
+                  "except when omp_sync_hint_none is used", &code->loc);
+      break;
     default:
       break;
     }
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index d506e2e..d6607ab 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -5385,7 +5385,8 @@ parse_omp_structured_block (gfc_statement omp_st, bool 
workshare_stmts_only)
       cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool;
       break;
     case EXEC_OMP_END_CRITICAL:
-      if (((cp->ext.omp_clauses == NULL) ^ (new_st.ext.omp_name == NULL))
+      if (((cp->ext.omp_clauses->critical_name == NULL)
+           ^ (new_st.ext.omp_name == NULL))
          || (new_st.ext.omp_name != NULL
              && strcmp (cp->ext.omp_clauses->critical_name,
                         new_st.ext.omp_name) != 0))
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 9a0f363..f2e6868 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -4249,12 +4249,20 @@ gfc_trans_omp_cancellation_point (gfc_code *code)
 static tree
 gfc_trans_omp_critical (gfc_code *code)
 {
-  tree name = NULL_TREE, stmt;
-  if (code->ext.omp_clauses != NULL)
+  stmtblock_t block;
+  tree stmt, name = NULL_TREE;
+  if (code->ext.omp_clauses->critical_name != NULL)
     name = get_identifier (code->ext.omp_clauses->critical_name);
-  stmt = gfc_trans_code (code->block->next);
-  return build3_loc (input_location, OMP_CRITICAL, void_type_node, stmt,
-                    NULL_TREE, name);
+  gfc_start_block (&block);
+  stmt = make_node (OMP_CRITICAL);
+  TREE_TYPE (stmt) = void_type_node;
+  OMP_CRITICAL_BODY (stmt) = gfc_trans_code (code->block->next);
+  OMP_CRITICAL_NAME (stmt) = name;
+  OMP_CRITICAL_CLAUSES (stmt) = gfc_trans_omp_clauses (&block,
+                                                      code->ext.omp_clauses,
+                                                      code->loc);
+  gfc_add_expr_to_block (&block, stmt);
+  return gfc_finish_block (&block);
 }
 
 typedef struct dovar_init_d {
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index e9d589f..0362145 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,6 +1,17 @@
 2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
+       2020-07-21  Tobias Burnus  <tob...@codesourcery.com>
+
+       * g++.dg/gomp/critical-3.C: Add nameless critical with hint testcase.
+       * c-c++-common/gomp/critical-hint-1.c: New test.
+       * c-c++-common/gomp/critical-hint-2.c: New test.
+       * gfortran.dg/gomp/critical-hint-1.f90: New test.
+       * gfortran.dg/gomp/critical-hint-2.f90: New test.
+
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
        2020-06-25  Tobias Burnus  <tob...@codesourcery.com>
 
        PR fortran/95837
diff --git a/gcc/testsuite/c-c++-common/gomp/critical-hint-1.c 
b/gcc/testsuite/c-c++-common/gomp/critical-hint-1.c
new file mode 100644
index 0000000..510f8ab
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/critical-hint-1.c
@@ -0,0 +1,47 @@
+#include <omp.h>
+
+void
+example_criticial ()
+{
+  int a, b;
+  #pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    {
+      #pragma omp critical hint(omp_sync_hint_none)  /* OK */
+      a += i;
+      #pragma omp critical (HASH) hint(omp_sync_hint_none)  /* OK */
+      a += i;
+      #pragma omp critical (HASH2) hint(omp_sync_hint_uncontended)  /* OK */
+      a += i;
+      #pragma omp critical (HASH3) hint(omp_sync_hint_contended)  /* OK */
+      a += i;
+      #pragma omp critical (HASH4) hint(omp_sync_hint_speculative)  /* OK */
+      a += i;
+      #pragma omp critical (HASH5) hint(omp_sync_hint_nonspeculative)  /* OK */
+      a += i;
+      #pragma omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)  /* OK */
+      a += i;
+      #pragma omp critical (HASH6) hint(omp_sync_hint_contended | 
omp_sync_hint_speculative)  /* OK */
+      a += i;
+
+      /* Accepted but invalid: different hint for same name. */
+      #pragma omp critical (HASH6) hint(omp_sync_hint_uncontended + 
omp_sync_hint_speculative)  
+      a += i;
+      /* Accepted but invalid: Some random integer expr. */
+      #pragma omp critical (HASH) hint(omp_sync_hint_speculative + 1 + 2)
+      a += i;
+
+      #pragma omp critical (HASH) hint(-3)  /* { dg-error "expected constant 
integer expression" } */
+      a += i;
+      #pragma omp critical (HASH2) hint(b)  /* { dg-error "constant integer 
expression" } */
+      a += i;
+/*
+  Fails with gcc as 'expected identifier' and
+        with g++ as "clause requires a name, except when 'omp_sync_hint_none'"
+      #pragma omp critical () hint(omp_sync_hint_speculative)
+      a += i;
+*/
+      #pragma omp critical hint(omp_sync_hint_speculative)  /* { dg-error 
"with 'hint' clause requires a name, except when 'omp_sync_hint_none' is used" 
} */
+      a += i;
+    }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/critical-hint-2.c 
b/gcc/testsuite/c-c++-common/gomp/critical-hint-2.c
new file mode 100644
index 0000000..effe24a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/critical-hint-2.c
@@ -0,0 +1,36 @@
+/* { dg-additional-options "-fdump-tree-original" } */
+#include <omp.h>
+
+void
+example_criticial ()
+{
+  int a, b;
+  #pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    {
+      #pragma omp critical hint(omp_sync_hint_none)
+      a += i;
+      #pragma omp critical (HASH1) hint(omp_sync_hint_none)
+      a += i;
+      #pragma omp critical (HASH2) hint(omp_sync_hint_uncontended)
+      a += i;
+      #pragma omp critical (HASH3) hint(omp_sync_hint_contended)
+      a += i;
+      #pragma omp critical (HASH4) hint(omp_sync_hint_speculative)
+      a += i;
+      #pragma omp critical (HASH5) hint(omp_sync_hint_nonspeculative)
+      a += i;
+      #pragma omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)
+      a += i;
+      #pragma omp critical (HASH7) hint(omp_sync_hint_contended | 
omp_sync_hint_speculative)
+      a += i;
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH1\\) hint\\(0\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH2\\) hint\\(1\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH3\\) hint\\(2\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH4\\) hint\\(8\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH5\\) hint\\(4\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH6\\) hint\\(10\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH7\\) hint\\(10\\)" 1 
"original" } } */
diff --git a/gcc/testsuite/g++.dg/gomp/critical-3.C 
b/gcc/testsuite/g++.dg/gomp/critical-3.C
index b8dc496..788582f 100644
--- a/gcc/testsuite/g++.dg/gomp/critical-3.C
+++ b/gcc/testsuite/g++.dg/gomp/critical-3.C
@@ -2,7 +2,15 @@ int i;
 
 template <int N>
 void
-foo (void)
+foo0 (void)
+{
+  #pragma omp critical (foo), hint (N + 1)  // { dg-error "critical' with 
'hint' clause requires a name, except when 'omp_sync_hint_none' is used" }
+  i++;
+}
+
+template <int N>
+void
+foo_1 (void)
 {
   #pragma omp critical (foo), hint (N + 1)
   i++;
@@ -10,6 +18,22 @@ foo (void)
 
 template <int N>
 void
+foobar0 (void)
+{
+  #pragma omp critical hint (N + 0)
+  i++;
+}
+
+template <int N>
+void
+foobar1 (void)
+{
+  #pragma omp critical hint (N + 0)  // { dg-error "critical' with 'hint' 
clause requires a name, except when 'omp_sync_hint_none' is used" }
+  i++;
+}
+
+template <int N>
+void
 bar (void)
 {
   #pragma omp critical (bar), hint (N + i)     // { dg-error "constant integer 
expression" }
@@ -27,7 +51,10 @@ baz (T x)
 void
 test ()
 {
-  foo <0> ();
+  foo0 <0> ();    // Error
+  foo_1 <-1> ();  // OK
+  foobar0 <0> (); // OK
+  foobar1 <1> (); // Error
   bar <0> ();
   baz (0.0);
 }
diff --git a/gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90 
b/gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90
new file mode 100644
index 0000000..c26b617
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90
@@ -0,0 +1,94 @@
+subroutine example_criticial ()
+  use omp_lib
+  implicit none
+  integer, parameter :: my_omp_hint = omp_sync_hint_contended
+  integer i, a, b
+
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH0) hint(my_omp_hint)  ! OK
+      a = a + i;
+      !$omp end critical (HASH0)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH1) hint(omp_sync_hint_none)  ! OK
+      a = a + i;
+      !$omp end critical (HASH1)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH2) hint(omp_sync_hint_uncontended)  ! OK
+      a = a + i;
+      !$omp end critical (HASH2)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH3) hint(omp_sync_hint_contended)  ! OK
+      a = a + i;
+      !$omp end critical (HASH3)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH4) hint(omp_sync_hint_speculative)  ! OK
+      a = a + i;
+      !$omp end critical (HASH4)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH5) hint(omp_sync_hint_nonspeculative)  ! OK
+      a = a + i;
+      !$omp end critical (HASH5)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)  ! OK
+      a = a + i;
+      !$omp end critical (HASH6)
+  end do
+
+  !$omp parallel do
+  do i = 1, 10
+      ! Accepted but invalid: different hint for same name.
+      !$omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)  ! OK
+      a = a + i;
+      !$omp end critical (HASH6)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      ! Accepted but invalid: Some random integer expr.
+      !$omp critical (HASH) hint(1 + 2)
+      a = a + i;
+      !$omp end critical (HASH)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH) hint(-3)  ! { dg-error "shall be a valid constant 
hint expression" }
+      a = a + i;
+      !$omp end critical (HASH)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH2) hint(b)  ! { dg-error "shall be a valid constant 
hint expression" }
+      a = a + i;
+      !$omp end critical (HASH2)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical () hint(omp_hint_speculative)  ! { dg-error "Invalid 
character in name" }
+      a = a + i;
+!      !$omp end critical
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical hint(omp_sync_hint_none)  ! OK
+      a = a + i;
+      !$omp end critical
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical hint(omp_sync_hint_contended)  ! { dg-error "CRITICAL at 
.1. with HINT clause requires a NAME, except when omp_sync_hint_none is used" }
+      a = a + i;
+      !$omp end critical
+  end do
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90 
b/gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90
new file mode 100644
index 0000000..15d6206
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90
@@ -0,0 +1,65 @@
+! { dg-additional-options "-fdump-tree-original" }
+subroutine example_criticial ()
+  use omp_lib
+  implicit none
+  integer, parameter :: my_omp_hint = omp_sync_hint_contended
+  integer i, a, b
+
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH0) hint(my_omp_hint)
+      a = a + i;
+      !$omp end critical (HASH0)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH1), hint(omp_sync_hint_none)
+      a = a + i;
+      !$omp end critical (HASH1)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH2) hint(omp_sync_hint_uncontended)
+      a = a + i;
+      !$omp end critical (HASH2)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH3) hint(omp_sync_hint_contended)
+      a = a + i;
+      !$omp end critical (HASH3)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH4) hint(omp_sync_hint_speculative)
+      a = a + i;
+      !$omp end critical (HASH4)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH5) hint(omp_sync_hint_nonspeculative)
+      a = a + i;
+      !$omp end critical (HASH5)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH6), hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)
+      a = a + i;
+      !$omp end critical (HASH6)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical hint(omp_sync_hint_none + omp_sync_hint_none)
+      a = a + i;
+      !$omp end critical
+  end do
+end
+
+! { dg-final { scan-tree-dump-times "omp critical \\(hash0\\) hint\\(2\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash1\\) hint\\(0\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash2\\) hint\\(1\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash3\\) hint\\(2\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash4\\) hint\\(8\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash5\\) hint\\(4\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash6\\) hint\\(10\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical hint\\(0\\)" 1 "original" } }
diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index ffdfc75..ebc5b0e 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,6 +1,14 @@
 2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
+       2020-07-21  Tobias Burnus  <tob...@codesourcery.com>
+
+       * omp_lib.f90.in: Add omp_sync_hint_* and omp_sync_hint_kind.
+       * omp_lib.h.in: Likewise.
+
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
        2020-07-15  Tobias Burnus  <tob...@codesourcery.com>
 
        * testsuite/libgomp.fortran/struct-elem-map-1.f90: Remove unused
diff --git a/libgomp/omp_lib.f90.in b/libgomp/omp_lib.f90.in
index 666b515..b22bcba 100644
--- a/libgomp/omp_lib.f90.in
+++ b/libgomp/omp_lib.f90.in
@@ -31,7 +31,8 @@
         integer, parameter :: omp_nest_lock_kind = @OMP_NEST_LOCK_KIND@
         integer, parameter :: omp_sched_kind = 4
         integer, parameter :: omp_proc_bind_kind = 4
-        integer, parameter :: omp_lock_hint_kind = 4
+        integer, parameter :: omp_sync_hint_kind = 4
+        integer, parameter :: omp_lock_hint_kind = omp_sync_hint_kind
         integer, parameter :: omp_pause_resource_kind = 4
         integer, parameter :: omp_allocator_handle_kind = c_intptr_t
         integer, parameter :: omp_alloctrait_key_kind = c_int
@@ -52,15 +53,29 @@
         integer (omp_proc_bind_kind), &
                  parameter :: omp_proc_bind_spread = 4
         integer (omp_lock_hint_kind), &
-                 parameter :: omp_lock_hint_none = 0
+                 parameter :: omp_sync_hint_none = 0
         integer (omp_lock_hint_kind), &
-                 parameter :: omp_lock_hint_uncontended = 1
+                 parameter :: omp_lock_hint_none = omp_sync_hint_none
         integer (omp_lock_hint_kind), &
-                 parameter :: omp_lock_hint_contended = 2
+                 parameter :: omp_sync_hint_uncontended = 1
         integer (omp_lock_hint_kind), &
-                 parameter :: omp_lock_hint_nonspeculative = 4
+                 parameter :: omp_lock_hint_uncontended &
+                 = omp_sync_hint_uncontended
         integer (omp_lock_hint_kind), &
-                 parameter :: omp_lock_hint_speculative = 8
+                 parameter :: omp_sync_hint_contended = 2
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_lock_hint_contended &
+                 = omp_sync_hint_contended
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_sync_hint_nonspeculative = 4
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_lock_hint_nonspeculative &
+                 = omp_sync_hint_nonspeculative
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_sync_hint_speculative = 8
+        integer (omp_lock_hint_kind), &
+                 parameter :: omp_lock_hint_speculative &
+                 = omp_sync_hint_speculative
         integer (kind=omp_pause_resource_kind), &
                  parameter :: omp_pause_soft = 1
         integer (kind=omp_pause_resource_kind), &
diff --git a/libgomp/omp_lib.h.in b/libgomp/omp_lib.h.in
index 34babe9..c7d444d 100644
--- a/libgomp/omp_lib.h.in
+++ b/libgomp/omp_lib.h.in
@@ -46,17 +46,29 @@
       parameter (omp_proc_bind_master = 2)
       parameter (omp_proc_bind_close = 3)
       parameter (omp_proc_bind_spread = 4)
+      integer omp_sync_hint_kind
       integer omp_lock_hint_kind
-      parameter (omp_lock_hint_kind = 4)
+      parameter (omp_sync_hint_kind = 4)
+      parameter (omp_lock_hint_kind = omp_sync_hint_kind)
+      integer (omp_sync_hint_kind) omp_sync_hint_none
       integer (omp_lock_hint_kind) omp_lock_hint_none
+      integer (omp_sync_hint_kind) omp_sync_hint_uncontended
       integer (omp_lock_hint_kind) omp_lock_hint_uncontended
-      integer (omp_lock_hint_kind) omp_lock_hint_contended
+      integer (omp_sync_hint_kind) omp_sync_hint_contended
+      integer (omp_sync_hint_kind) omp_lock_hint_contended
+      integer (omp_lock_hint_kind) omp_sync_hint_nonspeculative
       integer (omp_lock_hint_kind) omp_lock_hint_nonspeculative
+      integer (omp_sync_hint_kind) omp_sync_hint_speculative
       integer (omp_lock_hint_kind) omp_lock_hint_speculative
+      parameter (omp_sync_hint_none = 0)
       parameter (omp_lock_hint_none = 0)
+      parameter (omp_sync_hint_uncontended = 1)
       parameter (omp_lock_hint_uncontended = 1)
+      parameter (omp_sync_hint_contended = 2)
       parameter (omp_lock_hint_contended = 2)
+      parameter (omp_sync_hint_nonspeculative = 4)
       parameter (omp_lock_hint_nonspeculative = 4)
+      parameter (omp_sync_hint_speculative = 8)
       parameter (omp_lock_hint_speculative = 8)
       parameter (openmp_version = 201511)
       integer omp_pause_resource_kind
-- 
2.8.1

From bbbbd2caf3ecd323049743cbebfcc1f910c128e4 Mon Sep 17 00:00:00 2001
From: Kwok Cheung Yeung <k...@codesourcery.com>
Date: Tue, 18 Aug 2020 08:53:58 -0700
Subject: [PATCH 4/6] critical-hint-*.{c,f90}: Move from gcc/testsuite to
 libgomp/testsuite

This is a backport from master of commit
ade6e7204ce4d179cd9fa4637ddee85ba1fa12d9.

libgomp/ChangeLog:

        * testsuite/libgomp.c-c++-common/critical-hint-1.c: New; moved from
        gcc/testsuite/c-c++-common/gomp/.
        * testsuite/libgomp.c-c++-common/critical-hint-2.c: Likewise.
        * testsuite/libgomp.fortran/critical-hint-1.f90: New; moved
        from gcc/testsuite/gfortran.dg/gomp/.
        * testsuite/libgomp.fortran/critical-hint-2.f90: Likewise.

gcc/testsuite/ChangeLog:

        * c-c++-common/gomp/critical-hint-1.c: Moved to libgomp/.
        * c-c++-common/gomp/critical-hint-2.c: Moved to libgomp/.
        * gfortran.dg/gomp/critical-hint-1.f90: Moved to libgomp/.
        * gfortran.dg/gomp/critical-hint-2.f90: Moved to libgomp/.
---
 gcc/testsuite/ChangeLog.omp                        | 10 +++
 gcc/testsuite/c-c++-common/gomp/critical-hint-1.c  | 47 -----------
 gcc/testsuite/c-c++-common/gomp/critical-hint-2.c  | 36 --------
 gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90 | 94 ---------------------
 gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90 | 65 ---------------
 libgomp/ChangeLog.omp                              | 12 +++
 .../libgomp.c-c++-common/critical-hint-1.c         | 49 +++++++++++
 .../libgomp.c-c++-common/critical-hint-2.c         | 37 +++++++++
 .../testsuite/libgomp.fortran/critical-hint-1.f90  | 96 ++++++++++++++++++++++
 .../testsuite/libgomp.fortran/critical-hint-2.f90  | 66 +++++++++++++++
 10 files changed, 270 insertions(+), 242 deletions(-)
 delete mode 100644 gcc/testsuite/c-c++-common/gomp/critical-hint-1.c
 delete mode 100644 gcc/testsuite/c-c++-common/gomp/critical-hint-2.c
 delete mode 100644 gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90
 delete mode 100644 gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/critical-hint-1.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/critical-hint-2.c
 create mode 100644 libgomp/testsuite/libgomp.fortran/critical-hint-1.f90
 create mode 100644 libgomp/testsuite/libgomp.fortran/critical-hint-2.f90

diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 0362145..9838d84 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,6 +1,16 @@
 2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
+       2020-07-22  Tobias Burnus  <tob...@codesourcery.com>
+
+       * c-c++-common/gomp/critical-hint-1.c: Moved to libgomp/.
+       * c-c++-common/gomp/critical-hint-2.c: Moved to libgomp/.
+       * gfortran.dg/gomp/critical-hint-1.f90: Moved to libgomp/.
+       * gfortran.dg/gomp/critical-hint-2.f90: Moved to libgomp/.
+
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
        2020-07-21  Tobias Burnus  <tob...@codesourcery.com>
 
        * g++.dg/gomp/critical-3.C: Add nameless critical with hint testcase.
diff --git a/gcc/testsuite/c-c++-common/gomp/critical-hint-1.c 
b/gcc/testsuite/c-c++-common/gomp/critical-hint-1.c
deleted file mode 100644
index 510f8ab..0000000
--- a/gcc/testsuite/c-c++-common/gomp/critical-hint-1.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <omp.h>
-
-void
-example_criticial ()
-{
-  int a, b;
-  #pragma omp parallel for
-  for (int i = 0; i < 10; ++i)
-    {
-      #pragma omp critical hint(omp_sync_hint_none)  /* OK */
-      a += i;
-      #pragma omp critical (HASH) hint(omp_sync_hint_none)  /* OK */
-      a += i;
-      #pragma omp critical (HASH2) hint(omp_sync_hint_uncontended)  /* OK */
-      a += i;
-      #pragma omp critical (HASH3) hint(omp_sync_hint_contended)  /* OK */
-      a += i;
-      #pragma omp critical (HASH4) hint(omp_sync_hint_speculative)  /* OK */
-      a += i;
-      #pragma omp critical (HASH5) hint(omp_sync_hint_nonspeculative)  /* OK */
-      a += i;
-      #pragma omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)  /* OK */
-      a += i;
-      #pragma omp critical (HASH6) hint(omp_sync_hint_contended | 
omp_sync_hint_speculative)  /* OK */
-      a += i;
-
-      /* Accepted but invalid: different hint for same name. */
-      #pragma omp critical (HASH6) hint(omp_sync_hint_uncontended + 
omp_sync_hint_speculative)  
-      a += i;
-      /* Accepted but invalid: Some random integer expr. */
-      #pragma omp critical (HASH) hint(omp_sync_hint_speculative + 1 + 2)
-      a += i;
-
-      #pragma omp critical (HASH) hint(-3)  /* { dg-error "expected constant 
integer expression" } */
-      a += i;
-      #pragma omp critical (HASH2) hint(b)  /* { dg-error "constant integer 
expression" } */
-      a += i;
-/*
-  Fails with gcc as 'expected identifier' and
-        with g++ as "clause requires a name, except when 'omp_sync_hint_none'"
-      #pragma omp critical () hint(omp_sync_hint_speculative)
-      a += i;
-*/
-      #pragma omp critical hint(omp_sync_hint_speculative)  /* { dg-error 
"with 'hint' clause requires a name, except when 'omp_sync_hint_none' is used" 
} */
-      a += i;
-    }
-}
diff --git a/gcc/testsuite/c-c++-common/gomp/critical-hint-2.c 
b/gcc/testsuite/c-c++-common/gomp/critical-hint-2.c
deleted file mode 100644
index effe24a..0000000
--- a/gcc/testsuite/c-c++-common/gomp/critical-hint-2.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* { dg-additional-options "-fdump-tree-original" } */
-#include <omp.h>
-
-void
-example_criticial ()
-{
-  int a, b;
-  #pragma omp parallel for
-  for (int i = 0; i < 10; ++i)
-    {
-      #pragma omp critical hint(omp_sync_hint_none)
-      a += i;
-      #pragma omp critical (HASH1) hint(omp_sync_hint_none)
-      a += i;
-      #pragma omp critical (HASH2) hint(omp_sync_hint_uncontended)
-      a += i;
-      #pragma omp critical (HASH3) hint(omp_sync_hint_contended)
-      a += i;
-      #pragma omp critical (HASH4) hint(omp_sync_hint_speculative)
-      a += i;
-      #pragma omp critical (HASH5) hint(omp_sync_hint_nonspeculative)
-      a += i;
-      #pragma omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)
-      a += i;
-      #pragma omp critical (HASH7) hint(omp_sync_hint_contended | 
omp_sync_hint_speculative)
-      a += i;
-    }
-}
-
-/* { dg-final { scan-tree-dump-times "omp critical \\(HASH1\\) hint\\(0\\)" 1 
"original" } } */
-/* { dg-final { scan-tree-dump-times "omp critical \\(HASH2\\) hint\\(1\\)" 1 
"original" } } */
-/* { dg-final { scan-tree-dump-times "omp critical \\(HASH3\\) hint\\(2\\)" 1 
"original" } } */
-/* { dg-final { scan-tree-dump-times "omp critical \\(HASH4\\) hint\\(8\\)" 1 
"original" } } */
-/* { dg-final { scan-tree-dump-times "omp critical \\(HASH5\\) hint\\(4\\)" 1 
"original" } } */
-/* { dg-final { scan-tree-dump-times "omp critical \\(HASH6\\) hint\\(10\\)" 1 
"original" } } */
-/* { dg-final { scan-tree-dump-times "omp critical \\(HASH7\\) hint\\(10\\)" 1 
"original" } } */
diff --git a/gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90 
b/gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90
deleted file mode 100644
index c26b617..0000000
--- a/gcc/testsuite/gfortran.dg/gomp/critical-hint-1.f90
+++ /dev/null
@@ -1,94 +0,0 @@
-subroutine example_criticial ()
-  use omp_lib
-  implicit none
-  integer, parameter :: my_omp_hint = omp_sync_hint_contended
-  integer i, a, b
-
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH0) hint(my_omp_hint)  ! OK
-      a = a + i;
-      !$omp end critical (HASH0)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH1) hint(omp_sync_hint_none)  ! OK
-      a = a + i;
-      !$omp end critical (HASH1)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH2) hint(omp_sync_hint_uncontended)  ! OK
-      a = a + i;
-      !$omp end critical (HASH2)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH3) hint(omp_sync_hint_contended)  ! OK
-      a = a + i;
-      !$omp end critical (HASH3)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH4) hint(omp_sync_hint_speculative)  ! OK
-      a = a + i;
-      !$omp end critical (HASH4)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH5) hint(omp_sync_hint_nonspeculative)  ! OK
-      a = a + i;
-      !$omp end critical (HASH5)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)  ! OK
-      a = a + i;
-      !$omp end critical (HASH6)
-  end do
-
-  !$omp parallel do
-  do i = 1, 10
-      ! Accepted but invalid: different hint for same name.
-      !$omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)  ! OK
-      a = a + i;
-      !$omp end critical (HASH6)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      ! Accepted but invalid: Some random integer expr.
-      !$omp critical (HASH) hint(1 + 2)
-      a = a + i;
-      !$omp end critical (HASH)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH) hint(-3)  ! { dg-error "shall be a valid constant 
hint expression" }
-      a = a + i;
-      !$omp end critical (HASH)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH2) hint(b)  ! { dg-error "shall be a valid constant 
hint expression" }
-      a = a + i;
-      !$omp end critical (HASH2)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical () hint(omp_hint_speculative)  ! { dg-error "Invalid 
character in name" }
-      a = a + i;
-!      !$omp end critical
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical hint(omp_sync_hint_none)  ! OK
-      a = a + i;
-      !$omp end critical
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical hint(omp_sync_hint_contended)  ! { dg-error "CRITICAL at 
.1. with HINT clause requires a NAME, except when omp_sync_hint_none is used" }
-      a = a + i;
-      !$omp end critical
-  end do
-end
diff --git a/gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90 
b/gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90
deleted file mode 100644
index 15d6206..0000000
--- a/gcc/testsuite/gfortran.dg/gomp/critical-hint-2.f90
+++ /dev/null
@@ -1,65 +0,0 @@
-! { dg-additional-options "-fdump-tree-original" }
-subroutine example_criticial ()
-  use omp_lib
-  implicit none
-  integer, parameter :: my_omp_hint = omp_sync_hint_contended
-  integer i, a, b
-
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH0) hint(my_omp_hint)
-      a = a + i;
-      !$omp end critical (HASH0)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH1), hint(omp_sync_hint_none)
-      a = a + i;
-      !$omp end critical (HASH1)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH2) hint(omp_sync_hint_uncontended)
-      a = a + i;
-      !$omp end critical (HASH2)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH3) hint(omp_sync_hint_contended)
-      a = a + i;
-      !$omp end critical (HASH3)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH4) hint(omp_sync_hint_speculative)
-      a = a + i;
-      !$omp end critical (HASH4)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH5) hint(omp_sync_hint_nonspeculative)
-      a = a + i;
-      !$omp end critical (HASH5)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical (HASH6), hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)
-      a = a + i;
-      !$omp end critical (HASH6)
-  end do
-  !$omp parallel do
-  do i = 1, 10
-      !$omp critical hint(omp_sync_hint_none + omp_sync_hint_none)
-      a = a + i;
-      !$omp end critical
-  end do
-end
-
-! { dg-final { scan-tree-dump-times "omp critical \\(hash0\\) hint\\(2\\)" 1 
"original" } }
-! { dg-final { scan-tree-dump-times "omp critical \\(hash1\\) hint\\(0\\)" 1 
"original" } }
-! { dg-final { scan-tree-dump-times "omp critical \\(hash2\\) hint\\(1\\)" 1 
"original" } }
-! { dg-final { scan-tree-dump-times "omp critical \\(hash3\\) hint\\(2\\)" 1 
"original" } }
-! { dg-final { scan-tree-dump-times "omp critical \\(hash4\\) hint\\(8\\)" 1 
"original" } }
-! { dg-final { scan-tree-dump-times "omp critical \\(hash5\\) hint\\(4\\)" 1 
"original" } }
-! { dg-final { scan-tree-dump-times "omp critical \\(hash6\\) hint\\(10\\)" 1 
"original" } }
-! { dg-final { scan-tree-dump-times "omp critical hint\\(0\\)" 1 "original" } }
diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index ebc5b0e..6c3f695 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,6 +1,18 @@
 2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
+       2020-07-22  Tobias Burnus  <tob...@codesourcery.com>
+
+       * testsuite/libgomp.c-c++-common/critical-hint-1.c: New; moved from
+       gcc/testsuite/c-c++-common/gomp/.
+       * testsuite/libgomp.c-c++-common/critical-hint-2.c: Likewise.
+       * testsuite/libgomp.fortran/critical-hint-1.f90: New; moved
+       from gcc/testsuite/gfortran.dg/gomp/.
+       * testsuite/libgomp.fortran/critical-hint-2.f90: Likewise.
+
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
        2020-07-21  Tobias Burnus  <tob...@codesourcery.com>
 
        * omp_lib.f90.in: Add omp_sync_hint_* and omp_sync_hint_kind.
diff --git a/libgomp/testsuite/libgomp.c-c++-common/critical-hint-1.c 
b/libgomp/testsuite/libgomp.c-c++-common/critical-hint-1.c
new file mode 100644
index 0000000..1e49747
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/critical-hint-1.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+
+#include <omp.h>
+
+void
+example_criticial ()
+{
+  int a, b;
+  #pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    {
+      #pragma omp critical hint(omp_sync_hint_none)  /* OK */
+      a += i;
+      #pragma omp critical (HASH) hint(omp_sync_hint_none)  /* OK */
+      a += i;
+      #pragma omp critical (HASH2) hint(omp_sync_hint_uncontended)  /* OK */
+      a += i;
+      #pragma omp critical (HASH3) hint(omp_sync_hint_contended)  /* OK */
+      a += i;
+      #pragma omp critical (HASH4) hint(omp_sync_hint_speculative)  /* OK */
+      a += i;
+      #pragma omp critical (HASH5) hint(omp_sync_hint_nonspeculative)  /* OK */
+      a += i;
+      #pragma omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)  /* OK */
+      a += i;
+      #pragma omp critical (HASH6) hint(omp_sync_hint_contended | 
omp_sync_hint_speculative)  /* OK */
+      a += i;
+
+      /* Accepted but invalid: different hint for same name. */
+      #pragma omp critical (HASH6) hint(omp_sync_hint_uncontended + 
omp_sync_hint_speculative)  
+      a += i;
+      /* Accepted but invalid: Some random integer expr. */
+      #pragma omp critical (HASH) hint(omp_sync_hint_speculative + 1 + 2)
+      a += i;
+
+      #pragma omp critical (HASH) hint(-3)  /* { dg-error "expected constant 
integer expression" } */
+      a += i;
+      #pragma omp critical (HASH2) hint(b)  /* { dg-error "constant integer 
expression" } */
+      a += i;
+/*
+  Fails with gcc as 'expected identifier' and
+        with g++ as "clause requires a name, except when 'omp_sync_hint_none'"
+      #pragma omp critical () hint(omp_sync_hint_speculative)
+      a += i;
+*/
+      #pragma omp critical hint(omp_sync_hint_speculative)  /* { dg-error 
"with 'hint' clause requires a name, except when 'omp_sync_hint_none' is used" 
} */
+      a += i;
+    }
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/critical-hint-2.c 
b/libgomp/testsuite/libgomp.c-c++-common/critical-hint-2.c
new file mode 100644
index 0000000..057353b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/critical-hint-2.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-original" } */
+#include <omp.h>
+
+void
+example_criticial ()
+{
+  int a, b;
+  #pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    {
+      #pragma omp critical hint(omp_sync_hint_none)
+      a += i;
+      #pragma omp critical (HASH1) hint(omp_sync_hint_none)
+      a += i;
+      #pragma omp critical (HASH2) hint(omp_sync_hint_uncontended)
+      a += i;
+      #pragma omp critical (HASH3) hint(omp_sync_hint_contended)
+      a += i;
+      #pragma omp critical (HASH4) hint(omp_sync_hint_speculative)
+      a += i;
+      #pragma omp critical (HASH5) hint(omp_sync_hint_nonspeculative)
+      a += i;
+      #pragma omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)
+      a += i;
+      #pragma omp critical (HASH7) hint(omp_sync_hint_contended | 
omp_sync_hint_speculative)
+      a += i;
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH1\\) hint\\(0\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH2\\) hint\\(1\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH3\\) hint\\(2\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH4\\) hint\\(8\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH5\\) hint\\(4\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH6\\) hint\\(10\\)" 1 
"original" } } */
+/* { dg-final { scan-tree-dump-times "omp critical \\(HASH7\\) hint\\(10\\)" 1 
"original" } } */
diff --git a/libgomp/testsuite/libgomp.fortran/critical-hint-1.f90 
b/libgomp/testsuite/libgomp.fortran/critical-hint-1.f90
new file mode 100644
index 0000000..225d9a7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/critical-hint-1.f90
@@ -0,0 +1,96 @@
+! { dg-do compile }
+
+subroutine example_criticial ()
+  use omp_lib
+  implicit none
+  integer, parameter :: my_omp_hint = omp_sync_hint_contended
+  integer i, a, b
+
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH0) hint(my_omp_hint)  ! OK
+      a = a + i;
+      !$omp end critical (HASH0)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH1) hint(omp_sync_hint_none)  ! OK
+      a = a + i;
+      !$omp end critical (HASH1)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH2) hint(omp_sync_hint_uncontended)  ! OK
+      a = a + i;
+      !$omp end critical (HASH2)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH3) hint(omp_sync_hint_contended)  ! OK
+      a = a + i;
+      !$omp end critical (HASH3)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH4) hint(omp_sync_hint_speculative)  ! OK
+      a = a + i;
+      !$omp end critical (HASH4)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH5) hint(omp_sync_hint_nonspeculative)  ! OK
+      a = a + i;
+      !$omp end critical (HASH5)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)  ! OK
+      a = a + i;
+      !$omp end critical (HASH6)
+  end do
+
+  !$omp parallel do
+  do i = 1, 10
+      ! Accepted but invalid: different hint for same name.
+      !$omp critical (HASH6) hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)  ! OK
+      a = a + i;
+      !$omp end critical (HASH6)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      ! Accepted but invalid: Some random integer expr.
+      !$omp critical (HASH) hint(1 + 2)
+      a = a + i;
+      !$omp end critical (HASH)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH) hint(-3)  ! { dg-error "shall be a valid constant 
hint expression" }
+      a = a + i;
+      !$omp end critical (HASH)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH2) hint(b)  ! { dg-error "shall be a valid constant 
hint expression" }
+      a = a + i;
+      !$omp end critical (HASH2)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical () hint(omp_hint_speculative)  ! { dg-error "Invalid 
character in name" }
+      a = a + i;
+!      !$omp end critical
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical hint(omp_sync_hint_none)  ! OK
+      a = a + i;
+      !$omp end critical
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical hint(omp_sync_hint_contended)  ! { dg-error "CRITICAL at 
.1. with HINT clause requires a NAME, except when omp_sync_hint_none is used" }
+      a = a + i;
+      !$omp end critical
+  end do
+end
diff --git a/libgomp/testsuite/libgomp.fortran/critical-hint-2.f90 
b/libgomp/testsuite/libgomp.fortran/critical-hint-2.f90
new file mode 100644
index 0000000..f34680c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/critical-hint-2.f90
@@ -0,0 +1,66 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+subroutine example_criticial ()
+  use omp_lib
+  implicit none
+  integer, parameter :: my_omp_hint = omp_sync_hint_contended
+  integer i, a, b
+
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH0) hint(my_omp_hint)
+      a = a + i;
+      !$omp end critical (HASH0)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH1), hint(omp_sync_hint_none)
+      a = a + i;
+      !$omp end critical (HASH1)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH2) hint(omp_sync_hint_uncontended)
+      a = a + i;
+      !$omp end critical (HASH2)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH3) hint(omp_sync_hint_contended)
+      a = a + i;
+      !$omp end critical (HASH3)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH4) hint(omp_sync_hint_speculative)
+      a = a + i;
+      !$omp end critical (HASH4)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH5) hint(omp_sync_hint_nonspeculative)
+      a = a + i;
+      !$omp end critical (HASH5)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical (HASH6), hint(omp_sync_hint_contended + 
omp_sync_hint_speculative)
+      a = a + i;
+      !$omp end critical (HASH6)
+  end do
+  !$omp parallel do
+  do i = 1, 10
+      !$omp critical hint(omp_sync_hint_none + omp_sync_hint_none)
+      a = a + i;
+      !$omp end critical
+  end do
+end
+
+! { dg-final { scan-tree-dump-times "omp critical \\(hash0\\) hint\\(2\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash1\\) hint\\(0\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash2\\) hint\\(1\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash3\\) hint\\(2\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash4\\) hint\\(8\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash5\\) hint\\(4\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical \\(hash6\\) hint\\(10\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "omp critical hint\\(0\\)" 1 "original" } }
-- 
2.8.1

From ed0eb7b607064170585be2f42c34e6ffc51b0896 Mon Sep 17 00:00:00 2001
From: Kwok Cheung Yeung <k...@codesourcery.com>
Date: Tue, 18 Aug 2020 08:55:21 -0700
Subject: [PATCH 5/6] openmp: Handle clauses with gimple sequences in
 convert_nonlocal_omp_clauses properly

This is a backport from master of commit
676b5525e8333005bdc1c596ed086f1da27a450f.

If the walk_body on the various sequences of reduction, lastprivate and/or 
linear
clauses needs to create a temporary variable, we should declare that variable
in that sequence rather than outside, where it would need to be privatized 
inside of
the construct.

2020-08-08  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/93553
        * tree-nested.c (convert_nonlocal_omp_clauses): For
        OMP_CLAUSE_REDUCTION, OMP_CLAUSE_LASTPRIVATE and OMP_CLAUSE_LINEAR
        save info->new_local_var_chain around walks of the clause gimple
        sequences and declare_vars if needed into the sequence.

2020-08-08  Tobias Burnus  <tob...@codesourcery.com>

        PR fortran/93553
        * testsuite/libgomp.fortran/pr93553.f90: New test.
---
 gcc/ChangeLog.omp                             | 11 +++++++
 gcc/tree-nested.c                             | 46 +++++++++++++++++++++------
 libgomp/ChangeLog.omp                         |  8 +++++
 libgomp/testsuite/libgomp.fortran/pr93553.f90 | 21 ++++++++++++
 4 files changed, 76 insertions(+), 10 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.fortran/pr93553.f90

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index 34622a3..063eda3 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,14 @@
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
+       2020-08-08  Jakub Jelinek  <ja...@redhat.com>
+
+       PR fortran/93553
+       * tree-nested.c (convert_nonlocal_omp_clauses): For
+       OMP_CLAUSE_REDUCTION, OMP_CLAUSE_LASTPRIVATE and OMP_CLAUSE_LINEAR
+       save info->new_local_var_chain around walks of the clause gimple
+       sequences and declare_vars if needed into the sequence.
+
 2020-07-30  Julian Brown  <jul...@codesourcery.com>
 
        * config/gcn/gcn-tree.c (gcn_goacc_get_worker_red_decl): Do not
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 7476a3a..e42f0b6 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1424,12 +1424,22 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct 
walk_stmt_info *wi)
              if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
                DECL_CONTEXT (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
                  = info->context;
+             tree save_local_var_chain = info->new_local_var_chain;
+             info->new_local_var_chain = NULL;
+             gimple_seq *seq = &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause);
              walk_body (convert_nonlocal_reference_stmt,
-                        convert_nonlocal_reference_op, info,
-                        &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
+                        convert_nonlocal_reference_op, info, seq);
+             if (info->new_local_var_chain)
+               declare_vars (info->new_local_var_chain,
+                             gimple_seq_first_stmt (*seq), false);
+             info->new_local_var_chain = NULL;
+             seq = &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause);
              walk_body (convert_nonlocal_reference_stmt,
-                        convert_nonlocal_reference_op, info,
-                        &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
+                        convert_nonlocal_reference_op, info, seq);
+             if (info->new_local_var_chain)
+               declare_vars (info->new_local_var_chain,
+                             gimple_seq_first_stmt (*seq), false);
+             info->new_local_var_chain = save_local_var_chain;
              DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
                = old_context;
              if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
@@ -1439,15 +1449,31 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct 
walk_stmt_info *wi)
          break;
 
        case OMP_CLAUSE_LASTPRIVATE:
-         walk_body (convert_nonlocal_reference_stmt,
-                    convert_nonlocal_reference_op, info,
-                    &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
+         {
+           tree save_local_var_chain = info->new_local_var_chain;
+           info->new_local_var_chain = NULL;
+           gimple_seq *seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause);
+           walk_body (convert_nonlocal_reference_stmt,
+                      convert_nonlocal_reference_op, info, seq);
+           if (info->new_local_var_chain)
+             declare_vars (info->new_local_var_chain,
+                           gimple_seq_first_stmt (*seq), false);
+           info->new_local_var_chain = save_local_var_chain;
+         }
          break;
 
        case OMP_CLAUSE_LINEAR:
-         walk_body (convert_nonlocal_reference_stmt,
-                    convert_nonlocal_reference_op, info,
-                    &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause));
+         {
+           tree save_local_var_chain = info->new_local_var_chain;
+           info->new_local_var_chain = NULL;
+           gimple_seq *seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause);
+           walk_body (convert_nonlocal_reference_stmt,
+                      convert_nonlocal_reference_op, info, seq);
+           if (info->new_local_var_chain)
+             declare_vars (info->new_local_var_chain,
+                           gimple_seq_first_stmt (*seq), false);
+           info->new_local_var_chain = save_local_var_chain;
+         }
          break;
 
        default:
diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index 6c3f695..4601eae 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,6 +1,14 @@
 2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
+       2020-08-08  Tobias Burnus  <tob...@codesourcery.com>
+
+       PR fortran/93553
+       * testsuite/libgomp.fortran/pr93553.f90: New test.
+
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
        2020-07-22  Tobias Burnus  <tob...@codesourcery.com>
 
        * testsuite/libgomp.c-c++-common/critical-hint-1.c: New; moved from
diff --git a/libgomp/testsuite/libgomp.fortran/pr93553.f90 
b/libgomp/testsuite/libgomp.fortran/pr93553.f90
new file mode 100644
index 0000000..5d6f10f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/pr93553.f90
@@ -0,0 +1,21 @@
+program p
+   implicit none
+   integer :: x(8) = 0
+   call sub(x)
+end
+subroutine sub(x)
+   implicit none
+   integer i
+   integer :: x(8)
+   integer :: c(8) = [(11*i, i=1,8)]
+   call s
+   if (any (x /= c)) stop 1
+contains
+   subroutine s
+      integer :: i
+      !$omp parallel do reduction(+:x)
+      do i = 1, 8
+         x(i) = c(i)
+      end do
+   end
+end
-- 
2.8.1

From 00ee82759bbfbc07851a4e88207254969da9a167 Mon Sep 17 00:00:00 2001
From: Kwok Cheung Yeung <k...@codesourcery.com>
Date: Tue, 18 Aug 2020 08:59:27 -0700
Subject: [PATCH 6/6] Fortran/OpenMP: Fix detecting not perfectly nested loops

This is a backport for master of commit
57dd9f3bfca8bb752c630431dc033c761e2ad382.

gcc/fortran/ChangeLog:

        * openmp.c (resolve_omp_do): Detect not perfectly
        nested loop with innermost collapse.

gcc/testsuite/ChangeLog:

        * gfortran.dg/gomp/collapse1.f90: Add dg-error.
        * gfortran.dg/gomp/collapse2.f90: New test.
---
 gcc/fortran/ChangeLog.omp                    |  8 +++++++
 gcc/fortran/openmp.c                         |  4 +---
 gcc/testsuite/ChangeLog.omp                  |  8 +++++++
 gcc/testsuite/gfortran.dg/gomp/collapse1.f90 |  2 +-
 gcc/testsuite/gfortran.dg/gomp/collapse2.f90 | 32 ++++++++++++++++++++++++++++
 5 files changed, 50 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/collapse2.f90

diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index d68db5b..e64bf82 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -1,6 +1,14 @@
 2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
+       2020-08-04  Tobias Burnus  <tob...@codesourcery.com>
+
+       * openmp.c (resolve_omp_do): Detect not perfectly
+       nested loop with innermost collapse.
+
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
        2020-07-21  Tobias Burnus  <tob...@codesourcery.com>
 
        * openmp.c (gfc_match_omp_critical): Fix handling hints; permit
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index d9b110f..9d13863 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -5907,8 +5907,6 @@ resolve_omp_do (gfc_code *code)
              do_code2 = do_code2->block->next;
            }
        }
-      if (i == collapse)
-       break;
       for (c = do_code->next; c; c = c->next)
        if (c->op != EXEC_NOP && c->op != EXEC_CONTINUE)
          {
@@ -5916,7 +5914,7 @@ resolve_omp_do (gfc_code *code)
                       name, &c->loc);
            break;
          }
-      if (c)
+      if (i == collapse || c)
        break;
       do_code = do_code->block;
       if (do_code->op != EXEC_DO && do_code->op != EXEC_DO_WHILE)
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 9838d84..19395cf 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,6 +1,14 @@
 2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
 
        Backport from mainline
+       2020-08-04  Tobias Burnus  <tob...@codesourcery.com>
+
+       * gfortran.dg/gomp/collapse1.f90: Add dg-error.
+       * gfortran.dg/gomp/collapse2.f90: New test.
+
+2020-08-18  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       Backport from mainline
        2020-07-22  Tobias Burnus  <tob...@codesourcery.com>
 
        * c-c++-common/gomp/critical-hint-1.c: Moved to libgomp/.
diff --git a/gcc/testsuite/gfortran.dg/gomp/collapse1.f90 
b/gcc/testsuite/gfortran.dg/gomp/collapse1.f90
index f16a780..1a06eab 100644
--- a/gcc/testsuite/gfortran.dg/gomp/collapse1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/collapse1.f90
@@ -31,7 +31,7 @@ subroutine collapse1
     do i = 1, 3
       do j = 4, 6
       end do
-      k = 4
+      k = 4  ! { dg-error "loops not perfectly nested" }
     end do
   !$omp parallel do collapse(2)
     do i = 1, 3
diff --git a/gcc/testsuite/gfortran.dg/gomp/collapse2.f90 
b/gcc/testsuite/gfortran.dg/gomp/collapse2.f90
new file mode 100644
index 0000000..1ab934e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/collapse2.f90
@@ -0,0 +1,32 @@
+program p
+   integer :: i, j, k
+   real :: x
+   !$omp parallel do collapse(3)
+   do i = 1, 8
+      do j = 1, 8
+        do k = 1, 8
+        end do
+        x = 5  ! { dg-error "loops not perfectly nested" }
+      end do
+   end do
+   !$omp parallel do ordered(3)
+   do i = 1, 8
+      do j = 1, 8
+        do k = 1, 8
+        end do
+      end do
+      x = 5  ! { dg-error "loops not perfectly nested" }
+   end do
+   !$omp parallel do collapse(2)  ! { dg-error "not enough DO loops for 
collapsed" }
+   do i = 1, 8
+      x = 5
+      do j = 1, 8
+      end do
+   end do
+   !$omp parallel do ordered(2)  ! { dg-error "not enough DO loops for 
collapsed" }
+   do i = 1, 8
+      x = 5
+      do j = 1, 8
+      end do
+   end do
+end
-- 
2.8.1

Reply via email to