On 9/9/24 14:55, Sandra Loosemore wrote:
On 9/9/24 05:01, Jakub Jelinek wrote:

I think also testing the device={kind(any,any)} and device={kind("any",any)}
and device={kind(any,"any"))} would be useful.

Hmmm, it looks like GCC does not presently check for the restriction

"Each trait-property may only be specified once in a trait selector other than those in the construct selector set."

I'll have to re-work the patch again to add that.  :-S

Here's the revised patch, covering both restrictions.  OK to commit?

-Sandra
From 6dabf26a4e893b93a38a5e791d70719429687bc5 Mon Sep 17 00:00:00 2001
From: Sandra Loosemore <sloosem...@baylibre.com>
Date: Fri, 6 Sep 2024 20:58:13 +0000
Subject: [PATCH] OpenMP: Check additional restrictions on context selector
 properties

TR13 (pre-6.0) of the OpenMP spec says:

"Each trait-property may only be specified once in a trait selector
other than those in the construct selector set."

and

"If trait-property any is specified in the kind trait-selector of the
device selector set or the target_device selector sets, no other
trait-property may be specified in the same selector set."

These restrictions (with slightly different wording) date back to
OpenMP 5.1, but were not in 5.0 which was the basis for GCC's
implementation.

This patch adds a diagnostic, adds new testcases, and fixes some older
testcases that include now-invalid selectors.

gcc/ChangeLog
	* omp-general.cc (omp_check_context_selector): Reject other
	properties in the same selector set with kind(any).  Also reject
	duplicate name-list properties.

gcc/testsuite/ChangeLog
	* c-c++-common/gomp/declare-variant-10.c: Fix broken tests.
	* c-c++-common/gomp/declare-variant-3.c: Likewise.
	* c-c++-common/gomp/declare-variant-9.c: Likewise.
	* c-c++-common/gomp/declare-variant-any.c: New.
	* c-c++-common/gomp/declare-variant-duplicates.c: New.
	* gfortran.dg/gomp/declare-variant-10.f90: Fix broken tests.
	* gfortran.dg/gomp/declare-variant-3.f90: Likewise.
	* gfortran.dg/gomp/declare-variant-9.f90: Likewise.
	* gfortran.dg/gomp/declare-variant-any.f90: New.
	* gfortran.dg/gomp/declare-variant-duplicates.f90: New.
---
 gcc/omp-general.cc                            | 64 ++++++++++++++++++-
 .../c-c++-common/gomp/declare-variant-10.c    |  4 +-
 .../c-c++-common/gomp/declare-variant-3.c     | 10 +--
 .../c-c++-common/gomp/declare-variant-9.c     |  4 +-
 .../c-c++-common/gomp/declare-variant-any.c   | 17 +++++
 .../gomp/declare-variant-duplicates.c         | 13 ++++
 .../gfortran.dg/gomp/declare-variant-10.f90   |  4 +-
 .../gfortran.dg/gomp/declare-variant-3.f90    | 12 +---
 .../gfortran.dg/gomp/declare-variant-9.f90    |  2 +-
 .../gfortran.dg/gomp/declare-variant-any.f90  | 40 ++++++++++++
 .../gomp/declare-variant-duplicates.f90       | 30 +++++++++
 11 files changed, 176 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/declare-variant-any.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/declare-variant-duplicates.c
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-variant-any.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-variant-duplicates.f90

diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc
index 0b61335dba4..599cfbc4338 100644
--- a/gcc/omp-general.cc
+++ b/gcc/omp-general.cc
@@ -1288,6 +1288,8 @@ omp_check_context_selector (location_t loc, tree ctx)
   for (tree tss = ctx; tss; tss = TREE_CHAIN (tss))
     {
       enum omp_tss_code tss_code = OMP_TSS_CODE (tss);
+      bool saw_any_prop = false;
+      bool saw_other_prop = false;
 
       /* We can parse this, but not handle it yet.  */
       if (tss_code == OMP_TRAIT_SET_TARGET_DEVICE)
@@ -1324,9 +1326,61 @@ omp_check_context_selector (location_t loc, tree ctx)
 	  else
 	    ts_seen[ts_code] = true;
 
+	  /* If trait-property "any" is specified in the "kind"
+	     trait-selector of the "device" selector set or the
+	     "target_device" selector sets, no other trait-property
+	     may be specified in the same selector set.  */
+	  if (ts_code == OMP_TRAIT_DEVICE_KIND)
+	    for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
+	      {
+		const char *prop = omp_context_name_list_prop (p);
+		if (!prop)
+		  continue;
+		else if (strcmp (prop, "any") == 0)
+		  saw_any_prop = true;
+		else
+		  saw_other_prop = true;
+	      }
+	  /* It seems slightly suspicious that the spec's language covers
+	     the device_num selector too, but
+	       target_device={device_num(whatever),kind(any)}
+	     is probably not terribly useful anyway.  */
+	  else if (ts_code == OMP_TRAIT_DEVICE_ARCH
+		   || ts_code == OMP_TRAIT_DEVICE_ISA
+		   || ts_code == OMP_TRAIT_DEVICE_NUM)
+	    saw_other_prop = true;
+
+	  /* Each trait-property can only be specified once in a trait-selector
+	     other than the construct selector set.  FIXME: only handles
+	     name-list properties, not clause-list properties, since the
+	     "requires" selector is not implemented yet (PR 113067).  */
+	  if (tss_code != OMP_TRAIT_SET_CONSTRUCT)
+	    for (tree p1 = OMP_TS_PROPERTIES (ts); p1; p1 = TREE_CHAIN (p1))
+	      {
+		if (OMP_TP_NAME (p1) != OMP_TP_NAMELIST_NODE)
+		  break;
+		const char *n1 = omp_context_name_list_prop (p1);
+		if (!n1)
+		  continue;
+		for (tree p2 = TREE_CHAIN (p1); p2; p2 = TREE_CHAIN (p2))
+		  {
+		    const char *n2 = omp_context_name_list_prop (p2);
+		    if (!n2)
+		      continue;
+		    if (!strcmp (n1, n2))
+		      {
+			error_at (loc,
+				  "trait-property %qs specified more "
+				  "than once in %qs selector",
+				  n1, OMP_TS_NAME (ts));
+			return error_mark_node;
+		      }
+		  }
+	      }
+
+	  /* Check for unknown properties.  */
 	  if (omp_ts_map[ts_code].valid_properties == NULL)
 	    continue;
-
 	  for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
 	    for (unsigned j = 0; ; j++)
 	      {
@@ -1376,6 +1430,14 @@ omp_check_context_selector (location_t loc, tree ctx)
 		  break;
 	      }
 	}
+
+      if (saw_any_prop && saw_other_prop)
+	{
+	  error_at (loc,
+		    "no other trait-property may be specified "
+		    "in the same selector set with %<kind(\"any\")%>");
+	  return error_mark_node;
+	}
     }
   return ctx;
 }
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-10.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-10.c
index 2b8a39425b1..e77693430d1 100644
--- a/gcc/testsuite/c-c++-common/gomp/declare-variant-10.c
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-10.c
@@ -7,7 +7,7 @@ void f01 (void);
 #pragma omp declare variant (f01) match (device={isa(avx512f,avx512bw)})
 void f02 (void);
 void f03 (void);
-#pragma omp declare variant (f03) match (device={kind("any"),arch(x86_64),isa(avx512f,avx512bw)})
+#pragma omp declare variant (f03) match (device={arch(x86_64),isa(avx512f,avx512bw)})
 void f04 (void);
 void f05 (void);
 #pragma omp declare variant (f05) match (device={kind(gpu)})
