[09/12] OpenMP/C++: Diagnose constexpr vars in an allocate directive

Message ID 20260505151030.1749548-10-waffl3x@baylibre.com
State New
Headers
Series OpenMP/C++: 'allocate' directive |

Commit Message

Waffl3x May 5, 2026, 3:02 p.m. UTC
  It is unclear whether this should be allowed or not. For now, diagnose it
until one can come up with a compelling reason to allow it.

gcc/cp/ChangeLog:

	* parser.cc (cp_parser_omp_allocate): Add diagnostics.

gcc/testsuite/ChangeLog:

	* g++.dg/gomp/allocate-15.C: Add cases.

Signed-off-by: Waffl3x <waffl3x@baylibre.com>
---
 gcc/cp/parser.cc                        | 13 ++++++++
 gcc/testsuite/g++.dg/gomp/allocate-15.C | 42 +++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
  

Patch

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index aa6777e5ed4..791ac2d6ea9 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -47254,6 +47254,19 @@  cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)
 	    continue;
 	  }
 
+	if (DECL_DECLARED_CONSTEXPR_P (var))
+	  {
+	    auto_diagnostic_group d;
+	    error_at (arg_loc,
+		      "constexpr variable %qD may not appear as list item in "
+		      "an %<allocate%> directive", var);
+	    inform (DECL_SOURCE_LOCATION (var),
+		    "%qD declared here", var);
+	    /* Remove the node.  */
+	    *chain = TREE_CHAIN (node);
+	    continue;
+	  }
+
 	/* Do this before checking if the var was used in another allocate
 	   directive, as the latter diagnostic implies that removing the var
 	   from the previous directive would fix the problem.  */
diff --git a/gcc/testsuite/g++.dg/gomp/allocate-15.C b/gcc/testsuite/g++.dg/gomp/allocate-15.C
index 605e10e477f..ef4bd098fa9 100644
--- a/gcc/testsuite/g++.dg/gomp/allocate-15.C
+++ b/gcc/testsuite/g++.dg/gomp/allocate-15.C
@@ -48,3 +48,45 @@  void instantiate_var_templ()
   dependent_var_templ<int const&&>(); /* { dg-message "required from here" } */
 }
 
+
+/* Diagnostics for constexpr vars used in an allocate directive.  */
+
+void cx_var()
+{
+  constexpr int cx = 42; /* { dg-note "'cx' declared here" } */
+  #pragma omp allocate(cx) /* { dg-error "constexpr variable 'cx' may not appear as list item in an 'allocate' directive" } */
+}
+
+template<typename>
+void cx_var_templ_not_instantiated()
+{
+  constexpr int cx = 42; /* { dg-note "'cx' declared here" } */
+  #pragma omp allocate(cx) /* { dg-error "constexpr variable 'cx' may not appear as list item in an 'allocate' directive" } */
+}
+
+template<typename>
+void cx_var_templ()
+{
+  constexpr int cx = 42; /* { dg-note "'cx' declared here" } */
+  #pragma omp allocate(cx) /* { dg-error "constexpr variable 'cx' may not appear as list item in an 'allocate' directive" } */
+}
+
+template<typename T>
+void dependent_cx_var_templ_not_instantiated()
+{
+  constexpr T cx = 42; /* { dg-note "'cx' declared here" } */
+  #pragma omp allocate(cx) /* { dg-error "constexpr variable 'cx' may not appear as list item in an 'allocate' directive" } */
+}
+
+template<typename T>
+void dependent_cx_var_templ()
+{
+  constexpr T cx = 42; /* { dg-note "'cx' declared here" } */
+  #pragma omp allocate(cx) /* { dg-error "constexpr variable 'cx' may not appear as list item in an 'allocate' directive" } */
+}
+
+void instantiate_cx_templ()
+{
+  cx_var_templ<void>();
+  dependent_cx_var_templ<int>();
+}