diff options
author | David Malcolm <dmalcolm@redhat.com> | 2016-06-07 15:04:22 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2016-06-07 15:04:22 +0000 |
commit | 6ffd47b70a4553b621a124ce2632cb2d39a8008f (patch) | |
tree | 71a730994243919c88c4e269b3d48b4000eb9529 | |
parent | 0f471dc3e81fee3d346c4887ce63688dc2735fdd (diff) | |
download | gcc-6ffd47b70a4553b621a124ce2632cb2d39a8008f.zip gcc-6ffd47b70a4553b621a124ce2632cb2d39a8008f.tar.gz gcc-6ffd47b70a4553b621a124ce2632cb2d39a8008f.tar.bz2 |
C: add fixit hint to misspelled field names
gcc/c/ChangeLog:
* c-parser.c (c_parser_postfix_expression): In __builtin_offsetof
and structure element reference, capture the location of the
element name token and pass it to build_component_ref.
(c_parser_postfix_expression_after_primary): Likewise for
structure element dereference.
(c_parser_omp_variable_list): Likewise for
OMP_CLAUSE_{_CACHE, MAP, FROM, TO},
* c-tree.h (build_component_ref): Add location_t param.
* c-typeck.c (build_component_ref): Add location_t param
COMPONENT_LOC. Use it, if available, when issuing hints about
mispelled member names to provide a fixit replacement hint.
gcc/objc/ChangeLog:
* objc-act.c (objc_build_component_ref): Update call
to build_component_ref for added param, passing UNKNOWN_LOCATION.
gcc/testsuite/ChangeLog:
* gcc.dg/spellcheck-fields-2.c: New test case.
From-SVN: r237176
-rw-r--r-- | gcc/c/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 34 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 2 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 26 | ||||
-rw-r--r-- | gcc/objc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/objc/objc-act.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/spellcheck-fields-2.c | 19 |
8 files changed, 91 insertions, 16 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 3b7feaa..de23e36 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,17 @@ +2016-06-07 David Malcolm <dmalcolm@redhat.com> + + * c-parser.c (c_parser_postfix_expression): In __builtin_offsetof + and structure element reference, capture the location of the + element name token and pass it to build_component_ref. + (c_parser_postfix_expression_after_primary): Likewise for + structure element dereference. + (c_parser_omp_variable_list): Likewise for + OMP_CLAUSE_{_CACHE, MAP, FROM, TO}, + * c-tree.h (build_component_ref): Add location_t param. + * c-typeck.c (build_component_ref): Add location_t param + COMPONENT_LOC. Use it, if available, when issuing hints about + mispelled member names to provide a fixit replacement hint. + 2016-06-06 Marek Polacek <polacek@redhat.com> PR c/71362 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 799a473..2fef1ac 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -7708,8 +7708,9 @@ c_parser_postfix_expression (c_parser *parser) accept sub structure and sub array references. */ 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, c_parser_peek_token (parser)->value); + (loc, offsetof_ref, comp_tok->value, comp_tok->location); c_parser_consume_token (parser); while (c_parser_next_token_is (parser, CPP_DOT) || c_parser_next_token_is (parser, @@ -7735,9 +7736,10 @@ c_parser_postfix_expression (c_parser *parser) c_parser_error (parser, "expected identifier"); break; } + c_token *comp_tok = c_parser_peek_token (parser); offsetof_ref = build_component_ref - (loc, offsetof_ref, - c_parser_peek_token (parser)->value); + (loc, offsetof_ref, comp_tok->value, + comp_tok->location); c_parser_consume_token (parser); } else @@ -8214,7 +8216,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, { struct c_expr orig_expr; tree ident, idx; - location_t sizeof_arg_loc[3]; + location_t sizeof_arg_loc[3], comp_loc; tree sizeof_arg[3]; unsigned int literal_zero_mask; unsigned int i; @@ -8328,7 +8330,11 @@ c_parser_postfix_expression_after_primary (c_parser *parser, c_parser_consume_token (parser); expr = default_function_array_conversion (expr_loc, expr); if (c_parser_next_token_is (parser, CPP_NAME)) - ident = c_parser_peek_token (parser)->value; + { + c_token *comp_tok = c_parser_peek_token (parser); + ident = comp_tok->value; + comp_loc = comp_tok->location; + } else { c_parser_error (parser, "expected identifier"); @@ -8340,7 +8346,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser, start = expr.get_start (); finish = c_parser_peek_token (parser)->get_finish (); c_parser_consume_token (parser); - expr.value = build_component_ref (op_loc, expr.value, ident); + expr.value = build_component_ref (op_loc, expr.value, ident, + comp_loc); set_c_expr_source_range (&expr, start, finish); expr.original_code = ERROR_MARK; if (TREE_CODE (expr.value) != COMPONENT_REF) @@ -8360,7 +8367,11 @@ c_parser_postfix_expression_after_primary (c_parser *parser, c_parser_consume_token (parser); expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false); if (c_parser_next_token_is (parser, CPP_NAME)) - ident = c_parser_peek_token (parser)->value; + { + c_token *comp_tok = c_parser_peek_token (parser); + ident = comp_tok->value; + comp_loc = comp_tok->location; + } else { c_parser_error (parser, "expected identifier"); @@ -8376,7 +8387,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, build_indirect_ref (op_loc, expr.value, RO_ARROW), - ident); + ident, comp_loc); set_c_expr_source_range (&expr, start, finish); expr.original_code = ERROR_MARK; if (TREE_CODE (expr.value) != COMPONENT_REF) @@ -10622,9 +10633,12 @@ c_parser_omp_variable_list (c_parser *parser, t = error_mark_node; break; } - tree ident = c_parser_peek_token (parser)->value; + + c_token *comp_tok = c_parser_peek_token (parser); + 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); + t = build_component_ref (op_loc, t, ident, comp_loc); } /* FALLTHROUGH */ case OMP_CLAUSE_DEPEND: diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 444e9a4..b4374e3 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -614,7 +614,7 @@ extern struct c_expr convert_lvalue_to_rvalue (location_t, struct c_expr, bool, bool); extern void mark_exp_read (tree); extern tree composite_type (tree, tree); -extern tree build_component_ref (location_t, tree, tree); +extern tree build_component_ref (location_t, tree, tree, location_t); extern tree build_array_ref (location_t, tree, tree); extern tree build_external_ref (location_t, tree, int, tree *); extern void pop_maybe_used (bool); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index cee566f..cd8e9e5 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -2329,10 +2329,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. */ + location of the COMPONENT_REF. COMPONENT_LOC is the location + of COMPONENT. */ tree -build_component_ref (location_t loc, tree datum, tree component) +build_component_ref (location_t loc, tree datum, tree component, + location_t component_loc) { tree type = TREE_TYPE (datum); enum tree_code code = TREE_CODE (type); @@ -2364,8 +2366,24 @@ build_component_ref (location_t loc, tree datum, tree component) { tree guessed_id = lookup_field_fuzzy (type, component); if (guessed_id) - error_at (loc, "%qT has no member named %qE; did you mean %qE?", - type, component, guessed_id); + { + /* Attempt to provide a fixit replacement hint, if + we have a valid range for the component. */ + location_t reported_loc + = (component_loc != UNKNOWN_LOCATION) ? component_loc : loc; + rich_location rich_loc (line_table, reported_loc); + if (component_loc != UNKNOWN_LOCATION) + { + source_range component_range = + get_range_from_loc (line_table, component_loc); + rich_loc.add_fixit_replace (component_range, + IDENTIFIER_POINTER (guessed_id)); + } + error_at_rich_loc + (&rich_loc, + "%qT has no member named %qE; did you mean %qE?", + type, component, guessed_id); + } else error_at (loc, "%qT has no member named %qE", type, component); return error_mark_node; diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 3b3f0f5..ddc670a 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,8 @@ +2016-06-07 David Malcolm <dmalcolm@redhat.com> + + * objc-act.c (objc_build_component_ref): Update call + to build_component_ref for added param, passing UNKNOWN_LOCATION. + 2016-04-18 Michael Matz <matz@suse.de> * objc-act.c (objc_build_struct): Use SET_DECL_ALIGN. diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 4856457..44f01d2 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -2654,7 +2654,8 @@ objc_build_component_ref (tree datum, tree component) return finish_class_member_access_expr (datum, component, false, tf_warning_or_error); #else - return build_component_ref (input_location, datum, component); + return build_component_ref (input_location, datum, component, + UNKNOWN_LOCATION); #endif } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 33540ea..dd514d6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-06-07 David Malcolm <dmalcolm@redhat.com> + + * gcc.dg/spellcheck-fields-2.c: New test case. + 2016-06-07 Richard Biener <rguenther@suse.de> PR c/61564 diff --git a/gcc/testsuite/gcc.dg/spellcheck-fields-2.c b/gcc/testsuite/gcc.dg/spellcheck-fields-2.c new file mode 100644 index 0000000..d6ebff1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-fields-2.c @@ -0,0 +1,19 @@ +/* { dg-options "-fdiagnostics-show-caret" } */ + +union u +{ + int color; + int shape; +}; + +int test (union u *ptr) +{ + return ptr->colour; /* { dg-error "did you mean .color.?" } */ +} + +/* Verify that we get an underline and a fixit hint. */ +/* { dg-begin-multiline-output "" } + return ptr->colour; + ^~~~~~ + color + { dg-end-multiline-output "" } */ |