From 59bc434a3327ce58f7afcd1e9209eeb2da714960 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 27 Sep 2019 22:14:24 +0200 Subject: [PATCH] re PR c++/88203 (assert does not compile with OpenMP's pragma omp parallel for default(none)) PR c++/88203 c-family/ * c-common.h (c_omp_predefined_variable): Declare. * c-omp.c (c_omp_predefined_variable): New function. (c_omp_predetermined_sharing): Return OMP_CLAUSE_DEFAULT_SHARED for predefined variables. c/ * c-parser.c (c_parser_predefined_identifier): New function. (c_parser_postfix_expression): Use it. (c_parser_omp_variable_list): Parse predefined identifiers. * c-typeck.c (c_finish_omp_clauses): Allow predefined variables in shared and firstprivate clauses, even when they are predetermined shared. cp/ * parser.c (cp_parser_omp_var_list_no_open): Parse predefined variables. * semantics.c (finish_omp_clauses): Allow predefined variables in shared and firstprivate clauses, even when they are predetermined shared. * cp-gimplify.c (cxx_omp_predetermined_sharing_1): Return OMP_CLAUSE_DEFAULT_SHARED for predefined variables. testsuite/ * c-c++-common/gomp/pr88203-1.c: New test. * c-c++-common/gomp/pr88203-2.c: New test. * c-c++-common/gomp/pr88203-3.c: New test. From-SVN: r276212 --- gcc/c-family/ChangeLog | 8 +++ gcc/c-family/c-common.h | 1 + gcc/c-family/c-omp.c | 22 ++++++ gcc/c/ChangeLog | 10 +++ gcc/c/c-parser.c | 104 ++++++++++++++++++---------- gcc/c/c-typeck.c | 7 ++ gcc/cp/ChangeLog | 11 +++ gcc/cp/cp-gimplify.c | 3 + gcc/cp/parser.c | 8 +++ gcc/cp/semantics.c | 7 ++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/c-c++-common/gomp/pr88203-1.c | 61 ++++++++++++++++ gcc/testsuite/c-c++-common/gomp/pr88203-2.c | 65 +++++++++++++++++ gcc/testsuite/c-c++-common/gomp/pr88203-3.c | 28 ++++++++ 14 files changed, 302 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/gomp/pr88203-1.c create mode 100644 gcc/testsuite/c-c++-common/gomp/pr88203-2.c create mode 100644 gcc/testsuite/c-c++-common/gomp/pr88203-3.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 7b10957..9334ed5 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2019-09-27 Jakub Jelinek + + PR c++/88203 + * c-common.h (c_omp_predefined_variable): Declare. + * c-omp.c (c_omp_predefined_variable): New function. + (c_omp_predetermined_sharing): Return OMP_CLAUSE_DEFAULT_SHARED + for predefined variables. + 2019-09-27 Richard Sandiford * c-common.h (build_function_call_vec): Take the original diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index c1554f3..1e13aaa 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1187,6 +1187,7 @@ extern void c_omp_split_clauses (location_t, enum tree_code, omp_clause_mask, tree, tree *); extern tree c_omp_declare_simd_clauses_to_numbers (tree, tree); extern void c_omp_declare_simd_clauses_to_decls (tree, tree); +extern bool c_omp_predefined_variable (tree); extern enum omp_clause_default_kind c_omp_predetermined_sharing (tree); /* Return next tree in the chain for chain_next walking of tree nodes. */ diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c index 10f7c4e..0048289 100644 --- a/gcc/c-family/c-omp.c +++ b/gcc/c-family/c-omp.c @@ -2083,6 +2083,25 @@ c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses) } } +/* Return true for __func__ and similar function-local predefined + variables (which are in OpenMP predetermined shared, allowed in + shared/firstprivate clauses). */ + +bool +c_omp_predefined_variable (tree decl) +{ + if (VAR_P (decl) + && DECL_ARTIFICIAL (decl) + && TREE_READONLY (decl) + && TREE_STATIC (decl) + && DECL_NAME (decl) + && (DECL_NAME (decl) == ridpointers[RID_C99_FUNCTION_NAME] + || DECL_NAME (decl) == ridpointers[RID_FUNCTION_NAME] + || DECL_NAME (decl) == ridpointers[RID_PRETTY_FUNCTION_NAME])) + return true; + return false; +} + /* True if OpenMP sharing attribute of DECL is predetermined. */ enum omp_clause_default_kind @@ -2096,5 +2115,8 @@ c_omp_predetermined_sharing (tree decl) && INTEGRAL_TYPE_P (TREE_TYPE (decl))) return OMP_CLAUSE_DEFAULT_SHARED; + if (c_omp_predefined_variable (decl)) + return OMP_CLAUSE_DEFAULT_SHARED; + return OMP_CLAUSE_DEFAULT_UNSPECIFIED; } diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 718e5b8..fa0bbc8 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,13 @@ +2019-09-27 Jakub Jelinek + + PR c++/88203 + * c-parser.c (c_parser_predefined_identifier): New function. + (c_parser_postfix_expression): Use it. + (c_parser_omp_variable_list): Parse predefined identifiers. + * c-typeck.c (c_finish_omp_clauses): Allow predefined variables + in shared and firstprivate clauses, even when they are predetermined + shared. + 2019-09-27 Richard Sandiford * c-typeck.c (build_function_call_vec): Take the original function diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 6070502..c8afab2 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -8049,6 +8049,41 @@ enum tgmath_parm_kind tgmath_fixed, tgmath_real, tgmath_complex }; +/* Helper function for c_parser_postfix_expression. Parse predefined + identifiers. */ + +static struct c_expr +c_parser_predefined_identifier (c_parser *parser) +{ + location_t loc = c_parser_peek_token (parser)->location; + switch (c_parser_peek_token (parser)->keyword) + { + case RID_FUNCTION_NAME: + pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined " + "identifier", "__FUNCTION__"); + break; + case RID_PRETTY_FUNCTION_NAME: + pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined " + "identifier", "__PRETTY_FUNCTION__"); + break; + case RID_C99_FUNCTION_NAME: + pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support " + "%<__func__%> predefined identifier"); + break; + default: + gcc_unreachable (); + } + + struct c_expr expr; + expr.original_code = ERROR_MARK; + expr.original_type = NULL; + expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword, + c_parser_peek_token (parser)->value); + set_c_expr_source_range (&expr, loc, loc); + c_parser_consume_token (parser); + return expr; +} + /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2, C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to call c_parser_postfix_expression_after_paren_type on encountering them. @@ -8269,31 +8304,9 @@ c_parser_postfix_expression (c_parser *parser) switch (c_parser_peek_token (parser)->keyword) { case RID_FUNCTION_NAME: - pedwarn (loc, OPT_Wpedantic, "ISO C does not support " - "%<__FUNCTION__%> predefined identifier"); - expr.value = fname_decl (loc, - c_parser_peek_token (parser)->keyword, - c_parser_peek_token (parser)->value); - set_c_expr_source_range (&expr, loc, loc); - c_parser_consume_token (parser); - break; case RID_PRETTY_FUNCTION_NAME: - pedwarn (loc, OPT_Wpedantic, "ISO C does not support " - "%<__PRETTY_FUNCTION__%> predefined identifier"); - expr.value = fname_decl (loc, - c_parser_peek_token (parser)->keyword, - c_parser_peek_token (parser)->value); - set_c_expr_source_range (&expr, loc, loc); - c_parser_consume_token (parser); - break; case RID_C99_FUNCTION_NAME: - pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support " - "%<__func__%> predefined identifier"); - expr.value = fname_decl (loc, - c_parser_peek_token (parser)->keyword, - c_parser_peek_token (parser)->value); - set_c_expr_source_range (&expr, loc, loc); - c_parser_consume_token (parser); + expr = c_parser_predefined_identifier (parser); break; case RID_VA_ARG: { @@ -11997,15 +12010,9 @@ c_parser_omp_variable_list (c_parser *parser, { auto_vec tokens; unsigned int tokens_avail = 0; + bool first = true; - if (kind != OMP_CLAUSE_DEPEND - && (c_parser_next_token_is_not (parser, CPP_NAME) - || c_parser_peek_token (parser)->id_kind != C_ID_ID)) - c_parser_error (parser, "expected identifier"); - - while (kind == OMP_CLAUSE_DEPEND - || (c_parser_next_token_is (parser, CPP_NAME) - && c_parser_peek_token (parser)->id_kind == C_ID_ID)) + while (1) { bool array_section_p = false; if (kind == OMP_CLAUSE_DEPEND) @@ -12026,6 +12033,7 @@ c_parser_omp_variable_list (c_parser *parser, break; c_parser_consume_token (parser); + first = false; continue; } @@ -12076,16 +12084,35 @@ c_parser_omp_variable_list (c_parser *parser, parser->tokens_avail = tokens.length (); } - tree t = lookup_name (c_parser_peek_token (parser)->value); + tree t = NULL_TREE; - if (t == NULL_TREE) + if (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_token (parser)->id_kind == C_ID_ID) { - undeclared_variable (c_parser_peek_token (parser)->location, - c_parser_peek_token (parser)->value); - t = error_mark_node; - } + t = lookup_name (c_parser_peek_token (parser)->value); - c_parser_consume_token (parser); + if (t == NULL_TREE) + { + undeclared_variable (c_parser_peek_token (parser)->location, + c_parser_peek_token (parser)->value); + t = error_mark_node; + } + + c_parser_consume_token (parser); + } + else if (c_parser_next_token_is (parser, CPP_KEYWORD) + && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME + || (c_parser_peek_token (parser)->keyword + == RID_PRETTY_FUNCTION_NAME) + || (c_parser_peek_token (parser)->keyword + == RID_C99_FUNCTION_NAME))) + t = c_parser_predefined_identifier (parser).value; + else + { + if (first) + c_parser_error (parser, "expected identifier"); + break; + } if (t == error_mark_node) ; @@ -12223,6 +12250,7 @@ c_parser_omp_variable_list (c_parser *parser, break; c_parser_consume_token (parser); + first = false; } return list; diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index cc13fdc..c733950 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -14822,6 +14822,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) case OMP_CLAUSE_DEFAULT_UNSPECIFIED: break; case OMP_CLAUSE_DEFAULT_SHARED: + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE) + && c_omp_predefined_variable (t)) + /* The __func__ variable and similar function-local + predefined variables may be listed in a shared or + firstprivate clause. */ + break; share_name = "shared"; break; case OMP_CLAUSE_DEFAULT_PRIVATE: diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 20f543e..8ea2a84 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2019-09-27 Jakub Jelinek + + PR c++/88203 + * parser.c (cp_parser_omp_var_list_no_open): Parse predefined + variables. + * semantics.c (finish_omp_clauses): Allow predefined variables in + shared and firstprivate clauses, even when they are predetermined + shared. + * cp-gimplify.c (cxx_omp_predetermined_sharing_1): Return + OMP_CLAUSE_DEFAULT_SHARED for predefined variables. + 2019-09-27 Jason Merrill * constexpr.c (cxx_fold_indirect_ref): Use similar_type_p. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 49fa47a..8bda736 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -2055,6 +2055,9 @@ cxx_omp_predetermined_sharing_1 (tree decl) tree ctx = CP_DECL_CONTEXT (decl); if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx)) return OMP_CLAUSE_DEFAULT_SHARED; + + if (c_omp_predefined_variable (decl)) + return OMP_CLAUSE_DEFAULT_SHARED; } /* this may not be specified in data-sharing clauses, still we need diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 44082f7..018a03d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -32736,6 +32736,14 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, decl = TREE_OPERAND (decl, 0); cp_lexer_consume_token (parser->lexer); } + else if (cp_parser_is_keyword (token, RID_FUNCTION_NAME) + || cp_parser_is_keyword (token, RID_PRETTY_FUNCTION_NAME) + || cp_parser_is_keyword (token, RID_C99_FUNCTION_NAME)) + { + cp_id_kind idk; + decl = cp_parser_primary_expression (parser, false, false, false, + &idk); + } else { name = cp_parser_id_expression (parser, /*template_p=*/false, diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 7563248..5a8c4d2 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -7967,6 +7967,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) case OMP_CLAUSE_DEFAULT_UNSPECIFIED: break; case OMP_CLAUSE_DEFAULT_SHARED: + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE) + && c_omp_predefined_variable (t)) + /* The __func__ variable and similar function-local predefined + variables may be listed in a shared or firstprivate + clause. */ + break; if (VAR_P (t) && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE && TREE_STATIC (t) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9aee20c..163e38d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2019-09-27 Jakub Jelinek + PR c++/88203 + * c-c++-common/gomp/pr88203-1.c: New test. + * c-c++-common/gomp/pr88203-2.c: New test. + * c-c++-common/gomp/pr88203-3.c: New test. + PR middle-end/91920 * c-c++-common/gomp/pr91920.c: New test. diff --git a/gcc/testsuite/c-c++-common/gomp/pr88203-1.c b/gcc/testsuite/c-c++-common/gomp/pr88203-1.c new file mode 100644 index 0000000..54a6864 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr88203-1.c @@ -0,0 +1,61 @@ +/* PR c++/88203 */ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99" { target c } } */ +/* { dg-additional-options "-std=c++11" { target c++ } } */ + +void foo (const char *); +#pragma omp declare target to (foo) + +void +f1 (void) +{ + #pragma omp parallel default(none) + foo (__func__); +} + +void +f2 (void) +{ + #pragma omp parallel default(none) shared(__func__) + foo (__func__); +} + +void +f3 (void) +{ + #pragma omp parallel default(none) firstprivate(__func__) + foo (__func__); +} + +void +f4 (void) +{ + foo (__func__); + #pragma omp parallel default(none) + foo (__func__); +} + +void +f5 (void) +{ + foo (__func__); + #pragma omp parallel default(none) shared(__func__) + foo (__func__); +} + +void +f6 (void) +{ + foo (__func__); + #pragma omp parallel default(none) firstprivate(__func__) + foo (__func__); +} + +void +f7 (void) +{ + #pragma omp target map(to: __func__) + foo (__func__); + #pragma omp task depend(inout:__func__) + foo (__func__); +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr88203-2.c b/gcc/testsuite/c-c++-common/gomp/pr88203-2.c new file mode 100644 index 0000000..90c4a72 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr88203-2.c @@ -0,0 +1,65 @@ +/* PR c++/88203 */ +/* { dg-do compile } */ +/* { dg-additional-options "-std=gnu99" { target c } } */ +/* { dg-additional-options "-std=gnu++11" { target c++ } } */ + +void foo (const char *, const char *); +#pragma omp declare target to (foo) + +void +f1 (void) +{ + #pragma omp parallel default(none) + foo (__FUNCTION__, __PRETTY_FUNCTION__); +} + +void +f2 (void) +{ + #pragma omp parallel default(none) shared(__FUNCTION__, __PRETTY_FUNCTION__) + foo (__FUNCTION__, __PRETTY_FUNCTION__); + #pragma omp parallel default(none) shared(__FUNCTION__) firstprivate(__PRETTY_FUNCTION__) + foo (__FUNCTION__, __PRETTY_FUNCTION__); +} + +void +f3 (void) +{ + #pragma omp parallel default(none) firstprivate(__FUNCTION__, __PRETTY_FUNCTION__) + foo (__FUNCTION__, __PRETTY_FUNCTION__); + #pragma omp parallel default(none) firstprivate(__FUNCTION__), shared(__PRETTY_FUNCTION__) + foo (__FUNCTION__, __PRETTY_FUNCTION__); +} + +void +f4 (void) +{ + foo (__FUNCTION__, __PRETTY_FUNCTION__); + #pragma omp parallel default(none) + foo (__FUNCTION__, __PRETTY_FUNCTION__); +} + +void +f5 (void) +{ + foo (__FUNCTION__, __PRETTY_FUNCTION__); + #pragma omp parallel default(none) shared(__FUNCTION__, __PRETTY_FUNCTION__) + foo (__FUNCTION__, __PRETTY_FUNCTION__); +} + +void +f6 (void) +{ + foo (__FUNCTION__, __PRETTY_FUNCTION__); + #pragma omp parallel default(none) firstprivate(__FUNCTION__, __PRETTY_FUNCTION__) + foo (__FUNCTION__, __PRETTY_FUNCTION__); +} + +void +f7 (void) +{ + #pragma omp target map(to: __FUNCTION__, __PRETTY_FUNCTION__) + foo (__FUNCTION__, __PRETTY_FUNCTION__); + #pragma omp task depend(inout:__FUNCTION__, __PRETTY_FUNCTION__) + foo (__FUNCTION__, __PRETTY_FUNCTION__); +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr88203-3.c b/gcc/testsuite/c-c++-common/gomp/pr88203-3.c new file mode 100644 index 0000000..6a9585d --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr88203-3.c @@ -0,0 +1,28 @@ +/* PR c++/88203 */ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99" { target c } } */ +/* { dg-additional-options "-std=c++11" { target c++ } } */ + +void foo (const char *); +#pragma omp declare target to (foo) + +void +f1 (void) +{ + #pragma omp parallel for lastprivate (__func__) /* { dg-error "'__func__' is predetermined 'shared' for 'lastprivate'" } */ + for (int i = 0; i < 2; i++) + foo (__func__); + #pragma omp parallel private (__func__) /* { dg-error "'__func__' is predetermined 'shared' for 'private'" } */ + foo (__func__); +} + +void +f2 (void) +{ + foo (__func__); + #pragma omp parallel default(none) private (__func__) /* { dg-error "'__func__' is predetermined 'shared' for 'private'" } */ + foo (__func__); + #pragma omp parallel for default(none) lastprivate (__func__) /* { dg-error "'__func__' is predetermined 'shared' for 'lastprivate'" } */ + for (int i = 0; i < 2; i++) + foo (__func__); +} -- 2.7.4