diff options
author | David Malcolm <dmalcolm@redhat.com> | 2018-02-07 17:55:54 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2018-02-07 17:55:54 +0000 |
commit | 0d7d8e66e4f6bcdfc363db28a4a79c3fe6d89beb (patch) | |
tree | acf80cb00db639a9d1bb07ecfc76a71a183fe04a | |
parent | 085e82463714a665bc0236fb753dd5a216a0507e (diff) | |
download | gcc-0d7d8e66e4f6bcdfc363db28a4a79c3fe6d89beb.zip gcc-0d7d8e66e4f6bcdfc363db28a4a79c3fe6d89beb.tar.gz gcc-0d7d8e66e4f6bcdfc363db28a4a79c3fe6d89beb.tar.bz2 |
C++: avoid most reserved words as misspelling suggestions (PR c++/81610 and PR c++/80567)
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.
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".
From-SVN: r257456
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/spellcheck-reswords.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/spellcheck-stdlib.C | 2 |
5 files changed, 56 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ce0b759..42c3cbf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2018-02-07 David Malcolm <dmalcolm@redhat.com> + + 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. + 2018-02-07 Jason Merrill <jason@redhat.com> PR c++/84182 - ICE with captured lambda diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index d0488c0..e5a3400 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -5705,6 +5705,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 @@ -5769,9 +5795,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/ChangeLog b/gcc/testsuite/ChangeLog index 42f163a..ec17df1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2018-02-07 David Malcolm <dmalcolm@redhat.com> + + 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". + 2018-02-07 Martin Liska <mliska@suse.cz> PR c++/84059. 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 } |