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
This commit is contained in:
parent
00798c5843
commit
59bc434a33
|
@ -1,3 +1,11 @@
|
|||
2019-09-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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 <richard.sandiford@arm.com>
|
||||
|
||||
* c-common.h (build_function_call_vec): Take the original
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2019-09-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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 <richard.sandiford@arm.com>
|
||||
|
||||
* c-typeck.c (build_function_call_vec): Take the original function
|
||||
|
|
104
gcc/c/c-parser.c
104
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<c_token> 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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
2019-09-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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 <jason@redhat.com>
|
||||
|
||||
* constexpr.c (cxx_fold_indirect_ref): Use similar_type_p.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
2019-09-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -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__);
|
||||
}
|
|
@ -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__);
|
||||
}
|
|
@ -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__);
|
||||
}
|
Loading…
Reference in New Issue