https://gcc.gnu.org/g:325b88b9a4588c08c4dca9bc9ff19f029e90cc45
commit r17-515-g325b88b9a4588c08c4dca9bc9ff19f029e90cc45 Author: Tobias Burnus <[email protected]> Date: Thu May 14 18:23:57 2026 +0200 OpenMP: mapper [C/C++] reject w/o map usage, reject C++98, fix map decay This commit adds a check for the following 'declare mapper restriction: "At least one map clause that maps var or at least one element of var is required." It additionally fixes a bug in the map-decay code, which did not handle map modifiers like 'always' when specified in the declare mapper's map clause. For C++, some checks are now also run when templates are involved. Additionally, it turned out that the internal use of constexpr caused bogus errors when compiled with -std=c++98; therefore, a sorry is now shown. Solution is to use -std=c++11 or higher. gcc/c-family/ChangeLog: * c-omp.cc (omp_map_decayed_kind): Handle map modifiers also for declare-mapper's map clauses. gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_declare_mapper): Check that the struct var is actually used by at least one map clause. gcc/cp/ChangeLog: * semantics.cc (cp_check_omp_declare_mapper): Change what argument is expected; check that the struct var is used by at least one map war. Print sorry when compiling with -std=c++98. * pt.cc (tsubst_stmt, tsubst_expr): Call it. * parser.cc (cp_parser_omp_declare_mapper): Update call. gcc/testsuite/ChangeLog: * c-c++-common/gomp/declare-mapper-10.c: Exclude C++98. * c-c++-common/gomp/declare-mapper-15.c: Likewise. * c-c++-common/gomp/declare-mapper-16.c: Likewise. * c-c++-common/gomp/declare-mapper-3.c: Likewise. * c-c++-common/gomp/declare-mapper-4.c: Likewise. * c-c++-common/gomp/declare-mapper-5.c: Likewise. * c-c++-common/gomp/declare-mapper-6.c: Likewise. * c-c++-common/gomp/declare-mapper-7.c: Likewise. * c-c++-common/gomp/declare-mapper-8.c: Likewise. * c-c++-common/gomp/declare-mapper-9.c: Likewise. * g++.dg/gomp/declare-mapper-1.C: Likewise. * g++.dg/gomp/declare-mapper-2.C: Likewise. * c-c++-common/gomp/pr122866.c: Expect sorry with C++98. * c-c++-common/gomp/declare-mapper-11.c: Likewise. Add dg-error for missing var-in-map-clause use. * g++.dg/gomp/declare-mapper-3.C: Likewise. * c-c++-common/gomp/declare-mapper-17.c: New test. * c-c++-common/gomp/declare-mapper-18.c: New test. * g++.dg/gomp/declare-mapper-4.C: New test. * g++.dg/gomp/declare-mapper-5.C: New test. Diff: --- gcc/c-family/c-omp.cc | 5 ++- gcc/c/c-parser.cc | 12 +++++ gcc/cp/parser.cc | 2 +- gcc/cp/pt.cc | 2 + gcc/cp/semantics.cc | 52 ++++++++++++++++++++-- .../c-c++-common/gomp/declare-mapper-10.c | 2 +- .../c-c++-common/gomp/declare-mapper-11.c | 5 +++ .../c-c++-common/gomp/declare-mapper-15.c | 2 +- .../c-c++-common/gomp/declare-mapper-16.c | 2 +- .../c-c++-common/gomp/declare-mapper-17.c | 23 ++++++++++ .../c-c++-common/gomp/declare-mapper-18.c | 39 ++++++++++++++++ gcc/testsuite/c-c++-common/gomp/declare-mapper-3.c | 2 +- gcc/testsuite/c-c++-common/gomp/declare-mapper-4.c | 2 +- gcc/testsuite/c-c++-common/gomp/declare-mapper-5.c | 2 +- gcc/testsuite/c-c++-common/gomp/declare-mapper-6.c | 3 +- gcc/testsuite/c-c++-common/gomp/declare-mapper-7.c | 3 +- gcc/testsuite/c-c++-common/gomp/declare-mapper-8.c | 2 +- gcc/testsuite/c-c++-common/gomp/declare-mapper-9.c | 2 +- gcc/testsuite/c-c++-common/gomp/pr122866.c | 1 + gcc/testsuite/g++.dg/gomp/declare-mapper-1.C | 2 +- gcc/testsuite/g++.dg/gomp/declare-mapper-2.C | 2 +- gcc/testsuite/g++.dg/gomp/declare-mapper-3.C | 6 +++ gcc/testsuite/g++.dg/gomp/declare-mapper-4.C | 23 ++++++++++ gcc/testsuite/g++.dg/gomp/declare-mapper-5.C | 29 ++++++++++++ 24 files changed, 207 insertions(+), 18 deletions(-) diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc index f75f0788ac66..b48243a22616 100644 --- a/gcc/c-family/c-omp.cc +++ b/gcc/c-family/c-omp.cc @@ -4517,8 +4517,10 @@ omp_map_decayed_kind (enum gomp_map_kind mapper_kind, if (invoked_as == GOMP_MAP_RELEASE || invoked_as == GOMP_MAP_DELETE) return invoked_as; + bool m_force_p, m_always_p, m_present_p; bool force_p, always_p, present_p; + mapper_kind = omp_split_map_kind (mapper_kind, &m_force_p, &m_always_p, &m_present_p); invoked_as = omp_split_map_kind (invoked_as, &force_p, &always_p, &present_p); gomp_map_kind decay_to; @@ -4556,7 +4558,8 @@ omp_map_decayed_kind (enum gomp_map_kind mapper_kind, gcc_unreachable (); } - return omp_join_map_kind (decay_to, force_p, always_p, present_p); + return omp_join_map_kind (decay_to, m_force_p | force_p, + m_always_p | always_p, m_present_p | present_p); } /* Instantiate a mapper MAPPER for expression EXPR, adding new clauses to diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index daf57061ee9a..07c7900c332e 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -29219,6 +29219,18 @@ c_parser_omp_declare_mapper (c_parser *parser, enum pragma_context context) error_at (input_location, "missing %<map%> clause"); goto fail; } + tree list; + for (list = maplist; list; list = OMP_CLAUSE_CHAIN (list)) + { + tree dvar = OMP_CLAUSE_DECL (list); + while (!DECL_P (dvar) && TREE_OPERAND_LENGTH (dvar)) + dvar = TREE_OPERAND (dvar, 0); + if (dvar == var) + break; + } + if (!list) + error_at (input_location, "at least one %<map%> clause must map %qD or an " + "element of it", var); stmt = make_node (OMP_DECLARE_MAPPER); TREE_TYPE (stmt) = type; diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index c7708f15f39b..1ab462160da8 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -55723,7 +55723,7 @@ cp_parser_omp_declare_mapper (cp_parser *parser, cp_token *pragma_tok, else pushdecl (vardecl); - cp_check_omp_declare_mapper (vardecl); + cp_check_omp_declare_mapper (mapper); cp_parser_require_pragma_eol (parser, pragma_tok); return; diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index b6e8948f005a..d19864774a3c 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -20762,6 +20762,7 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t complain, tree in_decl) TREE_TYPE (t) = type; OMP_DECLARE_MAPPER_DECL (t) = decl; OMP_DECLARE_MAPPER_CLAUSES (t) = clauses; + cp_check_omp_declare_mapper (t); RETURN (t); } @@ -21881,6 +21882,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) TREE_TYPE (t) = type; OMP_DECLARE_MAPPER_DECL (t) = decl; OMP_DECLARE_MAPPER_CLAUSES (t) = clauses; + cp_check_omp_declare_mapper (t); RETURN (t); } diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index e9fc01ef28fb..6564d9e37a6f 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -7440,25 +7440,69 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor) bool cp_check_omp_declare_mapper (tree udm) { - tree type = TREE_TYPE (udm); - location_t loc = DECL_SOURCE_LOCATION (udm); + tree var = OMP_DECLARE_MAPPER_DECL (udm); + tree type = TREE_TYPE (var); + location_t loc = DECL_SOURCE_LOCATION (var); if (type == error_mark_node) return false; - if (!processing_template_decl && !RECORD_OR_UNION_TYPE_P (type)) + if (processing_template_decl) + return true; + + if (!RECORD_OR_UNION_TYPE_P (type)) { error_at (loc, "%qT is not a struct, union or class type in " "%<#pragma omp declare mapper%>", type); return false; } - if (!processing_template_decl && CLASSTYPE_VBASECLASSES (type)) + if (CLASSTYPE_VBASECLASSES (type)) { error_at (loc, "%qT must not be a virtual base class in " "%<#pragma omp declare mapper%>", type); return false; } + tree c = OMP_DECLARE_MAPPER_CLAUSES (udm); + for ( ; c; c = OMP_CLAUSE_CHAIN (c)) + { + tree dvar = OMP_CLAUSE_DECL (c); + while (!DECL_P (dvar) && TREE_OPERAND_LENGTH (dvar)) + dvar = TREE_OPERAND (dvar, 0); + if (dvar == var) + break; + } + if (!c) + { + // After template handling, the var is mangled, demangle it + const char *name = IDENTIFIER_POINTER (DECL_NAME (var)); + char *n = NULL; + if (startswith (name, "omp declare mapper ")) + { + name += strlen ("omp declare mapper "); + n = xstrdup (name); + n[strchr (n, '~')-n] = '\0'; + name = n; + } + error_at (loc, "at least one %<map%> clause must map %qs or an " + "element of it", name); + if (n) + free (n); + return false; + } + + /* FIXME: The vardecl created for the mapper_id uses DECL_DECLARED_CONSTEXPR_P + = 1, which is set to false in finalize_literal_type_property for C++ < 11, + leading to an error in ensure_literal_type_for_constexpr_object. + Examples (compile with -std=c++98): gcc.dg/gomp/declare-mapper-13.c and + libgomp.c++/declare-mapper-{5,6,8}.C. */ + if (cxx_dialect < cxx11) + { + sorry_at (loc, "%<#pragma omp declare mapper%> with %<-std=%> set to " + "before C++11"); + return false; + } + return true; } diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-10.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-10.c index 4020c4bae307..6d0f285ee029 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-10.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-10.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { c || c++11 } } } */ /* { dg-additional-options "-fdump-tree-gimple" } */ struct S { diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-11.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-11.c index 1f65bad694dd..89d84db87a04 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-11.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-11.c @@ -18,9 +18,11 @@ struct XT { // { dg-error "expected primary-expression before '\\)' token" "" { target c++ } .-1 } // { dg-error "unknown type name 'XT'" "" { target c } .-2 } // { dg-error "expected end of line before 'y'" "" { target c } .-3 } +// { dg-error "at least one 'map' clause must map 'y' or an element of it" "" { target c++ } .-4 } #pragma omp declare mapper ( bar : struct XT y) map() // { dg-error "expected primary-expression before '\\)' token" "" { target c++ } .-1 } // { dg-error "expected expression before '\\)' token" "" { target c } .-2 } +// { dg-error "at least one 'map' clause must map 'y' or an element of it" "" { target *-*-* } .-3 } struct t { int x; @@ -45,8 +47,10 @@ typedef struct t myStruct; // { dg-error "expected primary-expression before '\\)' token" "" { target c++ } .-1 } // { dg-error "unknown type name 't'" "" { target c } .-2 } // { dg-error "expected end of line before 'v'" "" { target c } .-3 } +// { dg-error "at least one 'map' clause must map 'v' or an element of it" "" { target c++ } .-4 } #pragma omp declare mapper(fancy : struct t v) map(always,present,close,mapper(d),tofrom: v) // { dg-error "in 'declare mapper' directives, parameter to 'mapper' modifier must be 'default'" } +// { dg-message "sorry, unimplemented: '#pragma omp declare mapper' with '-std=' set to before C++11" "" { target c++98_only } .-1 } #pragma omp declare mapper(myStruct v) map(v, v.x) // { dg-note "'#pragma omp declare mapper \\(myStruct\\)' previously declared here" "" { target c++ } .-1 } @@ -61,6 +65,7 @@ union u_q { }; #pragma omp declare mapper(union u_t v) map() // { dg-error "expected primary-expression before '\\)' token" "" { target c++ } .-1 } // { dg-error "expected expression before '\\)' token" "" { target c } .-2 } +// { dg-error "at least one 'map' clause must map 'v' or an element of it" "" { target *-*-* } .-3 } #pragma omp declare mapper( one : union u_t v) map(v) // { dg-note "'#pragma omp declare mapper \\(one: u_t\\)' previously declared here" "" { target c++ } .-1 } diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-15.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-15.c index ecda2e5ebd1a..2d5c50eb4eae 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-15.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-15.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { c || c++11 } } } */ /* { dg-options "-fopenmp -fdump-tree-gimple" } */ typedef struct { diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-16.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-16.c index 20383cc2d69f..ba3559293c4d 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-16.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-16.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { c || c++11 } } } */ /* { dg-options "-fopenmp -fdump-tree-gimple" } */ typedef struct { diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-17.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-17.c new file mode 100644 index 000000000000..a77896fe4cc3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-17.c @@ -0,0 +1,23 @@ +typedef struct S { int x;} S; +int x; +S s; + +void f() { + #pragma omp declare mapper(S var) map(to: x) /* { dg-error "at least one 'map' clause must map 'var' or an element of it" } */ + #pragma omp target enter data map(s) +} + +void f2() +{ + int x; + #pragma omp declare mapper (int var) map(always, to: var) +// { dg-error "'int' is not a struct or union type in '#pragma omp declare mapper'" "" { target c } .-1 } +// { dg-error "'int' is not a struct, union or class type in '#pragma omp declare mapper'" "" { target c++ } .-2 } + #pragma omp target enter data map(x) +} + +void f3() { + float g[2]; + #pragma omp declare mapper (S var) map(always, to: g[var.x]) // { dg-error "at least one 'map' clause must map 'var' or an element of it" } + #pragma omp target enter data map(g) +} diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-18.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-18.c new file mode 100644 index 000000000000..6b53b1b1e18d --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-18.c @@ -0,0 +1,39 @@ +// { dg-do compile { target { c || c++11 } } } +// { dg-additional-options "-fdump-tree-gimple" } + +typedef struct S { int x;} S; +int x; +S s1; +S s2; + +void f() { + #pragma omp declare mapper(S var) map(to: var) + #pragma omp target exit data map(always, from: s1) +} + +void f2() { + #pragma omp declare mapper(S var) map(present, to: var) + #pragma omp target enter data map(always, tofrom : s2) +} + +void f3() +{ + S x; + int y; + #pragma omp declare mapper (S var) map(always, to: var, y) + #pragma omp target enter data map(x) +} + + +// to + 'exit date' always from -> release +// { dg final { scan-dump "static int omp declare mapper <default> = struct S #pragma omp declare mapper \\(struct S var\\) map\\(to:var\\);" "gimple" } +// { dg final { scan-dump "#pragma omp target exit data map\\(release:s1 \\\[len: 4\\\]\\)" "gimple" } + + +// present,to + always,from -> always,present,to +// { dg final { scan-dump "static int omp declare mapper <default> = struct S #pragma omp declare mapper \\(struct S var\\) map\\(present,to:var\\);" "gimple" } +// { dg final { scan-dump "#pragma omp target enter data map\\(always,present,to:s2 \\\[len: 4\\\]\\)" "gimple" } + +// always,to + - -> always,to +// { dg final { scan-dump "static int omp declare mapper <default> = struct S #pragma omp declare mapper \\(struct S var\\) map\\(always,to:y\\) map\\(always,to:var\\);" "gimple" } +// { dg final { scan-dump "#pragma omp target enter data map\\(always,to:y \\\[len: 4\\\]\\) map\\(always,to:x \\\[len: 4\\\]\\)" "gimple" } diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-3.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-3.c index c0ec21b1b380..c78e54293b96 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-3.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-3.c @@ -1,4 +1,4 @@ -// { dg-do compile } +// { dg-do compile { target { c || c++11 } } } // { dg-additional-options "-fdump-tree-gimple" } #include <stdlib.h> diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-4.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-4.c index 39e3ab114199..55a9af8edef6 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-4.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-4.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { c || c++11 } } } */ /* { dg-additional-options "-fdump-tree-original" } */ /* Check mapper binding clauses. */ diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-5.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-5.c index e8ab15941419..7671595f8d5d 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-5.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-5.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { c || c++11 } } } */ typedef struct S_ { int *myarr; diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-6.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-6.c index c13eb8b5816e..6d0b607041ae 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-6.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-6.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { c || c++11 } } } */ int x = 5; @@ -19,5 +19,6 @@ struct R { #pragma omp declare mapper (struct R myr) map(myr.arr3[0:y]) /* { dg-error "'y' undeclared" "" { target c } .-1 } */ /* { dg-error "'y' was not declared in this scope" "" { target c++ } .-2 } */ +/* { dg-error "at least one 'map' clause must map 'myr' or an element of it" "" { target c++ } .-3 } */ int y = 7; diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-7.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-7.c index 0f8dd25a18dc..acd00678b569 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-7.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-7.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { c || c++11 } } } */ struct Q { int *arr1; @@ -24,6 +24,7 @@ int bar (void) #pragma omp declare mapper (struct R myr) map(myr.arr3[0:y]) /* { dg-error "'y' undeclared" "" { target c } .-1 } */ /* { dg-error "'y' was not declared in this scope" "" { target c++ } .-2 } */ + /* { dg-error "at least one 'map' clause must map 'myr' or an element of it" "" { target c++ } .-3 } */ int y = 7; return y; } diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-8.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-8.c index dadca282711c..6cf25df0ab7f 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-8.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-8.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { c || c++11 } } } */ struct Q { int *arr1; diff --git a/gcc/testsuite/c-c++-common/gomp/declare-mapper-9.c b/gcc/testsuite/c-c++-common/gomp/declare-mapper-9.c index 709bc0c8f4de..6e00bb688f6c 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-mapper-9.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-mapper-9.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { c || c++11 } } } */ int x = 5; diff --git a/gcc/testsuite/c-c++-common/gomp/pr122866.c b/gcc/testsuite/c-c++-common/gomp/pr122866.c index bb42bc634dbd..58972e1b9f41 100644 --- a/gcc/testsuite/c-c++-common/gomp/pr122866.c +++ b/gcc/testsuite/c-c++-common/gomp/pr122866.c @@ -8,6 +8,7 @@ void froggify (struct test); #pragma omp declare mapper(struct test v) map(iterator(i = 0:1), tofrom: v.x) /* { dg-message "sorry, unimplemented: user-defined mapper that uses a .map. clause with .iterator." "" { target *-*-* } .-1 } */ +/* { dg-message "'#pragma omp declare mapper' with '-std=' set to before C++11" "" { target c++98_only } .-2 } */ int main () diff --git a/gcc/testsuite/g++.dg/gomp/declare-mapper-1.C b/gcc/testsuite/g++.dg/gomp/declare-mapper-1.C index 2f2dd219bcb5..f74c3bb38929 100644 --- a/gcc/testsuite/g++.dg/gomp/declare-mapper-1.C +++ b/gcc/testsuite/g++.dg/gomp/declare-mapper-1.C @@ -1,4 +1,4 @@ -// { dg-do compile } +// { dg-do compile { target c++11 } } // { dg-additional-options "-fdump-tree-gimple" } // "omp declare mapper" support -- check expansion in gimple. diff --git a/gcc/testsuite/g++.dg/gomp/declare-mapper-2.C b/gcc/testsuite/g++.dg/gomp/declare-mapper-2.C index 379be2900182..cf2e4d0aaa3c 100644 --- a/gcc/testsuite/g++.dg/gomp/declare-mapper-2.C +++ b/gcc/testsuite/g++.dg/gomp/declare-mapper-2.C @@ -1,4 +1,4 @@ -// { dg-do compile } +// { dg-do compile { target c++11 } } // Error-checking tests for "omp declare mapper". diff --git a/gcc/testsuite/g++.dg/gomp/declare-mapper-3.C b/gcc/testsuite/g++.dg/gomp/declare-mapper-3.C index 1f019c710ca1..4ad09b2ffd2e 100644 --- a/gcc/testsuite/g++.dg/gomp/declare-mapper-3.C +++ b/gcc/testsuite/g++.dg/gomp/declare-mapper-3.C @@ -1,3 +1,5 @@ +// { dg-do compile { target c++11 } } + #pragma omp declare mapper (int v) // { dg-error "missing 'map' clause before end of line" } #pragma omp declare mapper (float v) map() // { dg-error "expected primary-expression before '\\)' token" } // { dg-error "'float' is not a struct, union or class type in '#pragma omp declare mapper'" "" { target *-*-* } .-1 } @@ -8,6 +10,8 @@ struct XT { int x; }; #pragma omp declare mapper (XT y) map() // { dg-error "expected primary-expression before '\\)' token" } +// { dg-error "at least one 'map' clause must map 'y' or an element of it" "" { target *-*-* } .-1 } + struct t { int x; @@ -20,6 +24,7 @@ typedef struct t myStruct; #pragma omp declare mapper(myStruct) // { dg-error "expected unqualified-id before '\\)' token" } #pragma omp declare mapper(name : t v) map() // { dg-error "expected primary-expression before '\\)' token" } +// { dg-error "at least one 'map' clause must map 'v' or an element of it" "" { target *-*-* } .-1 } #pragma omp declare mapper(fancy : struct t v) map(always,present,close,mapper(d),tofrom: v) // { dg-error "in 'declare mapper' directives, parameter to 'mapper' modifier must be 'default'" } @@ -37,3 +42,4 @@ class B : public virtual A { }; union u_t { }; #pragma omp declare mapper(u_t v) map() // { dg-error "expected primary-expression before '\\)' token" } +// { dg-error "at least one 'map' clause must map 'v' or an element of it" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/g++.dg/gomp/declare-mapper-4.C b/gcc/testsuite/g++.dg/gomp/declare-mapper-4.C new file mode 100644 index 000000000000..52ad3d7e95ff --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/declare-mapper-4.C @@ -0,0 +1,23 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fdump-tree-original" } + +// Ensure that always in mapper does not ICE and gets propagated to both 'x' and 'y' + +struct S { int x; }; + +template<typename T> +void f() +{ + T x; + int y; + #pragma omp declare mapper (T var) map(always, to: var, y) +// error: the type 'S' of 'constexpr' variable '#pragma omp declare mapper' is not literal + #pragma omp target enter data map(x) +} + +void g() +{ + f<S>(); +} + +// { dg-final { scan-tree-dump "#pragma omp target enter data map\\(always,to:y\\) map\\(always,to:x\\)" "original" } } diff --git a/gcc/testsuite/g++.dg/gomp/declare-mapper-5.C b/gcc/testsuite/g++.dg/gomp/declare-mapper-5.C new file mode 100644 index 000000000000..b20b5e2ff71d --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/declare-mapper-5.C @@ -0,0 +1,29 @@ +// { dg-do compile { target c++11 } } + +struct S { int x; }; + +template<typename T> +void f() +{ + T x; + int y; + #pragma omp declare mapper (T var) map(always, to: var, y) // { dg-error "'int' is not a struct, union or class type in '#pragma omp declare mapper'" } + #pragma omp target enter data map(x) +} + +void g() +{ + f<int>(); +} + +template<typename T> +void h() { + T g[2]; + #pragma omp declare mapper (S var) map(always, to: g[var.x]) // { dg-error "at least one 'map' clause must map 'var' or an element of it" } + #pragma omp target enter data map(g) +} + +void h2() +{ + h<S>(); +}
