aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2023-10-26 12:05:26 +0200
committerPaul-Antoine Arras <parras@baylibre.com>2024-06-27 17:58:13 +0200
commitfa71b9884775505aa2281829a7e90042e6bbb616 (patch)
tree2afacd869b3385ab18fb93789444b0a4749a4c02
parent2d14b0787c3f5acbbcd642ebf0352cb120e3012d (diff)
downloadgcc-fa71b9884775505aa2281829a7e90042e6bbb616.zip
gcc-fa71b9884775505aa2281829a7e90042e6bbb616.tar.gz
gcc-fa71b9884775505aa2281829a7e90042e6bbb616.tar.bz2
OpenMP: Add C++ support for 'omp allocate' with stack variables
gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_allocate): Change error wording. gcc/cp/ChangeLog: * cp-tree.h (finish_omp_allocate): New prototype. * parser.cc (struct cp_omp_loc_tree, cp_check_omp_allocate_allocator_r): New. (cp_parser_omp_allocate): Call it; remove sorry, improve checks, call finish_omp_allocate. * pt.cc (tsubst_stmt): Call finish_omp_allocate. * semantics.cc (finish_omp_allocate): New. libgomp/ChangeLog: * libgomp.texi (OpenMP Impl. Status): Document that 'omp allocate' is now supported for C++ stack/automatic variables. * testsuite/libgomp.c-c++-common/allocate-4.c: Renamed from ... * testsuite/libgomp.c/allocate-4.c: ... this. * testsuite/libgomp.c-c++-common/allocate-5.c: Renamed from ... * testsuite/libgomp.c/allocate-5.c: ... this. * testsuite/libgomp.c-c++-common/allocate-6.c: Renamed from ... * testsuite/libgomp.c/allocate-6.c: ... this. * testsuite/libgomp.c++/allocate-2.C: New test. gcc/testsuite/ChangeLog: * c-c++-common/gomp/allocate-5.c: Remove C++ 'sorry'; minor updates. * c-c++-common/gomp/allocate-9.c: Likewise. * c-c++-common/gomp/allocate-17.c: Likewise. * c-c++-common/gomp/directive-1.c: Likewise. * g++.dg/gomp/allocate-5.C: New test.
-rw-r--r--gcc/c/ChangeLog.omp5
-rw-r--r--gcc/c/c-parser.cc2
-rw-r--r--gcc/cp/ChangeLog.omp10
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/parser.cc149
-rw-r--r--gcc/cp/pt.cc4
-rw-r--r--gcc/cp/semantics.cc80
-rw-r--r--gcc/testsuite/ChangeLog.omp8
-rw-r--r--gcc/testsuite/c-c++-common/gomp/allocate-17.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/allocate-5.c24
-rw-r--r--gcc/testsuite/c-c++-common/gomp/allocate-9.c59
-rw-r--r--gcc/testsuite/c-c++-common/gomp/directive-1.c1
-rw-r--r--gcc/testsuite/c-c++-common/gomp/uses_allocators-1.c4
-rw-r--r--gcc/testsuite/g++.dg/gomp/allocate-5.C14
-rw-r--r--libgomp/ChangeLog.omp12
-rw-r--r--libgomp/libgomp.texi6
-rw-r--r--libgomp/testsuite/libgomp.c++/allocate-2.C329
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/allocate-4.c (renamed from libgomp/testsuite/libgomp.c/allocate-4.c)3
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/allocate-5.c (renamed from libgomp/testsuite/libgomp.c/allocate-5.c)3
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/allocate-6.c (renamed from libgomp/testsuite/libgomp.c/allocate-6.c)3
20 files changed, 605 insertions, 117 deletions
diff --git a/gcc/c/ChangeLog.omp b/gcc/c/ChangeLog.omp
index 21fa92f..ddc8129 100644
--- a/gcc/c/ChangeLog.omp
+++ b/gcc/c/ChangeLog.omp
@@ -1,3 +1,8 @@
+2023-10-26 Tobias Burnus <tobias@codesourcery.com>
+
+ * c-parser.cc (c_parser_omp_allocate): Change error
+ wording.
+
2023-08-10 Julian Brown <julian@codesourcery.com>
* c-parser.cc (c_parser_omp_variable_list): Support array-shaping
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index bf0fe09..ace44d6 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -21544,7 +21544,7 @@ c_parser_omp_allocate (c_parser *parser)
!= get_identifier ("omp_allocator_handle_t"))
{
error_at (expr_loc,
- "%<allocator%> clause allocator expression has type "
+ "%<allocator%> clause expression has type "
"%qT rather than %<omp_allocator_handle_t%>",
TREE_TYPE (allocator));
allocator = NULL_TREE;
diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp
index d3f607c..d87a21e 100644
--- a/gcc/cp/ChangeLog.omp
+++ b/gcc/cp/ChangeLog.omp
@@ -1,3 +1,13 @@
+2023-10-26 Tobias Burnus <tobias@codesourcery.com>
+
+ * cp-tree.h (finish_omp_allocate): New prototype.
+ * parser.cc (struct cp_omp_loc_tree,
+ cp_check_omp_allocate_allocator_r): New.
+ (cp_parser_omp_allocate): Call it; remove sorry,
+ improve checks, call finish_omp_allocate.
+ * pt.cc (tsubst_stmt): Call finish_omp_allocate.
+ * semantics.cc (finish_omp_allocate): New.
+
2023-08-10 Julian Brown <julian@codesourcery.com>
* parser.cc (cp_parser_omp_var_list_no_open): Support array-shaping
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 422093d..d5469b0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7924,6 +7924,10 @@ extern tree finish_omp_for (location_t, enum tree_code,
tree, tree, tree, tree, tree,
tree, tree, vec<tree> *, tree);
extern tree finish_omp_for_block (tree, tree);
+extern void finish_omp_allocate (bool, location_t, tree,
+ tree = NULL_TREE,
+ tsubst_flags_t = tf_warning_or_error,
+ tree = NULL_TREE);
extern void finish_omp_atomic (location_t, enum tree_code,
enum tree_code, tree, tree,
tree, tree, tree, tree, tree,
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index ae28730..c047535 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -43316,6 +43316,67 @@ cp_parser_omp_structured_block (cp_parser *parser, bool *if_p)
return finish_omp_structured_block (stmt);
}
+struct cp_omp_loc_tree
+{
+ location_t loc;
+ tree var;
+};
+
+/* Check whether the expression used in the allocator clause is declared or
+ modified between the variable declaration and its allocate directive. */
+static tree
+cp_check_omp_allocate_allocator_r (tree *tp, int *, void *data)
+{
+ tree var = ((struct cp_omp_loc_tree *) data)->var;
+ location_t loc = ((struct cp_omp_loc_tree *) data)->loc;
+ tree v = NULL_TREE;
+ if (TREE_CODE (*tp) == VAR_DECL)
+ for (v = current_binding_level->names; v; v = TREE_CHAIN (v))
+ if (v == var)
+ break;
+ if (v != NULL_TREE)
+ {
+ if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
+ DECL_SOURCE_LOCATION (*tp)))
+ {
+ error_at (loc, "variable %qD used in the %<allocator%> clause must "
+ "be declared before %qD", *tp, var);
+ inform (DECL_SOURCE_LOCATION (*tp), "declared here");
+ inform (DECL_SOURCE_LOCATION (var),
+ "to be allocated variable declared here");
+ return *tp;
+ }
+ else
+ {
+ gcc_assert (cur_stmt_list
+ && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
+
+ tree_stmt_iterator l = tsi_last (cur_stmt_list);
+ while (!tsi_end_p (l))
+ {
+ if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
+ DECL_SOURCE_LOCATION (var)))
+ break;
+ if (TREE_CODE (*l) == MODIFY_EXPR
+ && TREE_OPERAND (*l, 0) == *tp)
+ {
+ error_at (loc,
+ "variable %qD used in the %<allocator%> clause "
+ "must not be modified between declaration of %qD "
+ "and its %<allocate%> directive", *tp, var);
+ inform (EXPR_LOCATION (*l), "modified here");
+ inform (DECL_SOURCE_LOCATION (var),
+ "to be allocated variable declared here");
+ return *tp;
+ }
+ --l;
+ }
+ }
+ }
+ return NULL_TREE;
+}
+
+
/* OpenMP 5.x:
# pragma omp allocate (list) clauses
@@ -43330,7 +43391,6 @@ cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)
{
tree allocator = NULL_TREE;
tree alignment = NULL_TREE;
- location_t loc = pragma_tok->location;
tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
do
@@ -43360,63 +43420,56 @@ cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)
break;
}
else if (p[2] == 'i')
- {
- if (expr != error_mark_node)
- alignment = expr;
- /* FIXME: Remove when adding check to semantics.cc; cf FIXME below. */
- if (alignment
- && !type_dependent_expression_p (alignment)
- && !INTEGRAL_TYPE_P (TREE_TYPE (alignment)))
- {
- error_at (cloc, "%<align%> clause argument needs to be "
- "positive constant power of two integer "
- "expression");
- alignment = NULL_TREE;
- }
- else if (alignment)
- {
- alignment = mark_rvalue_use (alignment);
- if (!processing_template_decl)
- {
- alignment = maybe_constant_value (alignment);
- if (TREE_CODE (alignment) != INTEGER_CST
- || !tree_fits_uhwi_p (alignment)
- || !integer_pow2p (alignment))
- {
- error_at (cloc, "%<align%> clause argument needs to be "
- "positive constant power of two integer "
- "expression");
- alignment = NULL_TREE;
- }
- }
- }
- }
+ alignment = expr;
else if (allocator)
{
error_at (cloc, "too many %qs clauses", "allocator");
break;
}
else
- {
- if (expr != error_mark_node)
- allocator = expr;
- }
+ allocator = expr;
parens.require_close (parser);
} while (true);
cp_parser_require_pragma_eol (parser, pragma_tok);
- if (allocator || alignment)
- for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
- {
- OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
- OMP_CLAUSE_ALLOCATE_ALIGN (c) = alignment;
- }
-
- /* FIXME: When implementing properly, delete the align/allocate expr error
- check above and add one in semantics.cc (to properly handle templates).
- Base this on the allocator/align modifiers check for the 'allocate' clause
- in semantics.cc's finish_omp_clauses. */
- sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
+ for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
+ {
+ tree var = OMP_CLAUSE_DECL (c);
+ if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (nl),
+ "%qD already appeared as list item in an "
+ "%<allocate%> directive", var);
+ continue;
+ }
+ if (TREE_CODE (var) == PARM_DECL)
+ {
+ error_at (OMP_CLAUSE_LOCATION (nl),
+ "function parameter %qD may not appear as list item in an "
+ "%<allocate%> directive", var);
+ continue;
+ }
+ tree v;
+ for (v = current_binding_level->names; v; v = TREE_CHAIN (v))
+ if (v == var)
+ break;
+ if (v == NULL_TREE)
+ {
+ error_at (OMP_CLAUSE_LOCATION (nl),
+ "%<allocate%> directive must be in the same scope as %qD",
+ var);
+ inform (DECL_SOURCE_LOCATION (var), "declared here");
+ continue;
+ }
+ struct cp_omp_loc_tree data
+ = {EXPR_LOC_OR_LOC (allocator, OMP_CLAUSE_LOCATION (nl)), var};
+ walk_tree (&allocator, cp_check_omp_allocate_allocator_r, &data, NULL);
+ DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"),
+ build_tree_list (allocator, alignment),
+ DECL_ATTRIBUTES (var));
+ if (!processing_template_decl)
+ finish_omp_allocate (true, OMP_CLAUSE_LOCATION (nl), var);
+ }
}
/* OpenMP 2.5:
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index a577847..5568e51 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -18659,6 +18659,10 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t complain, tree in_decl)
cp_finish_decl (decl, init, const_init, asmspec_tree, 0,
decomp);
+ if (flag_openmp && VAR_P (decl))
+ finish_omp_allocate (false, DECL_SOURCE_LOCATION (decl),
+ decl, args, complain, in_decl);
+
if (ndecl != error_mark_node)
cp_finish_decomp (ndecl, decomp);
}
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 3332688..5fab248 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -11761,6 +11761,86 @@ finish_omp_for_block (tree bind, tree omp_for)
}
void
+finish_omp_allocate (bool in_parsing, location_t loc, tree decl, tree args,
+ tsubst_flags_t complain, tree in_decl)
+{
+ location_t loc2;
+ tree attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl));
+ if (attr == NULL_TREE)
+ return;
+
+ tree allocator = TREE_PURPOSE (TREE_VALUE (attr));
+ tree alignment = TREE_VALUE (TREE_VALUE (attr));
+
+ if (alignment == error_mark_node)
+ TREE_VALUE (TREE_VALUE (attr)) = NULL_TREE;
+ else if (alignment)
+ {
+ location_t loc2 = EXPR_LOCATION (alignment);
+ if (!in_parsing)
+ alignment = tsubst_expr (alignment, args, complain, in_decl);
+ alignment = fold_non_dependent_expr (alignment);
+
+ if (TREE_CODE (alignment) != INTEGER_CST
+ || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
+ || tree_int_cst_sgn (alignment) != 1
+ || !integer_pow2p (alignment))
+ {
+ error_at (loc2, "%<align%> clause argument needs to be positive "
+ "constant power of two integer expression");
+ TREE_VALUE (TREE_VALUE (attr)) = NULL_TREE;
+ }
+ else
+ TREE_VALUE (TREE_VALUE (attr)) = alignment;
+ }
+ loc2 = allocator ? EXPR_LOCATION (allocator) : UNKNOWN_LOCATION;
+ if (allocator == error_mark_node)
+ {
+ allocator = TREE_PURPOSE (TREE_VALUE (attr)) = NULL_TREE;
+ return;
+ }
+ else
+ {
+ if (!in_parsing)
+ allocator = tsubst_expr (allocator, args, complain, in_decl);
+ allocator = fold_non_dependent_expr (allocator);
+ }
+
+ if (allocator)
+ {
+ tree orig_type = TYPE_MAIN_VARIANT (TREE_TYPE (allocator));
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
+ || TREE_CODE (orig_type) != ENUMERAL_TYPE
+ || TYPE_NAME (orig_type) == NULL_TREE
+ || (DECL_NAME (TYPE_NAME (orig_type))
+ != get_identifier ("omp_allocator_handle_t")))
+ {
+ error_at (loc2, "%<allocator%> clause expression has type "
+ "%qT rather than %<omp_allocator_handle_t%>",
+ TREE_TYPE (allocator));
+ allocator = TREE_PURPOSE (TREE_VALUE (attr)) = NULL_TREE;
+ }
+ else
+ TREE_PURPOSE (TREE_VALUE (attr)) = fold_non_dependent_expr (allocator);
+ }
+ if (TREE_STATIC (decl))
+ {
+ if (allocator == NULL_TREE)
+ error_at (loc, "%<allocator%> clause required for "
+ "static variable %qD", decl);
+ else if (allocator
+ && (wi::to_widest (allocator) < 1
+ || wi::to_widest (allocator) > 8))
+ /* 8 = largest predefined memory allocator. */
+ error_at (loc2, "%<allocator%> clause requires a predefined allocator "
+ "as %qD is static", decl);
+ else
+ sorry_at (loc, "%<#pragma omp allocate%> for static variables like %qD "
+ "not yet supported", decl);
+ }
+}
+
+void
finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
tree lhs, tree rhs, tree v, tree lhs1, tree rhs1, tree r,
tree clauses, enum omp_memory_order mo, bool weak)
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 2ddf24b..aa7b8a1 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,11 @@
+2023-10-26 Tobias Burnus <tobias@codesourcery.com>
+
+ * c-c++-common/gomp/allocate-5.c: Remove C++ 'sorry'; minor updates.
+ * c-c++-common/gomp/allocate-9.c: Likewise.
+ * c-c++-common/gomp/allocate-17.c: Likewise.
+ * c-c++-common/gomp/directive-1.c: Likewise.
+ * g++.dg/gomp/allocate-5.C: New test.
+
2023-08-10 Julian Brown <julian@codesourcery.com>
* c-c++-common/gomp/declare-mapper-17.c: New test.
diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-17.c b/gcc/testsuite/c-c++-common/gomp/allocate-17.c
index f75af0c..2a896cc 100644
--- a/gcc/testsuite/c-c++-common/gomp/allocate-17.c
+++ b/gcc/testsuite/c-c++-common/gomp/allocate-17.c
@@ -20,7 +20,7 @@ one ()
#pragma omp target map(tofrom: result) firstprivate(n)
{
int var = 5; //, var2[n];
- #pragma omp allocate(var) align(128) allocator(omp_low_lat_mem_alloc) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */
+ #pragma omp allocate(var) align(128) allocator(omp_low_lat_mem_alloc)
var = 7;
}
diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-5.c b/gcc/testsuite/c-c++-common/gomp/allocate-5.c
index 2ca4786..b9eed15 100644
--- a/gcc/testsuite/c-c++-common/gomp/allocate-5.c
+++ b/gcc/testsuite/c-c++-common/gomp/allocate-5.c
@@ -21,11 +21,10 @@ foo ()
omp_allocator_handle_t my_allocator = omp_default_mem_alloc;
int a, b;
static int c;
-#pragma omp allocate (a) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */
-#pragma omp allocate (b) allocator(my_allocator) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */
+#pragma omp allocate (a)
+#pragma omp allocate (b) allocator(my_allocator)
#pragma omp allocate(c) align(32)
- /* { dg-message "'allocator' clause required for static variable 'c'" "" { target c } .-1 } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */
+ /* { dg-message "'allocator' clause required for static variable 'c'" "" { target *-*-* } .-1 } */
}
void
@@ -34,14 +33,12 @@ bar ()
int a, a2, b;
omp_allocator_handle_t my_allocator;
#pragma omp allocate /* { dg-error "expected '\\(' before end of line" } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
#pragma omp allocate allocator(my_allocator) /* { dg-error "expected '\\(' before 'allocator'" } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
#pragma omp allocate(a) foo(my_allocator) /* { dg-error "expected 'allocator'" } */
/* { dg-error "expected end of line before '\\(' token" "" { target *-*-* } .-1 } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */
-#pragma omp allocate(a2) allocator(b) /* { dg-error "'allocator' clause allocator expression has type 'int' rather than 'omp_allocator_handle_t'" "todo: cp/semantics.c" { xfail c++ } } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
+#pragma omp allocate(a2) allocator(b) /* { dg-error "'allocator' clause expression has type 'int' rather than 'omp_allocator_handle_t'" } */
+ /* The following error is correct albeit slightly surprising: */
+ /* { dg-error "variable 'b' used in the 'allocator' clause must be declared before 'a2'" "" { target c++ } .-2 } */
}
@@ -50,22 +47,16 @@ align_test ()
{
int i1,i2,i3,i4,i5,i6;
#pragma omp allocate(i1) allocator(omp_default_mem_alloc), align(32)
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
#pragma omp allocate(i2) align ( 32 ),allocator(omp_default_mem_alloc)
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
#pragma omp allocate(i3),allocator(omp_default_mem_alloc) align(32)
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
#pragma omp allocate(i4) align ( 32 ) allocator(omp_default_mem_alloc)
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
#pragma omp allocate(i5) allocator ( omp_high_bw_mem_alloc ), align ( 32 ) allocator(omp_default_mem_alloc)
/* { dg-error "too many 'allocator' clauses" "" { target *-*-* } .-1 } */
/* { dg-error "expected end of line before '\\)' token" "" { target *-*-* } .-2 } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-3 } */
#pragma omp allocate(i6) align ( 32 ), align(32) allocator(omp_default_mem_alloc)
/* { dg-error "too many 'align' clauses" "" { target *-*-* } .-1 } */
/* { dg-error "expected end of line before '\\)' token" "" { target *-*-* } .-2 } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-3 } */
}
void
@@ -73,9 +64,6 @@ align_test2 ()
{
int i, i2,i3;
#pragma omp allocate(i) align (32.0) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
#pragma omp allocate(i2) align ( 31 ) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
#pragma omp allocate(i3) align ( -32 ) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */
- /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
}
diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-9.c b/gcc/testsuite/c-c++-common/gomp/allocate-9.c
index 3138274..aaa52b3 100644
--- a/gcc/testsuite/c-c++-common/gomp/allocate-9.c
+++ b/gcc/testsuite/c-c++-common/gomp/allocate-9.c
@@ -17,7 +17,11 @@ typedef enum omp_allocator_handle_t
} omp_allocator_handle_t;
-static int A[5] = {1,2,3,4,5};
+static int A1[5] = {1,2,3,4,5};
+static int A2[5] = {1,2,3,4,5};
+static int A3[5] = {1,2,3,4,5};
+static int A4[5] = {1,2,3,4,5};
+static int A5[5] = {1,2,3,4,5};
int B, C, D;
/* If the following fails because of added predefined allocators, please update
@@ -27,72 +31,60 @@ int B, C, D;
- libgomp/libgomp.texi (document the new values - multiple locations)
+ ensure that the memory-spaces are also up to date. */
-#pragma omp allocate(A) align(32) allocator((omp_allocator_handle_t) 9) /* { dg-error "'allocator' clause requires a predefined allocator as 'A' is static" "" { xfail c++ } } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
+#pragma omp allocate(A1) align(32) allocator((omp_allocator_handle_t) 9) /* { dg-error "'allocator' clause requires a predefined allocator as 'A1' is static" } */
// typo in allocator name:
-#pragma omp allocate(A) allocator(omp_low_latency_mem_alloc)
+#pragma omp allocate(A2) allocator(omp_low_latency_mem_alloc)
/* { dg-error "'omp_low_latency_mem_alloc' undeclared here \\(not in a function\\); did you mean 'omp_low_lat_mem_alloc'\\?" "" { target c } .-1 } */
/* { dg-error "'omp_low_latency_mem_alloc' was not declared in this scope; did you mean 'omp_low_lat_mem_alloc'\\?" "" { target c++ } .-2 } */
-/* { dg-error "'allocator' clause required for static variable 'A'" "" { target c } .-3 } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-4 } */
+/* { dg-error "'allocator' clause required for static variable 'A2'" "" { target c } .-3 } */
/* align be const multiple of 2 */
-#pragma omp allocate(A) align(31) allocator(omp_default_mem_alloc) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'A' not yet supported" "" { target c } .-1 } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */
+#pragma omp allocate(A3) align(31) allocator(omp_default_mem_alloc) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */
+/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'A3' not yet supported" "" { target *-*-* } .-1 } */
/* allocator missing (required as A is static) */
-#pragma omp allocate(A) align(32) /* { dg-error "'allocator' clause required for static variable 'A'" "" { xfail c++ } } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
+#pragma omp allocate(A4) align(32) /* { dg-error "'allocator' clause required for static variable 'A4'" } */
/* "expression in the clause must be a constant expression that evaluates to one of the
predefined memory allocator values -> omp_low_lat_mem_alloc" */
#pragma omp allocate(B) allocator((omp_allocator_handle_t) (omp_high_bw_mem_alloc+1)) align(32) /* OK: omp_low_lat_mem_alloc */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'B' not yet supported" "" { target c } .-1 } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */
+/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'B' not yet supported" "" { target *-*-* } .-1 } */
#pragma omp allocate(C) allocator((omp_allocator_handle_t) 2) /* OK: omp_large_cap_mem_alloc */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'C' not yet supported" "" { target c } .-1 } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */
+/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'C' not yet supported" "" { target *-*-* } .-1 } */
-#pragma omp allocate(A) align(32) allocator(omp_null_allocator) /* { dg-error "'allocator' clause requires a predefined allocator as 'A' is static" "" { xfail c++ } } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
+#pragma omp allocate(A5) align(32) allocator(omp_null_allocator) /* { dg-error "'allocator' clause requires a predefined allocator as 'A5' is static" } */
-#pragma omp allocate(C) align(32) allocator(omp_large_cap_mem_alloc) /* { dg-error "'C' already appeared as list item in an 'allocate' directive" "" { xfail *-*-* } } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'C' not yet supported" "" { target c } .-1 } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */
+#pragma omp allocate(C) align(32) allocator(omp_large_cap_mem_alloc)
+/* { dg-error "'C' already appeared as list item in an 'allocate' directive" "" { target c++ } .-1 } */
+/* { dg-message "sorry, unimplemented: '#pragma omp allocate' for static variables like 'C' not yet supported" "" { target c } .-2 } */
// allocate directive in same TU
int f()
{
- #pragma omp allocate(D) align(32) allocator(omp_large_cap_mem_alloc) /* { dg-error "'allocate' directive must be in the same scope as 'D'" "" { xfail c++ } } */
-/* { dg-note "declared here" "" { target c } 21 } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */
- return A[0];
+ #pragma omp allocate(D) align(32) allocator(omp_large_cap_mem_alloc) /* { dg-error "'allocate' directive must be in the same scope as 'D'" } */
+/* { dg-note "declared here" "" { target *-*-* } 25 } */
+ return A1[0];
}
int g()
{
int a2=1, b2=2;
#pragma omp allocate(a2)
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
- #pragma omp allocate(a2) /* { dg-error "'a2' already appeared as list item in an 'allocate' directive" "" { xfail c++ } } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
+ #pragma omp allocate(a2) /* { dg-error "'a2' already appeared as list item in an 'allocate' directive" } */
{
int c2=3;
- #pragma omp allocate(c2, b2) /* { dg-error "'allocate' directive must be in the same scope as 'b2'" "" { xfail c++ } } */
-/* { dg-note "declared here" "" { target c } .-8 } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-2 } */
+ #pragma omp allocate(c2, b2) /* { dg-error "'allocate' directive must be in the same scope as 'b2'" } */
+/* { dg-note "declared here" "" { target *-*-* } .-6 } */
return c2+a2+b2;
}
}
int h(int q)
{
- #pragma omp allocate(q) /* { dg-error "function parameter 'q' may not appear as list item in an 'allocate' directive" "" { xfail c++ } } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
+ #pragma omp allocate(q) /* { dg-error "function parameter 'q' may not appear as list item in an 'allocate' directive" } */
return q;
}
@@ -100,7 +92,6 @@ int
k ()
{
static int var3 = 8;
- #pragma omp allocate(var3) allocator((omp_allocator_handle_t)-1L) /* { dg-error "'allocator' clause requires a predefined allocator as 'var3' is static" "" { target c } } */
-/* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */
+ #pragma omp allocate(var3) allocator((omp_allocator_handle_t)-1L) /* { dg-error "'allocator' clause requires a predefined allocator as 'var3' is static" } */
return var3;
}
diff --git a/gcc/testsuite/c-c++-common/gomp/directive-1.c b/gcc/testsuite/c-c++-common/gomp/directive-1.c
index 21ca319..e3ede6e 100644
--- a/gcc/testsuite/c-c++-common/gomp/directive-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/directive-1.c
@@ -19,7 +19,6 @@ foo (void)
int i, k = 0, l = 0;
#pragma omp allocate, (i) /* { dg-error "expected '\\\(' before ',' token" } */
/* { dg-error "expected end of line before ',' token" "" { target c++ } .-1 } */
- /* { dg-message "not yet supported" "" { target c++ } .-2 } */
#pragma omp critical, (bar) /* { dg-error "expected an OpenMP clause before '\\\(' token" } */
;
#pragma omp flush, (k, l) /* { dg-error "expected '\\\(' or end of line before ',' token" "" { target c } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/uses_allocators-1.c b/gcc/testsuite/c-c++-common/gomp/uses_allocators-1.c
index 5a2e4a9..acfd5b7 100644
--- a/gcc/testsuite/c-c++-common/gomp/uses_allocators-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/uses_allocators-1.c
@@ -22,7 +22,7 @@ f (omp_allocator_handle_t my_alloc)
#pragma omp target
{
int a; /* { dg-error "'my_alloc' in 'allocator' clause inside a target region must be specified in an 'uses_allocators' clause on the 'target' directive" "" { target c } } */
- #pragma omp allocate(a) allocator(my_alloc) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */
+ #pragma omp allocate(a) allocator(my_alloc) /* { dg-error "'my_alloc' in 'allocator' clause inside a target region must be specified in an 'uses_allocators' clause on the 'target' directive" "" { target c++ } } */
a = 5;
void *prt = omp_alloc(32, my_alloc);
#pragma omp parallel allocate(allocator(my_alloc) : a) firstprivate(a) /* { dg-error "allocator 'my_alloc' in 'allocate' clause inside a target region must be specified in an 'uses_allocators' clause on the 'target' directive" } */
@@ -37,7 +37,7 @@ g (omp_allocator_handle_t my_alloc)
#pragma omp target uses_allocators(my_alloc)
{
int a;
- #pragma omp allocate(a) allocator(my_alloc) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */
+ #pragma omp allocate(a) allocator(my_alloc)
a = 5;
void *prt = omp_alloc(32, my_alloc);
#pragma omp parallel allocate(allocator(my_alloc) : a) firstprivate(a)
diff --git a/gcc/testsuite/g++.dg/gomp/allocate-5.C b/gcc/testsuite/g++.dg/gomp/allocate-5.C
new file mode 100644
index 0000000..39f423c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/allocate-5.C
@@ -0,0 +1,14 @@
+template<typename t>
+t
+foo()
+{
+ t var = 5;
+ #pragma omp allocate(var) align(sizeof(t) + 1) /* { dg-error "'align' clause argument needs to be positive constant power of two integer expression" } */
+ return var;
+}
+
+int
+b()
+{
+ return foo<float>(); /* { dg-message "required from here" } */
+}
diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index a053803..0903418 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,3 +1,15 @@
+2023-10-26 Tobias Burnus <tobias@codesourcery.com>
+
+ * libgomp.texi (OpenMP Impl. Status): Document that 'omp allocate'
+ is now supported for C++ stack/automatic variables.
+ * testsuite/libgomp.c-c++-common/allocate-4.c: Renamed from ...
+ * testsuite/libgomp.c/allocate-4.c: ... this.
+ * testsuite/libgomp.c-c++-common/allocate-5.c: Renamed from ...
+ * testsuite/libgomp.c/allocate-5.c: ... this.
+ * testsuite/libgomp.c-c++-common/allocate-6.c: Renamed from ...
+ * testsuite/libgomp.c/allocate-6.c: ... this.
+ * testsuite/libgomp.c++/allocate-2.C: New test.
+
2023-09-19 Julian Brown <julian@codesourcery.com>
* target.c (omp_target_memcpy_rect_worker): Add 1D strided transfer
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index d635a32..409023b 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -233,8 +233,8 @@ The OpenMP 4.5 specification is fully supported.
@tab Y @tab See also @ref{Memory allocation}
@item Memory management routines @tab Y @tab
@item @code{allocate} directive @tab P
- @tab Only C for stack/automatic and Fortran for stack/automatic
- and allocatable/pointer variables
+ @tab Stack/automatic variables and, for Fortran, allocatable/pointer
+ variables
@item @code{allocate} clause @tab P @tab Initial support
@item @code{use_device_addr} clause on @code{target data} @tab Y @tab
@item @code{ancestor} modifier on @code{device} clause @tab Y @tab
@@ -306,7 +306,7 @@ The OpenMP 4.5 specification is fully supported.
@item @code{strict} modifier in the @code{grainsize} and @code{num_tasks}
clauses of the @code{taskloop} construct @tab Y @tab
@item @code{align} clause in @code{allocate} directive @tab P
- @tab Only C and Fortran (and not for static variables)
+ @tab Only for stack variables
@item @code{align} modifier in @code{allocate} clause @tab Y @tab
@item @code{thread_limit} clause to @code{target} construct @tab Y @tab
@item @code{has_device_addr} clause to @code{target} construct @tab Y @tab
diff --git a/libgomp/testsuite/libgomp.c++/allocate-2.C b/libgomp/testsuite/libgomp.c++/allocate-2.C
new file mode 100644
index 0000000..f79cada
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/allocate-2.C
@@ -0,0 +1,329 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fdump-tree-omplower" } */
+
+/* For the 4 vars in omp_parallel, 4 in omp_target and 1 of 2 in each of no_alloc{,2}_func. */
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_alloc \\(" 10 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_free \\(" 10 "omplower" } } */
+
+#include <omp.h>
+
+
+void
+check_int (int *x, int y)
+{
+ if (*x != y)
+ __builtin_abort ();
+}
+
+void
+check_ptr (int **x, int *y)
+{
+ if (*x != y)
+ __builtin_abort ();
+}
+
+
+template<typename t>
+t
+no_alloc_func ()
+{
+ /* There is no __builtin_GOMP_alloc / __builtin_GOMP_free as
+ allocator == omp_default_mem_alloc (known at compile time. */
+ t no_alloc, alloc_has_align = 3;
+ #pragma omp allocate(no_alloc) allocator(omp_default_mem_alloc)
+ /* But this one is allocated because of align. */
+ #pragma omp allocate(alloc_has_align) allocator(omp_default_mem_alloc) align(sizeof(t))
+ no_alloc = 7;
+ return no_alloc + alloc_has_align;
+}
+
+template<typename t>
+t
+no_alloc2_func()
+{
+ /* There is no __builtin_GOMP_alloc / __builtin_GOMP_free as
+ no_alloc2 is TREE_UNUSED. But there is for is_alloc2. */
+ t no_alloc2, is_alloc2;
+ #pragma omp allocate(no_alloc2, is_alloc2)
+ is_alloc2 = 7;
+ return is_alloc2;
+}
+
+
+template<typename t>
+void
+omp_parallel ()
+{
+ int n = 6;
+ t iii = 5, jjj[5], kkk[n];
+ t *ptr = (t *) 0x1234;
+ #pragma omp allocate(iii, jjj, kkk, ptr)
+
+ for (int i = 0; i < 5; i++)
+ jjj[i] = 3*i;
+ for (int i = 0; i < 6; i++)
+ kkk[i] = 7*i;
+
+ #pragma omp parallel default(none) firstprivate(iii, jjj, kkk, ptr) if(0)
+ {
+ if (iii != 5)
+ __builtin_abort();
+ iii = 7;
+ check_int (&iii, 7);
+ for (int i = 0; i < 5; i++)
+ if (jjj[i] != 3*i)
+ __builtin_abort ();
+ for (int i = 0; i < 6; i++)
+ if (kkk[i] != 7*i)
+ __builtin_abort ();
+ for (int i = 0; i < 5; i++)
+ jjj[i] = 4*i;
+ for (int i = 0; i < 6; i++)
+ kkk[i] = 8*i;
+ for (int i = 0; i < 5; i++)
+ check_int (&jjj[i], 4*i);
+ for (int i = 0; i < 6; i++)
+ check_int (&kkk[i], 8*i);
+ if (ptr != (int *) 0x1234)
+ __builtin_abort ();
+ ptr = (int *) 0xabcd;
+ if (ptr != (int *) 0xabcd)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0xabcd);
+ }
+ if (iii != 5)
+ __builtin_abort ();
+ check_int (&iii, 5);
+ for (int i = 0; i < 5; i++)
+ {
+ if (jjj[i] != 3*i)
+ __builtin_abort ();
+ check_int (&jjj[i], 3*i);
+ }
+ for (int i = 0; i < 6; i++)
+ {
+ if (kkk[i] != 7*i)
+ __builtin_abort ();
+ check_int (&kkk[i], 7*i);
+ }
+ if (ptr != (int *) 0x1234)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0x1234);
+
+ #pragma omp parallel default(firstprivate) if(0)
+ {
+ if (iii != 5)
+ __builtin_abort();
+ iii = 7;
+ check_int (&iii, 7);
+ for (int i = 0; i < 5; i++)
+ if (jjj[i] != 3*i)
+ __builtin_abort ();
+ for (int i = 0; i < 6; i++)
+ if (kkk[i] != 7*i)
+ __builtin_abort ();
+ for (int i = 0; i < 5; i++)
+ jjj[i] = 4*i;
+ for (int i = 0; i < 6; i++)
+ kkk[i] = 8*i;
+ for (int i = 0; i < 5; i++)
+ check_int (&jjj[i], 4*i);
+ for (int i = 0; i < 6; i++)
+ check_int (&kkk[i], 8*i);
+ if (ptr != (int *) 0x1234)
+ __builtin_abort ();
+ ptr = (int *) 0xabcd;
+ if (ptr != (int *) 0xabcd)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0xabcd);
+ }
+ if (iii != 5)
+ __builtin_abort ();
+ check_int (&iii, 5);
+ for (int i = 0; i < 5; i++)
+ {
+ if (jjj[i] != 3*i)
+ __builtin_abort ();
+ check_int (&jjj[i], 3*i);
+ }
+ for (int i = 0; i < 6; i++)
+ {
+ if (kkk[i] != 7*i)
+ __builtin_abort ();
+ check_int (&kkk[i], 7*i);
+ }
+ if (ptr != (int *) 0x1234)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0x1234);
+}
+
+
+template<typename t>
+void
+omp_target ()
+{
+ int n = 6;
+ t iii = 5, jjj[5], kkk[n];
+ t *ptr = (int *) 0x1234;
+ #pragma omp allocate(iii, jjj, kkk, ptr)
+
+ for (int i = 0; i < 5; i++)
+ jjj[i] = 3*i;
+ for (int i = 0; i < 6; i++)
+ kkk[i] = 7*i;
+
+ #pragma omp target defaultmap(none) firstprivate(iii, jjj, kkk, ptr)
+ {
+ if (iii != 5)
+ __builtin_abort();
+ iii = 7;
+ check_int (&iii, 7);
+ for (int i = 0; i < 5; i++)
+ if (jjj[i] != 3*i)
+ __builtin_abort ();
+ for (int i = 0; i < 6; i++)
+ if (kkk[i] != 7*i)
+ __builtin_abort ();
+ for (int i = 0; i < 5; i++)
+ jjj[i] = 4*i;
+ for (int i = 0; i < 6; i++)
+ kkk[i] = 8*i;
+ for (int i = 0; i < 5; i++)
+ check_int (&jjj[i], 4*i);
+ for (int i = 0; i < 6; i++)
+ check_int (&kkk[i], 8*i);
+ if (ptr != (int *) 0x1234)
+ __builtin_abort ();
+ ptr = (int *) 0xabcd;
+ if (ptr != (int *) 0xabcd)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0xabcd);
+ }
+ if (iii != 5)
+ __builtin_abort ();
+ check_int (&iii, 5);
+ for (int i = 0; i < 5; i++)
+ {
+ if (jjj[i] != 3*i)
+ __builtin_abort ();
+ check_int (&jjj[i], 3*i);
+ }
+ for (int i = 0; i < 6; i++)
+ {
+ if (kkk[i] != 7*i)
+ __builtin_abort ();
+ check_int (&kkk[i], 7*i);
+ }
+ if (ptr != (int *) 0x1234)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0x1234);
+
+ #pragma omp target defaultmap(firstprivate)
+ {
+ if (iii != 5)
+ __builtin_abort();
+ iii = 7;
+ check_int (&iii, 7);
+ for (int i = 0; i < 5; i++)
+ if (jjj[i] != 3*i)
+ __builtin_abort ();
+ for (int i = 0; i < 6; i++)
+ if (kkk[i] != 7*i)
+ __builtin_abort ();
+ for (int i = 0; i < 5; i++)
+ jjj[i] = 4*i;
+ for (int i = 0; i < 6; i++)
+ kkk[i] = 8*i;
+ for (int i = 0; i < 5; i++)
+ check_int (&jjj[i], 4*i);
+ for (int i = 0; i < 6; i++)
+ check_int (&kkk[i], 8*i);
+ if (ptr != (int *) 0x1234)
+ __builtin_abort ();
+ ptr = (int *) 0xabcd;
+ if (ptr != (int *) 0xabcd)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0xabcd);
+ }
+ if (iii != 5)
+ __builtin_abort ();
+ check_int (&iii, 5);
+ for (int i = 0; i < 5; i++)
+ {
+ if (jjj[i] != 3*i)
+ __builtin_abort ();
+ check_int (&jjj[i], 3*i);
+ }
+ for (int i = 0; i < 6; i++)
+ {
+ if (kkk[i] != 7*i)
+ __builtin_abort ();
+ check_int (&kkk[i], 7*i);
+ }
+ if (ptr != (int *) 0x1234)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0x1234);
+
+ #pragma omp target defaultmap(tofrom)
+ {
+ if (iii != 5)
+ __builtin_abort();
+ iii = 7;
+ check_int (&iii, 7);
+ for (int i = 0; i < 5; i++)
+ if (jjj[i] != 3*i)
+ __builtin_abort ();
+ for (int i = 0; i < 6; i++)
+ if (kkk[i] != 7*i)
+ __builtin_abort ();
+ for (int i = 0; i < 5; i++)
+ jjj[i] = 4*i;
+ for (int i = 0; i < 6; i++)
+ kkk[i] = 8*i;
+ for (int i = 0; i < 5; i++)
+ check_int (&jjj[i], 4*i);
+ for (int i = 0; i < 6; i++)
+ check_int (&kkk[i], 8*i);
+ if (ptr != (int *) 0x1234)
+ __builtin_abort ();
+ ptr = (int *) 0xabcd;
+ if (ptr != (int *) 0xabcd)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0xabcd);
+ }
+
+ if (iii != 7)
+ __builtin_abort ();
+ check_int (&iii, 7);
+ for (int i = 0; i < 5; i++)
+ {
+ if (jjj[i] != 4*i)
+ __builtin_abort ();
+ check_int (&jjj[i], 4*i);
+ }
+ for (int i = 0; i < 6; i++)
+ {
+ if (kkk[i] != 8*i)
+ __builtin_abort ();
+ check_int (&kkk[i], 8*i);
+ }
+ if (ptr != (int *) 0xabcd)
+ __builtin_abort ();
+ check_ptr (&ptr, (int *) 0xabcd);
+}
+
+int
+foo()
+{
+ return no_alloc_func<int>() + no_alloc2_func<int>();
+}
+
+int
+main ()
+{
+ omp_parallel<int> ();
+ omp_target<int> ();
+ if (foo() != 10 + 7)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/allocate-4.c b/libgomp/testsuite/libgomp.c-c++-common/allocate-4.c
index e81cc40..706c851 100644
--- a/libgomp/testsuite/libgomp.c/allocate-4.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/allocate-4.c
@@ -1,6 +1,3 @@
-/* TODO: move to ../libgomp.c-c++-common once C++ is implemented. */
-/* NOTE: { target c } is unsupported with with the C compiler. */
-
/* { dg-do run } */
/* { dg-additional-options "-fdump-tree-gimple" } */
diff --git a/libgomp/testsuite/libgomp.c/allocate-5.c b/libgomp/testsuite/libgomp.c-c++-common/allocate-5.c
index beaf164..3bbe78d 100644
--- a/libgomp/testsuite/libgomp.c/allocate-5.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/allocate-5.c
@@ -1,6 +1,3 @@
-/* TODO: move to ../libgomp.c-c++-common once C++ is implemented. */
-/* NOTE: { target c } is unsupported with with the C compiler. */
-
/* { dg-do run } */
/* { dg-additional-options "-fdump-tree-gimple" } */
diff --git a/libgomp/testsuite/libgomp.c/allocate-6.c b/libgomp/testsuite/libgomp.c-c++-common/allocate-6.c
index 6d7278c..669581b 100644
--- a/libgomp/testsuite/libgomp.c/allocate-6.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/allocate-6.c
@@ -1,6 +1,3 @@
-/* TODO: move to ../libgomp.c-c++-common once C++ is implemented. */
-/* NOTE: { target c } is unsupported with with the C compiler. */
-
/* { dg-do run } */
/* { dg-additional-options "-fdump-tree-omplower" } */