https://gcc.gnu.org/g:cf94ba812ca49608decbd1e28296f1b618c9c7d9
commit r15-6512-gcf94ba812ca49608decbd1e28296f1b618c9c7d9 Author: Tobias Burnus <tbur...@baylibre.com> Date: Fri Jan 3 10:12:32 2025 +0100 OpenMP/C++: Store location in cp_parser_omp_var_list for kind=0 cp_parser_omp_var_list and cp_parser_omp_var_list_no_open have a special modus: kind = 0 alias kind = OMP_CLAUSE_ERROR, which returns a simple tree list; however, for a decl, no location is associated with that variable, yielding to confusing error locations. With this patch, also for kind=0, a reasonable error location is stored, albeit with creating a tree node (build_empty_stmt), which is otherwise not used. gcc/cp/ChangeLog: * parser.cc (cp_parser_omp_var_list_no_open, cp_parser_omp_var_list): For kind=0 (= OMP_CLAUSE_ERROR), store also the expression location in the tree list. (cp_parser_oacc_data_clause_deviceptr, cp_finish_omp_declare_variant): Use that location instead or input_location/the before-parsing location. * semantics.cc (finish_omp_threadprivate): Likewise. Diff: --- gcc/cp/parser.cc | 27 +++++++++++++-------------- gcc/cp/semantics.cc | 15 ++++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index cd1d9b5f7151..f548dc31c2b8 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -38698,8 +38698,9 @@ check_no_duplicate_clause (tree clauses, enum omp_clause_code code, If KIND is nonzero, create the appropriate node and install the decl in OMP_CLAUSE_DECL and add the node to the head of the list. - 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. COLON can be NULL if only closing parenthesis should end the list, or pointer to bool which will receive false if the list is terminated @@ -38836,7 +38837,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, goto build_clause; } token = cp_lexer_peek_token (parser->lexer); - if (kind != 0 + if (kind != 0 /* kind != OMP_CLAUSE_ERROR */ && cp_parser_is_keyword (token, RID_THIS)) { decl = finish_this_expr (); @@ -38894,7 +38895,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, decl = process_outer_var_ref (decl, tf_warning_or_error); if (decl == error_mark_node) ; - else if (kind != 0) + else if (kind != 0) /* kind != OMP_CLAUSE_ERROR */ { switch (kind) { @@ -39040,8 +39041,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, OMP_CLAUSE_CHAIN (u) = list; list = u; } - else - list = tree_cons (decl, NULL_TREE, list); + else /* kind == 0 alias kind == OMP_CLAUSE_ERROR */ + list = tree_cons (decl, build_empty_stmt (token->location), list); get_comma: if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) @@ -39088,17 +39089,17 @@ cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list, { if (parser->lexer->in_omp_decl_attribute) { + location_t loc = cp_lexer_peek_token (parser->lexer)->location; if (kind) { - location_t loc = cp_lexer_peek_token (parser->lexer)->location; tree u = build_omp_clause (loc, kind); OMP_CLAUSE_DECL (u) = parser->lexer->in_omp_decl_attribute; OMP_CLAUSE_CHAIN (u) = list; return u; } - else - return tree_cons (parser->lexer->in_omp_decl_attribute, NULL_TREE, - list); + else /* kind == OMP_CLAUSE_ERROR */ + return tree_cons (parser->lexer->in_omp_decl_attribute, + build_empty_stmt (loc), list); } if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) @@ -39213,7 +39214,6 @@ cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind, static tree cp_parser_oacc_data_clause_deviceptr (cp_parser *parser, tree list) { - location_t loc = cp_lexer_peek_token (parser->lexer)->location; tree vars, t; /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic @@ -39223,6 +39223,7 @@ cp_parser_oacc_data_clause_deviceptr (cp_parser *parser, tree list) for (t = vars; t; t = TREE_CHAIN (t)) { tree v = TREE_PURPOSE (t); + location_t loc = EXPR_LOCATION (TREE_VALUE (t)); tree u = build_omp_clause (loc, OMP_CLAUSE_MAP); OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR); OMP_CLAUSE_DECL (u) = v; @@ -50229,8 +50230,6 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok, { cp_lexer_consume_token (parser->lexer); // need_device_ptr cp_lexer_consume_token (parser->lexer); // : - location_t arg_loc - = cp_lexer_peek_token (parser->lexer)->location; tree arg; tree list @@ -50240,6 +50239,7 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok, 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++) @@ -50254,7 +50254,6 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok, arg = TREE_VALUE (arg); if (adjust_args_list.contains (arg)) { - // TODO fix location error_at (arg_loc, "%qD is specified more than once", decl); continue; diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index e7ae9ce5ea43..15840e10620c 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -10196,26 +10196,27 @@ finish_omp_threadprivate (tree vars) for (t = vars; t; t = TREE_CHAIN (t)) { tree v = TREE_PURPOSE (t); + location_t loc = EXPR_LOCATION (TREE_VALUE (t)); if (error_operand_p (v)) ; else if (!VAR_P (v)) - error ("%<threadprivate%> %qD is not file, namespace " - "or block scope variable", v); + error_at (loc, "%<threadprivate%> %qD is not file, namespace " + "or block scope variable", v); /* If V had already been marked threadprivate, it doesn't matter whether it had been used prior to this point. */ else if (TREE_USED (v) && (DECL_LANG_SPECIFIC (v) == NULL || !CP_DECL_THREADPRIVATE_P (v))) - error ("%qE declared %<threadprivate%> after first use", v); + error_at (loc, "%qE declared %<threadprivate%> after first use", v); else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v)) - error ("automatic variable %qE cannot be %<threadprivate%>", v); + error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v); else if (! COMPLETE_TYPE_P (complete_type (TREE_TYPE (v)))) - error ("%<threadprivate%> %qE has incomplete type", v); + error_at (loc, "%<threadprivate%> %qE has incomplete type", v); else if (TREE_STATIC (v) && TYPE_P (CP_DECL_CONTEXT (v)) && CP_DECL_CONTEXT (v) != current_class_type) - error ("%<threadprivate%> %qE directive not " - "in %qT definition", v, CP_DECL_CONTEXT (v)); + error_at (loc, "%<threadprivate%> %qE directive not " + "in %qT definition", v, CP_DECL_CONTEXT (v)); else { /* Allocate a LANG_SPECIFIC structure for V, if needed. */