OpenMP/C: Store location in cp_parser_omp_var_list for kind=0 [PR118579]
This patch is the C equivalent of commit r15-6512-gcf94ba812ca496 for C++, to improve the location information for individual items in an OpenMP variable list. gcc/c/ChangeLog PR c/118579 * c-parser.cc (c_parser_omp_variable_list): Capture location information when KIND is OMP_CLAUSE_ERROR. (c_parser_oacc_data_clause_deviceptr): Use the improved location for diagnostics, and remove the FIXME. (c_finish_omp_declare_variant): Likewise. (c_parser_omp_threadprivate): Likewise. gcc/testsuite/ChangeLog PR c/118579 * c-c++-common/gomp/pr118579.c: New testcase.
This commit is contained in:
parent
f695d0392f
commit
f74ed83e28
2 changed files with 39 additions and 22 deletions
|
@ -16282,8 +16282,9 @@ c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
|
|||
decl in OMP_CLAUSE_DECL and add the node to the head of the list.
|
||||
If KIND is nonzero, CLAUSE_LOC is the location of the clause.
|
||||
|
||||
If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
|
||||
return the list created.
|
||||
If KIND is zero (= OMP_CLAUSE_ERROR), create a TREE_LIST with the decl
|
||||
in TREE_PURPOSE and the location in TREE_VALUE (accessible using
|
||||
EXPR_LOCATION); return the list created.
|
||||
|
||||
The optional ALLOW_DEREF argument is true if list items can use the deref
|
||||
(->) operator. */
|
||||
|
@ -16312,6 +16313,7 @@ c_parser_omp_variable_list (c_parser *parser,
|
|||
while (1)
|
||||
{
|
||||
tree t = NULL_TREE;
|
||||
location_t tloc = c_parser_peek_token (parser)->location;
|
||||
|
||||
if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
|
||||
{
|
||||
|
@ -16512,7 +16514,7 @@ c_parser_omp_variable_list (c_parser *parser,
|
|||
|
||||
if (t == error_mark_node)
|
||||
;
|
||||
else if (kind != 0)
|
||||
else if (kind != 0) /* kind != OMP_CLAUSE_ERROR */
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
|
@ -16686,8 +16688,8 @@ c_parser_omp_variable_list (c_parser *parser,
|
|||
list = u;
|
||||
}
|
||||
}
|
||||
else
|
||||
list = tree_cons (t, NULL_TREE, list);
|
||||
else /* kind == OMP_CLAUSE_ERROR */
|
||||
list = tree_cons (t, build_empty_stmt (tloc), list);
|
||||
|
||||
if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
|
||||
{
|
||||
|
@ -16847,7 +16849,6 @@ c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
|
|||
static tree
|
||||
c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
|
||||
{
|
||||
location_t loc = c_parser_peek_token (parser)->location;
|
||||
tree vars, t;
|
||||
|
||||
/* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
|
||||
|
@ -16857,12 +16858,7 @@ c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
|
|||
for (t = vars; t && t; t = TREE_CHAIN (t))
|
||||
{
|
||||
tree v = TREE_PURPOSE (t);
|
||||
|
||||
/* FIXME diagnostics: Ideally we should keep individual
|
||||
locations for all the variables in the var list to make the
|
||||
following errors more precise. Perhaps
|
||||
c_parser_omp_var_list_parens() should construct a list of
|
||||
locations to go along with the var list. */
|
||||
location_t loc = EXPR_LOCATION (TREE_VALUE (t));
|
||||
|
||||
if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
|
||||
error_at (loc, "%qD is not a variable", v);
|
||||
|
@ -27031,6 +27027,7 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
|
|||
for (tree c = list; c != NULL_TREE; c = TREE_CHAIN (c))
|
||||
{
|
||||
tree decl = TREE_PURPOSE (c);
|
||||
location_t arg_loc = EXPR_LOCATION (TREE_VALUE (c));
|
||||
int idx;
|
||||
for (arg = parms, idx = 0; arg != NULL;
|
||||
arg = TREE_CHAIN (arg), idx++)
|
||||
|
@ -27038,14 +27035,15 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
|
|||
break;
|
||||
if (arg == NULL_TREE)
|
||||
{
|
||||
error_at (loc, "%qD is not a function argument",
|
||||
error_at (arg_loc,
|
||||
"%qD is not a function argument",
|
||||
decl);
|
||||
goto fail;
|
||||
}
|
||||
if (adjust_args_list.contains (arg))
|
||||
{
|
||||
// TODO fix location
|
||||
error_at (loc, "%qD is specified more than once",
|
||||
error_at (arg_loc,
|
||||
"%qD is specified more than once",
|
||||
decl);
|
||||
goto fail;
|
||||
}
|
||||
|
@ -29495,19 +29493,13 @@ c_parser_omp_threadprivate (c_parser *parser)
|
|||
location_t loc;
|
||||
|
||||
c_parser_consume_pragma (parser);
|
||||
loc = c_parser_peek_token (parser)->location;
|
||||
vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
|
||||
|
||||
/* Mark every variable in VARS to be assigned thread local storage. */
|
||||
for (t = vars; t; t = TREE_CHAIN (t))
|
||||
{
|
||||
tree v = TREE_PURPOSE (t);
|
||||
|
||||
/* FIXME diagnostics: Ideally we should keep individual
|
||||
locations for all the variables in the var list to make the
|
||||
following errors more precise. Perhaps
|
||||
c_parser_omp_var_list_parens() should construct a list of
|
||||
locations to go along with the var list. */
|
||||
loc = EXPR_LOCATION (TREE_VALUE (t));
|
||||
|
||||
/* If V had already been marked threadprivate, it doesn't matter
|
||||
whether it had been used prior to this point. */
|
||||
|
|
25
gcc/testsuite/c-c++-common/gomp/pr118579.c
Normal file
25
gcc/testsuite/c-c++-common/gomp/pr118579.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
/* Make sure errors in variable-lists are diagnosed in the right place. */
|
||||
|
||||
void fvar(int *, int *);
|
||||
#pragma omp declare variant(fvar) \
|
||||
match(construct={dispatch}) \
|
||||
adjust_args(need_device_ptr: yyy, xxx, xxx)
|
||||
/* { dg-error "37: .xxx. is specified more than once" "" { target *-*-* } .-1 } */
|
||||
void f(int *xxx, int*yyy);
|
||||
|
||||
|
||||
extern void frobnicate (int);
|
||||
void g (int x, int y)
|
||||
{
|
||||
int l = x + y;
|
||||
static int s = 42;
|
||||
frobnicate (s);
|
||||
#pragma omp threadprivate (l, s)
|
||||
/* { dg-error "28: automatic variable .l. cannot be .threadprivate." "" { target *-*-* } .-1 } */
|
||||
/* { dg-error "31: .s. declared .threadprivate. after first use" "" { target *-*-* } .-2 } */
|
||||
{
|
||||
f (&l, &s);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue