aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2018-02-07 17:55:54 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2018-02-07 17:55:54 +0000
commit0d7d8e66e4f6bcdfc363db28a4a79c3fe6d89beb (patch)
treeacf80cb00db639a9d1bb07ecfc76a71a183fe04a
parent085e82463714a665bc0236fb753dd5a216a0507e (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cp/name-lookup.c31
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/spellcheck-reswords.C11
-rw-r--r--gcc/testsuite/g++.dg/spellcheck-stdlib.C2
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 }