aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTobias Burnus <tburnus@baylibre.com>2024-12-13 14:27:08 +0100
committerTobias Burnus <tburnus@baylibre.com>2024-12-13 14:27:08 +0100
commit46dd8acffe8264c5586cf5dc489157ea254dc152 (patch)
tree55944444abefdf2f632847b007ab17144bfcbf82 /gcc
parent6dcfe8743134936db17ffdfd0a5102a87338f494 (diff)
downloadgcc-46dd8acffe8264c5586cf5dc489157ea254dc152.zip
gcc-46dd8acffe8264c5586cf5dc489157ea254dc152.tar.gz
gcc-46dd8acffe8264c5586cf5dc489157ea254dc152.tar.bz2
C++: reject OpenMP directives in constexpr functions
gcc/cp/ChangeLog: * parser.cc (cp_parser_omp_construct, cp_parser_pragma): Reject OpenMP expressions in constexpr functions. gcc/testsuite/ChangeLog: * g++.dg/gomp/pr108607.C: Update dg-error. * g++.dg/gomp/pr79664.C: Update dg-error. * g++.dg/gomp/omp-constexpr.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/parser.cc24
-rw-r--r--gcc/testsuite/g++.dg/gomp/omp-constexpr.C45
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr108607.C16
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr79664.C38
4 files changed, 95 insertions, 28 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 15a5253..88641c3 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -52071,7 +52071,18 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
omp_clause_mask mask (0);
- switch (cp_parser_pragma_kind (pragma_tok))
+ unsigned int id = cp_parser_pragma_kind (pragma_tok);
+ if (current_function_decl
+ && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+ && id >= PRAGMA_OMP__START_
+ && id <= PRAGMA_OMP__LAST_)
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "OpenMP directives may not appear in %<constexpr%> functions");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return;
+ }
+ switch (id)
{
case PRAGMA_OACC_ATOMIC:
cp_parser_omp_atomic (parser, pragma_tok, true);
@@ -52596,6 +52607,17 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return false;
}
+ if (current_function_decl
+ && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+ && id >= PRAGMA_OMP__START_
+ && id <= PRAGMA_OMP__LAST_)
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "OpenMP directives may not appear in %<constexpr%> functions");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return false;
+ }
+
if (id != PRAGMA_OMP_DECLARE && id != PRAGMA_OACC_ROUTINE)
cp_ensure_no_omp_declare_simd (parser);
switch (id)
diff --git a/gcc/testsuite/g++.dg/gomp/omp-constexpr.C b/gcc/testsuite/g++.dg/gomp/omp-constexpr.C
new file mode 100644
index 0000000..0d984d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/omp-constexpr.C
@@ -0,0 +1,45 @@
+// { dg-do compile { target c++11 } }
+
+constexpr int
+f ()
+{
+ int a = 42;
+ #pragma omp parallel for simd /* { dg-error "OpenMP directives may not appear in 'constexpr' functions" } */
+ for (int i=0; i < 10; i++)
+ a += i;
+ return a;
+} // { dg-error "not a return-statement" "" { target c++11_down } }
+
+constexpr int
+g ()
+{
+ int a = 42;
+ [[omp::sequence(omp::directive(parallel),omp::directive(for))]] /* { dg-error "OpenMP directives may not appear in 'constexpr' functions" } */
+ for (int i=0; i < 10; i++)
+ a += i;
+ return a;
+} // { dg-error "not a return-statement" "" { target c++11_down } }
+
+constexpr int
+h ()
+{
+ int a = 42;
+ #pragma omp allocate(a) align(128) /* { dg-error "OpenMP directives may not appear in 'constexpr' functions" } */
+ return a;
+} // { dg-error "not a return-statement" "" { target c++11_down } }
+
+constexpr int
+i ()
+{
+ int a [[omp::decl(allocate, align(128))]] = 42; /* { dg-error "OpenMP directives may not appear in 'constexpr' functions" } */
+ return a;
+} // { dg-error "not a return-statement" "" { target c++11_down } }
+
+
+
+int main() {
+ static constexpr int a = f (); // { dg-error "called in a constant expression" "" { target c++11_down } }
+ static constexpr int b = g (); // { dg-error "called in a constant expression" "" { target c++11_down } }
+ static constexpr int c = h (); // { dg-error "called in a constant expression" "" { target c++11_down } }
+ static constexpr int d = i (); // { dg-error "called in a constant expression" "" { target c++11_down } }
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr108607.C b/gcc/testsuite/g++.dg/gomp/pr108607.C
index 9e5137b..d09f49d 100644
--- a/gcc/testsuite/g++.dg/gomp/pr108607.C
+++ b/gcc/testsuite/g++.dg/gomp/pr108607.C
@@ -9,10 +9,10 @@ bar (int x)
}
constexpr int
-foo (int x) // { dg-message "declared here" "" { target c++20_down } }
-{ // { dg-message "is not usable as a 'constexpr' function because" "" { target c++23 } .-1 }
- #pragma omp scope // { dg-warning "is not a constant expression" "" { target c++20_down } }
- x = bar (x); // { dg-error "is not a constant expression" "" { target c++23 } .-1 }
+foo (int x)
+{
+ #pragma omp scope // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
+ x = bar (x);
return x;
}
@@ -24,15 +24,15 @@ baz (int x)
case 42:
return 0;
case 2:
- #pragma omp scope // { dg-error "statement is not a constant expression" }
+ #pragma omp scope // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
x = bar (x);
return x;
case 3:
- #pragma omp parallel // { dg-error "statement is not a constant expression" }
+ #pragma omp parallel // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
x = bar (x);
return x;
case 4:
- #pragma omp task // { dg-error "statement is not a constant expression" }
+ #pragma omp task // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
x = bar (x);
return x;
default:
@@ -40,7 +40,7 @@ baz (int x)
}
}
-constexpr int a = foo (1); // { dg-error "called in a constant expression" }
+constexpr int a = foo (1);
constexpr int b = baz (42);
constexpr int c = baz (2);
constexpr int d = baz (3);
diff --git a/gcc/testsuite/g++.dg/gomp/pr79664.C b/gcc/testsuite/g++.dg/gomp/pr79664.C
index f4c30c0..fb04694 100644
--- a/gcc/testsuite/g++.dg/gomp/pr79664.C
+++ b/gcc/testsuite/g++.dg/gomp/pr79664.C
@@ -6,7 +6,7 @@ constexpr int
f1 ()
{
int i = 0;
-#pragma omp parallel for // { dg-error "is not a constant expression" }
+#pragma omp parallel for // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
for (i = 0; i < 10; ++i)
;
return 0;
@@ -16,7 +16,7 @@ constexpr int
f2 ()
{
int i = 0;
-#pragma omp parallel // { dg-error "is not a constant expression" }
+#pragma omp parallel // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 5;
return 0;
}
@@ -25,7 +25,7 @@ constexpr int
f3 ()
{
int i = 0;
-#pragma omp task // { dg-error "is not a constant expression" }
+#pragma omp task // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 5;
return 0;
}
@@ -34,7 +34,7 @@ constexpr int
f4 ()
{
int i = 0;
-#pragma omp for // { dg-error "is not a constant expression" }
+#pragma omp for // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
for (i = 0; i < 10; ++i)
;
return 0;
@@ -44,7 +44,7 @@ constexpr int
f5 ()
{
int i = 0;
-#pragma omp taskloop // { dg-error "is not a constant expression" }
+#pragma omp taskloop // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
for (i = 0; i < 10; ++i)
;
return 0;
@@ -54,7 +54,7 @@ constexpr int
f6 ()
{
int i = 0;
-#pragma omp target teams // { dg-error "is not a constant expression" }
+#pragma omp target teams // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 5;
return 0;
}
@@ -63,7 +63,7 @@ constexpr int
f7 ()
{
int i = 0;
-#pragma omp target data map(tofrom:i) // { dg-error "is not a constant expression" }
+#pragma omp target data map(tofrom:i) // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 5;
return 0;
}
@@ -72,7 +72,7 @@ constexpr int
f8 ()
{
int i = 0;
-#pragma omp target // { dg-error "is not a constant expression" }
+#pragma omp target // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 5;
return 0;
}
@@ -81,9 +81,9 @@ constexpr int
f9 ()
{
int i = 0;
-#pragma omp sections // { dg-error "is not a constant expression" }
+#pragma omp sections // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
{
-#pragma omp section
+#pragma omp section // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 5;
}
return 0;
@@ -93,7 +93,7 @@ constexpr int
f10 ()
{
int i = 0;
-#pragma omp ordered // { dg-error "is not a constant expression" }
+#pragma omp ordered // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 1;
return 0;
}
@@ -102,7 +102,7 @@ constexpr int
f11 ()
{
int i = 0;
-#pragma omp critical // { dg-error "is not a constant expression" }
+#pragma omp critical // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 1;
return 0;
}
@@ -111,7 +111,7 @@ constexpr int
f12 ()
{
int i = 0;
-#pragma omp single // { dg-error "is not a constant expression" }
+#pragma omp single // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 1;
return 0;
}
@@ -120,7 +120,7 @@ constexpr int
f13 ()
{
int i = 0;
-#pragma omp master // { dg-error "is not a constant expression" }
+#pragma omp master // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 1;
return 0;
}
@@ -129,7 +129,7 @@ constexpr int
f14 ()
{
int i = 0;
-#pragma omp taskgroup // { dg-error "is not a constant expression" }
+#pragma omp taskgroup // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 1;
return 0;
}
@@ -138,7 +138,7 @@ constexpr int
f15 ()
{
int i = 0;
-#pragma omp target update to(i) // { dg-error "is not a constant expression" }
+#pragma omp target update to(i) // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
i = 1;
return 0;
}
@@ -147,7 +147,7 @@ constexpr int
f16 ()
{
int i = 0;
-#pragma omp target update to(i) // { dg-error "is not a constant expression" }
+#pragma omp target update to(i) // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
return 0;
}
@@ -155,7 +155,7 @@ constexpr int
f17 ()
{
int i = 0;
-#pragma omp target enter data map(to:i) // { dg-error "is not a constant expression" }
+#pragma omp target enter data map(to:i) // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
return 0;
}
@@ -163,6 +163,6 @@ constexpr int
f18 ()
{
int i = 0;
-#pragma omp target exit data map(from:i) // { dg-error "is not a constant expression" }
+#pragma omp target exit data map(from:i) // { dg-error "OpenMP directives may not appear in 'constexpr' functions" }
return 0;
}