From: Marek Polacek <polacek@redhat.com>
To: Jakub Jelinek <jakub@redhat.com>
Cc: "Joseph S. Myers" <joseph@codesourcery.com>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c: Improve build_component_ref diagnostics [PR91134]
Date: Tue, 24 May 2022 09:43:54 -0400 [thread overview]
Message-ID: <YozhGuoPJTZo1Q8v@redhat.com> (raw)
In-Reply-To: <YoyIhfJbdPn9PgHH@tucnak>
On Tue, May 24, 2022 at 09:25:57AM +0200, Jakub Jelinek wrote:
> Hi!
>
> On the following testcase (the first dg-error line) we emit a weird
> diagnostics and even fixit on pointerpointer->member
> where pointerpointer is pointer to pointer to struct and we say
> 'pointerpointer' is a pointer; did you mean to use '->'?
> The first part is indeed true, but suggesting -> when the code already
> does use -> is confusing.
> The following patch adjusts callers so that they tell it if it is from
> . parsing or from -> parsing and in the latter case suggests to dereference
> the left operand instead by adding (* before it and ) after it (before ->).
> Or would a suggestion to add [0] before -> be better?
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2022-05-24 Jakub Jelinek <jakub@redhat.com>
>
> PR c/91134
> gcc/c/
> * c-tree.h (build_component_ref): Add ARROW_LOC location_t argument.
> * c-typeck.cc (build_component_ref): Likewise. If DATUM is
> INDIRECT_REF and ARROW_LOC isn't UNKNOWN_LOCATION, print a different
> diagnostics and fixit hint if DATUM has pointer type.
s/diagnostic/, missing "than" before if?
> * c-parser.cc (c_parser_postfix_expression,
> c_parser_omp_variable_list): Adjust build_component_ref callers.
> * gimple-parser.cc (c_parser_gimple_postfix_expression_after_primary):
> Likewise.
> gcc/objc/
> * objc-act.cc (objc_build_component_ref): Adjust build_component_ref
> caller.
> gcc/testsuite/
> * gcc.dg/pr91134.c: New test.
>
> --- gcc/c/c-tree.h.jj 2022-05-19 11:48:56.058291437 +0200
> +++ gcc/c/c-tree.h 2022-05-23 20:22:05.669515990 +0200
> @@ -699,7 +699,8 @@ extern struct c_expr convert_lvalue_to_r
> extern tree decl_constant_value_1 (tree, bool);
> extern void mark_exp_read (tree);
> extern tree composite_type (tree, tree);
> -extern tree build_component_ref (location_t, tree, tree, location_t);
> +extern tree build_component_ref (location_t, tree, tree, location_t,
> + location_t);
> extern tree build_array_ref (location_t, tree, tree);
> extern tree build_external_ref (location_t, tree, bool, tree *);
> extern void pop_maybe_used (bool);
> --- gcc/c/c-typeck.cc.jj 2022-05-19 11:48:56.077291176 +0200
> +++ gcc/c/c-typeck.cc 2022-05-23 20:23:44.713515875 +0200
> @@ -2457,11 +2457,12 @@ should_suggest_deref_p (tree datum_type)
> /* Make an expression to refer to the COMPONENT field of structure or
> union value DATUM. COMPONENT is an IDENTIFIER_NODE. LOC is the
> location of the COMPONENT_REF. COMPONENT_LOC is the location
> - of COMPONENT. */
> + of COMPONENT. ARROW_LOC is the location of first -> operand if
"of the first"?
> + it is from -> operator. */
>
> tree
> build_component_ref (location_t loc, tree datum, tree component,
> - location_t component_loc)
> + location_t component_loc, location_t arrow_loc)
> {
> tree type = TREE_TYPE (datum);
> enum tree_code code = TREE_CODE (type);
> @@ -2577,11 +2578,23 @@ build_component_ref (location_t loc, tre
> /* Special-case the error message for "ptr.field" for the case
> where the user has confused "." vs "->". */
> rich_location richloc (line_table, loc);
> - /* "loc" should be the "." token. */
> - richloc.add_fixit_replace ("->");
> - error_at (&richloc,
> - "%qE is a pointer; did you mean to use %<->%>?",
> - datum);
> + if (TREE_CODE (datum) == INDIRECT_REF && arrow_loc != UNKNOWN_LOCATION)
> + {
> + richloc.add_fixit_insert_before (arrow_loc, "(*");
> + richloc.add_fixit_insert_after (arrow_loc, ")");
> + error_at (&richloc,
> + "%qE is a pointer to pointer; did you mean to dereference "
> + "it before applying %<->%> to it?",
> + TREE_OPERAND (datum, 0));
> + }
> + else
> + {
> + /* "loc" should be the "." token. */
> + richloc.add_fixit_replace ("->");
> + error_at (&richloc,
> + "%qE is a pointer; did you mean to use %<->%>?",
> + datum);
> + }
> return error_mark_node;
> }
> else if (code != ERROR_MARK)
> --- gcc/c/c-parser.cc.jj 2022-05-23 16:16:30.360856580 +0200
> +++ gcc/c/c-parser.cc 2022-05-23 20:33:36.683537409 +0200
> @@ -9235,8 +9235,9 @@ c_parser_postfix_expression (c_parser *p
> if (c_parser_next_token_is (parser, CPP_NAME))
> {
> c_token *comp_tok = c_parser_peek_token (parser);
> - offsetof_ref = build_component_ref
> - (loc, offsetof_ref, comp_tok->value, comp_tok->location);
> + offsetof_ref
> + = build_component_ref (loc, offsetof_ref, comp_tok->value,
> + comp_tok->location, UNKNOWN_LOCATION);
> c_parser_consume_token (parser);
> while (c_parser_next_token_is (parser, CPP_DOT)
> || c_parser_next_token_is (parser,
> @@ -9263,9 +9264,11 @@ c_parser_postfix_expression (c_parser *p
> break;
> }
> c_token *comp_tok = c_parser_peek_token (parser);
> - offsetof_ref = build_component_ref
> - (loc, offsetof_ref, comp_tok->value,
> - comp_tok->location);
> + offsetof_ref
> + = build_component_ref (loc, offsetof_ref,
> + comp_tok->value,
> + comp_tok->location,
> + UNKNOWN_LOCATION);
> c_parser_consume_token (parser);
> }
> else
> @@ -10612,7 +10615,7 @@ c_parser_postfix_expression_after_primar
> finish = c_parser_peek_token (parser)->get_finish ();
> c_parser_consume_token (parser);
> expr.value = build_component_ref (op_loc, expr.value, ident,
> - comp_loc);
> + comp_loc, UNKNOWN_LOCATION);
> set_c_expr_source_range (&expr, start, finish);
> expr.original_code = ERROR_MARK;
> if (TREE_CODE (expr.value) != COMPONENT_REF)
> @@ -10652,7 +10655,8 @@ c_parser_postfix_expression_after_primar
> build_indirect_ref (op_loc,
> expr.value,
> RO_ARROW),
> - ident, comp_loc);
> + ident, comp_loc,
> + expr.get_location ());
> set_c_expr_source_range (&expr, start, finish);
> expr.original_code = ERROR_MARK;
> if (TREE_CODE (expr.value) != COMPONENT_REF)
> @@ -13171,6 +13175,7 @@ c_parser_omp_variable_list (c_parser *pa
> && c_parser_next_token_is (parser, CPP_DEREF)))
> {
> location_t op_loc = c_parser_peek_token (parser)->location;
> + location_t arrow_loc = UNKNOWN_LOCATION;
> if (c_parser_next_token_is (parser, CPP_DEREF))
> {
> c_expr t_expr;
> @@ -13181,6 +13186,7 @@ c_parser_omp_variable_list (c_parser *pa
> t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
> true, false);
> t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
> + arrow_loc = t_expr.get_location ();
> }
> c_parser_consume_token (parser);
> if (!c_parser_next_token_is (parser, CPP_NAME))
> @@ -13194,7 +13200,8 @@ c_parser_omp_variable_list (c_parser *pa
> tree ident = comp_tok->value;
> location_t comp_loc = comp_tok->location;
> c_parser_consume_token (parser);
> - t = build_component_ref (op_loc, t, ident, comp_loc);
> + t = build_component_ref (op_loc, t, ident, comp_loc,
> + arrow_loc);
> }
> /* FALLTHROUGH */
> case OMP_CLAUSE_AFFINITY:
> --- gcc/c/gimple-parser.cc.jj 2022-02-24 15:27:14.718744040 +0100
> +++ gcc/c/gimple-parser.cc 2022-05-23 20:27:34.538195175 +0200
> @@ -1800,7 +1800,7 @@ c_parser_gimple_postfix_expression_after
> finish = c_parser_peek_token (parser)->get_finish ();
> c_parser_consume_token (parser);
> expr.value = build_component_ref (op_loc, expr.value, ident,
> - comp_loc);
> + comp_loc, UNKNOWN_LOCATION);
> set_c_expr_source_range (&expr, start, finish);
> expr.original_code = ERROR_MARK;
> if (TREE_CODE (expr.value) != COMPONENT_REF)
> @@ -1848,7 +1848,8 @@ c_parser_gimple_postfix_expression_after
> expr.value = build_component_ref (op_loc,
> build_simple_mem_ref_loc
> (op_loc, expr.value),
> - ident, comp_loc);
> + ident, comp_loc,
> + expr.get_location ());
> set_c_expr_source_range (&expr, start, finish);
> expr.original_code = ERROR_MARK;
> if (TREE_CODE (expr.value) != COMPONENT_REF)
> --- gcc/objc/objc-act.cc.jj 2022-01-18 00:18:02.827743339 +0100
> +++ gcc/objc/objc-act.cc 2022-05-23 23:59:48.134923529 +0200
> @@ -2812,7 +2812,7 @@ objc_build_component_ref (tree datum, tr
> tf_warning_or_error);
> #else
> return build_component_ref (input_location, datum, component,
> - UNKNOWN_LOCATION);
> + UNKNOWN_LOCATION, UNKNOWN_LOCATION);
> #endif
> }
>
> --- gcc/testsuite/gcc.dg/pr91134.c.jj 2022-05-23 20:31:11.751001817 +0200
> +++ gcc/testsuite/gcc.dg/pr91134.c 2022-05-23 20:30:45.291268997 +0200
> @@ -0,0 +1,13 @@
> +/* PR c/91134 */
> +
> +struct X { int member; } x;
> +
> +int
> +foo (void)
> +{
> + struct X *pointer = &x;
> + struct X **pointerpointer = &pointer;
> + int i = *pointerpointer->member; /* { dg-error "'pointerpointer' is a pointer to pointer; did you mean to dereference it before applying '->' to it\\\?" } */
> + int j = pointer.member; /* { dg-error "'pointer' is a pointer; did you mean to use '->'\\\?" } */
> + return i + j;
> +}
Consider extending the test like
--- pr91134.c 2022-05-24 09:33:17.807520253 -0400
+++ pr911342.c 2022-05-24 09:36:09.908217139 -0400
@@ -1,13 +1,16 @@
/* PR c/91134 */
struct X { int member; } x;
+struct Y { struct X **x; } y;
int
foo (void)
{
struct X *pointer = &x;
+ struct Y *yp = &y;
struct X **pointerpointer = &pointer;
int i = *pointerpointer->member; /* { dg-error "'pointerpointer' is a pointer to pointer; did you mean to dereference it before applying '->' to it\\\?" } */
int j = pointer.member; /* { dg-error "'pointer' is a pointer; did you mean to use '->'\\\?" } */
- return i + j;
+ int k = yp->x->member; // dg-error
+ return i + j + k;
}
but I think the patch is OK, thanks.
Marek
next prev parent reply other threads:[~2022-05-24 13:43 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-24 7:25 Jakub Jelinek
2022-05-24 13:43 ` Marek Polacek [this message]
2022-05-25 12:24 ` Jakub Jelinek
2022-05-24 13:57 ` David Malcolm
2022-05-24 13:59 ` David Malcolm
2022-05-25 12:28 ` Jakub Jelinek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YozhGuoPJTZo1Q8v@redhat.com \
--to=polacek@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
--cc=joseph@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).