@@ -28,7 +28,7 @@ void f15 (void);
 #pragma omp declare variant (f15) match (device={isa(sse4,ssse3),arch(i386)})
 void f16 (void);
 void f17 (void);
-#pragma omp declare variant (f17) match (device={kind(any,fpga)})
+#pragma omp declare variant (f17) match (device={kind(fpga)})
 void f18 (void);
 
 #pragma omp declare target
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-3.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-3.c
index f5d7797f458..0d772d7aaab 100644
--- a/gcc/testsuite/c-c++-common/gomp/declare-variant-3.c
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-3.c
@@ -29,13 +29,13 @@ void f17 (void);
 void f18 (void);
 #pragma omp declare variant (f13) match (device={kind(fpga)})
 void f19 (void);
-#pragma omp declare variant (f13) match (device={kind(any,any)})
+#pragma omp declare variant (f13) match (device={kind(any)})
 void f20 (void);
 #pragma omp declare variant (f13) match (device={kind(host,nohost)})
 void f21 (void);
 #pragma omp declare variant (f13) match (device={kind("cpu","gpu","fpga")})
 void f22 (void);
-#pragma omp declare variant (f13) match (device={kind(any,cpu,nohost)})
+#pragma omp declare variant (f13) match (device={kind(cpu,nohost)})
 void f23 (void);
 #pragma omp declare variant (f13) match (device={isa(avx)})
 void f24 (void);
@@ -139,12 +139,8 @@ void f72 (void);
 void f73 (void);
 #pragma omp declare variant (f13) match (user={condition(score(25):1)})
 void f74 (void);
-#pragma omp declare variant (f13) match (device={kind(any,"any")})
+#pragma omp declare variant (f13) match (device={kind("any")})
 void f75 (void);
-#pragma omp declare variant (f13) match (device={kind("any","any")})
-void f76 (void);
-#pragma omp declare variant (f13) match (device={kind("any",any)})
-void f77 (void);
 #pragma omp declare variant (f13) match (implementation={vendor(nvidia)})
 void f78 (void);
 #pragma omp declare variant (f13) match (user={condition(score(0):0)})
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-9.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-9.c
index 5ee75892f2d..da96c81eb6f 100644
--- a/gcc/testsuite/c-c++-common/gomp/declare-variant-9.c
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-9.c
@@ -7,7 +7,7 @@ void f01 (void);
 #pragma omp declare variant (f01) match (device={isa("avx512f",avx512bw)})
 void f02 (void);
 void f03 (void);
-#pragma omp declare variant (f03) match (device={kind(any),arch(x86_64),isa("avx512f","avx512bw")})
+#pragma omp declare variant (f03) match (device={arch(x86_64),isa("avx512f","avx512bw")})
 void f04 (void);
 void f05 (void);
 #pragma omp declare variant (f05) match (device={kind(gpu)})
@@ -28,7 +28,7 @@ void f15 (void);
 #pragma omp declare variant (f15) match (device={isa(sse4,ssse3),arch(i386)})
 void f16 (void);
 void f17 (void);
