This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PING: [PATCH] C++: avoid most reserved words as misspelling suggestions (PR c++/81610 and PR c++/80567)
- From: David Malcolm <dmalcolm at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 11 Dec 2017 11:09:56 -0500
- Subject: PING: [PATCH] C++: avoid most reserved words as misspelling suggestions (PR c++/81610 and PR c++/80567)
- Authentication-results: sourceware.org; auth=none
- References: <1511365007-22684-1-git-send-email-dmalcolm@redhat.com>
Ping: https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02048.html
On Wed, 2017-11-22 at 10:36 -0500, David Malcolm wrote:
> lookup_name_fuzzy can offer some reserved words as suggestions for
> misspelled words, helping with "singed"/"signed" typos.
>
> PR c++/81610 and PR c++/80567 report problems where the C++ frontend
> suggested "if", "for" and "else" as corrections for misspelled
> variable
> names.
>
> The root cause is that in r247233
> ("Fix spelling suggestions for reserved words (PR c++/80177)")
> I loosened the conditions on these reserved words, adding this
> condition:
> if (kind == FUZZY_LOOKUP_TYPENAME)
> to the logic for rejecting words that don't start decl-specifiers, to
> allow for "static_assert" to be offered.
>
> This is too loose a condition: we don't want to suggest *any*
> reserved word
> when we're in a context where we don't know we expect a typename.
>
> For the kinds of error-recover situations where we're suggesting
> spelling corrections we don't have much contextual information, so it
> seems prudent to be stricter about which reserved words we offer
> as spelling suggestions; I don't think it makes sense for us to
> suggest e.g. "for".
>
> This patch implements that by effectively reinstating the old logic,
> but special-casing RID_STATIC_ASSERT, moving the logic to a new
> subroutine (in case we want to allow for other special-cases).
>
> I attempted to add suggestions for the various RID_*CAST, to cope
> with e.g. "reinterptet_cast" (I can never type that correctly on the
> first try), but the following '<' token confuses the error-recovery
> enough that the suggestion code isn't triggered.
>
> Hence this more minimal fix.
>
> Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
>
> OK for trunk?
>
> gcc/cp/ChangeLog:
> PR c++/81610
> PR c++/80567
> * name-lookup.c (suggest_rid_p): New function.
> (lookup_name_fuzzy): Replace enum-rid-filtering logic with call
> to
> suggest_rid_p.
>
> gcc/testsuite/ChangeLog:
> PR c++/81610
> PR c++/80567
> * g++.dg/spellcheck-reswords.C: New test case.
> * g++.dg/spellcheck-stdlib.C: Remove xfail from dg-bogus
> suggestion of "if".
> ---
> gcc/cp/name-lookup.c | 31
> +++++++++++++++++++++++++++---
> gcc/testsuite/g++.dg/spellcheck-reswords.C | 11 +++++++++++
> gcc/testsuite/g++.dg/spellcheck-stdlib.C | 2 +-
> 3 files changed, 40 insertions(+), 4 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/spellcheck-reswords.C
>
> diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
> index 7c363b0..a96be46 100644
> --- a/gcc/cp/name-lookup.c
> +++ b/gcc/cp/name-lookup.c
> @@ -5671,6 +5671,32 @@ class macro_use_before_def : public
> deferred_diagnostic
> cpp_hashnode *m_macro;
> };
>
> +/* Determine if it can ever make sense to offer RID as a suggestion
> for
> + a misspelling.
> +
> + Subroutine of lookup_name_fuzzy. */
> +
> +static bool
> +suggest_rid_p (enum rid rid)
> +{
> + switch (rid)
> + {
> + /* Support suggesting function-like keywords. */
> + case RID_STATIC_ASSERT:
> + return true;
> +
> + default:
> + /* Support suggesting the various decl-specifier words, to
> handle
> + e.g. "singed" vs "signed" typos. */
> + if (cp_keyword_starts_decl_specifier_p (rid))
> + return true;
> +
> + /* Otherwise, don't offer it. This avoids suggesting e.g.
> "if"
> + and "do" for short misspellings, which are likely to lead
> to
> + nonsensical results. */
> + return false;
> + }
> +}
>
> /* Search for near-matches for NAME within the current bindings, and
> within
> macro names, returning the best match as a const char *, or NULL
> if
> @@ -5735,9 +5761,8 @@ lookup_name_fuzzy (tree name, enum
> lookup_name_fuzzy_kind kind, location_t loc)
> {
> const c_common_resword *resword = &c_common_reswords[i];
>
> - if (kind == FUZZY_LOOKUP_TYPENAME)
> - if (!cp_keyword_starts_decl_specifier_p (resword->rid))
> - continue;
> + if (!suggest_rid_p (resword->rid))
> + continue;
>
> tree resword_identifier = ridpointers [resword->rid];
> if (!resword_identifier)
> diff --git a/gcc/testsuite/g++.dg/spellcheck-reswords.C
> b/gcc/testsuite/g++.dg/spellcheck-reswords.C
> new file mode 100644
> index 0000000..db6104b
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/spellcheck-reswords.C
> @@ -0,0 +1,11 @@
> +void pr81610 (void *p)
> +{
> + forget (p); // { dg-error "not declared" }
> + // { dg-bogus "'for'" "" { target *-*-*} .-1 }
> +}
> +
> +void pr80567 (void *p)
> +{
> + memset (p, 0, 4); // { dg-error "not declared" }
> + // { dg-bogus "'else'" "" { target *-*-*} .-1 }
> +}
> diff --git a/gcc/testsuite/g++.dg/spellcheck-stdlib.C
> b/gcc/testsuite/g++.dg/spellcheck-stdlib.C
> index 6e6ab1d..c7a6626 100644
> --- a/gcc/testsuite/g++.dg/spellcheck-stdlib.C
> +++ b/gcc/testsuite/g++.dg/spellcheck-stdlib.C
> @@ -16,7 +16,7 @@ void test_cstdio (void)
> FILE *f; // { dg-error "'FILE' was not declared in this scope" }
> // { dg-message "'FILE' is defined in header '<cstdio>'; did you
> forget to '#include <cstdio>'?" "" { target *-*-* } .-1 }
> // { dg-error "'f' was not declared in this scope" "" { target *-
> *-* } .-2 }
> - // { dg-bogus "suggested alternative: 'if'" "PR c++/80567" { xfail
> *-*-* } .-3 }
> + // { dg-bogus "suggested alternative: 'if'" "PR c++/80567" {
> target *-*-* } .-3 }
>
> char buf[BUFSIZ]; // { dg-error "'BUFSIZ' was not declared" }
> // { dg-message "'BUFSIZ' is defined in header '<cstdio>'; did you
> forget to '#include <cstdio>'?" "" { target *-*-* } .-1 }