-#pragma omp declare variant (f17) match (device={kind("any","fpga")})
+#pragma omp declare variant (f17) match (device={kind("fpga")})
 void f18 (void);
 
 void
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-any.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-any.c
new file mode 100644
index 00000000000..cddf73b64d4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-any.c
@@ -0,0 +1,17 @@
+/* Check that errors are detected if other trait-properties are given with
+   kind(any).  */
+
+extern int f1 (int);
+extern int f2 (int);
+extern int f3 (int);
+extern int f4 (int);
+extern int f5 (int);
+extern int f6 (int);
+
+#pragma omp declare variant (f1) match (device={kind(any,gpu)})  /* { dg-error "no other trait-property may be specified" } */
+#pragma omp declare variant (f2) match (device={kind(cpu,"any")})  /* { dg-error "no other trait-property may be specified" } */
+#pragma omp declare variant (f3) match (device={kind("any"),arch(x86_64)})  /* { dg-error "no other trait-property may be specified" } */
+#pragma omp declare variant (f4) match (device={arch(x86_64),kind(any)})  /* { dg-error "no other trait-property may be specified" } */
+#pragma omp declare variant (f5) match (device={kind(any,"any")})  /* { dg-error "trait-property .any. specified more than once" } */
+#pragma omp declare variant (f6) match (device={kind("any",any)})  /* { dg-error "trait-property .any. specified more than once" } */
+int f (int);
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-duplicates.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-duplicates.c
new file mode 100644
index 00000000000..47d34fc52e2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-duplicates.c
@@ -0,0 +1,13 @@
+/* Check that errors are detected if duplicates appear in name-list
+   properties.  */
+
+extern int f1 (int);
+extern int f2 (int);
+extern int f3 (int);
+extern int f4 (int);
+
+#pragma omp declare variant (f1) match (device={kind(cpu,gpu,"cpu")})  /* { dg-error "trait-property .cpu. specified more than once" } */
+#pragma omp declare variant (f2) match (device={isa(sse4,"avx",avx)})  /* { dg-error "trait-property .avx. specified more than once" } */
+#pragma omp declare variant (f3) match (device={arch(x86_64,i386,aarch64,"i386")})  /* { dg-error "trait-property .i386. specified more than once" } */
+#pragma omp declare variant (f4) match (implementation={vendor(llvm,gnu,"arm",gnu)})  /* { dg-error "trait-property .gnu. specified more than once" } */
+int f (int);
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-10.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-10.f90
index 2f09146a10d..01f59c52808 100644
--- a/gcc/testsuite/gfortran.dg/gomp/declare-variant-10.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-10.f90
@@ -15,7 +15,7 @@ contains
   subroutine f03 ()
   end subroutine
   subroutine f04 ()
-    !$omp declare variant (f03) match (device={kind("any"),arch(x86_64),isa(avx512f,avx512bw)})
+    !$omp declare variant (f03) match (device={arch(x86_64),isa(avx512f,avx512bw)})
   end subroutine
   subroutine f05 ()
   end subroutine
@@ -50,7 +50,7 @@ contains
   subroutine f17 ()
   end subroutine
   subroutine f18 ()
-    !$omp declare variant (f17) match (device={kind(any,fpga)})
+    !$omp declare variant (f17) match (device={kind(fpga)})
   end subroutine
 
   subroutine test1 ()
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-3.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-3.f90
index 6b23d40e410..30733209e14 100644
--- a/gcc/testsuite/gfortran.dg/gomp/declare-variant-3.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-3.f90
@@ -51,7 +51,7 @@ contains
     !$omp declare variant (f13) match (device={kind(fpga)})
   end subroutine
   subroutine f20 ()
-    !$omp declare variant (f13) match (device={kind(any,any)})
+    !$omp declare variant (f13) match (device={kind(any)})
   end subroutine
   subroutine f21 ()
     !$omp declare variant (f13) match (device={kind(host,nohost)})
@@ -60,7 +60,7 @@ contains
     !$omp declare variant (f13) match (device={kind("cpu","gpu","fpga")})
   end subroutine
   subroutine f23 ()
-    !$omp declare variant (f13) match (device={kind(any,cpu,nohost)})
+    !$omp declare variant (f13) match (device={kind(cpu,nohost)})
   end subroutine
   subroutine f24 ()
     !$omp declare variant (f13) match (device={isa(avx)})
@@ -219,13 +219,7 @@ contains
     !$omp declare variant (f13) match (user={condition(score(25):.true.)})
   end subroutine
   subroutine f75 ()
-    !$omp declare variant (f13) match (device={kind(any,"any")})
-  end subroutine
-  subroutine f76 ()
-    !$omp declare variant (f13) match (device={kind("any","any")})
-  end subroutine
-  subroutine f77 ()
-    !$omp declare variant (f13) match (device={kind("any",any)})
+    !$omp declare variant (f13) match (device={kind("any")})
   end subroutine
   subroutine f78 ()
     !$omp declare variant (f13) match (implementation={vendor(nvidia)})
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-9.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-9.f90
index ebd066609f3..297bff97d5e 100644
--- a/gcc/testsuite/gfortran.dg/gomp/declare-variant-9.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-9.f90
@@ -38,7 +38,7 @@ contains
   subroutine f17 ()
   end subroutine
   subroutine f18 ()
-    !$omp declare variant (f17) match (device={kind("any","fpga")})
+    !$omp declare variant (f17) match (device={kind("fpga")})
   end subroutine
 
   subroutine test1 ()
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-any.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-any.f90
new file mode 100644
index 00000000000..c22e27c0c81
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-any.f90
@@ -0,0 +1,40 @@
+! Check that errors are detected if other trait-properties are given with
+! kind(any).
+
+integer function f1 (x)
+  integer, intent(in) :: x
+  f1 = x + 1
+end function
+integer function f2 (x)
+  integer, intent(in) :: x
+  f2 = x + 2
+end function
+integer function f3 (x)
+  integer, intent(in) :: x
+  f3 = x + 3
+end function
+integer function f4 (x)
+  integer, intent(in) :: x
+  f4 = x + 4
+end function
+integer function f5 (x)
+  integer, intent(in) :: x
+  f4 = x + 5
+end function
+integer function f6 (x)
+  integer, intent(in) :: x
+  f4 = x + 6
+end function
+
+integer function f (x)
+  integer, intent(in) :: x
+
+  !$omp declare variant (f1) match (device={kind(any,gpu)})  ! { dg-error "no other trait-property may be specified" }
+  !$omp declare variant (f2) match (device={kind(cpu,"any")})  ! { dg-error "no other trait-property may be specified" }
+  !$omp declare variant (f3) match (device={kind("any"),arch(x86_64)})  ! { dg-error "no other trait-property may be specified" }
+  !$omp declare variant (f4) match (device={arch(x86_64),kind(any)})  ! { dg-error "no other trait-property may be specified" }
+  !$omp declare variant (f5) match (device={kind(any,"any")})  ! { dg-error "trait-property .any. specified more than once" }
+  !$omp declare variant (f6) match (device={kind("any",any)})  ! { dg-error "trait-property .any. specified more than once" }
+
+  f = x
+end function  
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-duplicates.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-duplicates.f90
new file mode 100644
index 00000000000..16dc0858ff9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-duplicates.f90
@@ -0,0 +1,30 @@
+! Check that errors are detected if duplicates appear in name-list
+! properties.
+
+integer function f1 (x)
+  integer, intent(in) :: x
+  f1 = x + 1
+end function
+integer function f2 (x)
+  integer, intent(in) :: x
+  f2 = x + 2
+end function
+integer function f3 (x)
+  integer, intent(in) :: x
+  f3 = x + 3
+end function
+integer function f4 (x)
+  integer, intent(in) :: x
+  f4 = x + 4
+end function
+
+integer function f (x)
+  integer, intent(in) :: x
+
+  !$omp declare variant (f1) match (device={kind(cpu,gpu,"cpu")})  ! { dg-error "trait-property .cpu. specified more than once" }
+  !$omp declare variant (f2) match (device={isa(sse4,"avx",avx)})  ! { dg-error "trait-property .avx. specified more than once" }
+  !$omp declare variant (f3) match (device={arch(x86_64,i386,aarch64,"i386")})  ! { dg-error "trait-property .i386. specified more than once" }
+  !$omp declare variant (f4) match (implementation={vendor(llvm,gnu,"arm",gnu)})  ! { dg-error "trait-property .gnu. specified more than once" }
+
+  f = x
+end function  
-- 
2.25.1

Reply via email to