diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 04d2030b561..92033ba8b47 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2016-11-29 David Malcolm + + PR c++/72774 + PR c++/72786 + PR c++/77922 + PR c++/78313 + * spellcheck.c (selftest::test_find_closest_string): Verify that + we don't offer the goal string as a suggestion. + * spellcheck.h (best_match::get_best_meaningful_candidate): Don't + offer the goal string as a suggestion. + + 2016-11-29 Claudiu Zissulescu * config/arc/arc.c (arc_override_options): Avoid selection of diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 476ff654bce..35db0db017c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-11-29 David Malcolm + + PR c++/77922 + * name-lookup.c (lookup_name_fuzzy): Filter out reserved words + that were filtered out by init_reswords. + 2016-11-28 Jakub Jelinek Jason Merrill diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 4f80e8d5af9..d80c0318330 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4812,6 +4812,12 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind) if (!resword_identifier) continue; gcc_assert (TREE_CODE (resword_identifier) == IDENTIFIER_NODE); + + /* Only consider reserved words that survived the + filtering in init_reswords (e.g. for -std). */ + if (!C_IS_RESERVED_WORD (resword_identifier)) + continue; + bm.consider (resword_identifier); } diff --git a/gcc/spellcheck.c b/gcc/spellcheck.c index b37b1e46929..86cdee14d79 100644 --- a/gcc/spellcheck.c +++ b/gcc/spellcheck.c @@ -210,6 +210,11 @@ test_find_closest_string () ASSERT_STREQ ("banana", find_closest_string ("banyan", &candidates)); ASSERT_STREQ ("cherry", find_closest_string ("berry", &candidates)); ASSERT_EQ (NULL, find_closest_string ("not like the others", &candidates)); + + /* If the goal string somehow makes it into the candidate list, offering + it as a suggestion will be nonsensical. Verify that we don't offer such + suggestions. */ + ASSERT_EQ (NULL, find_closest_string ("banana", &candidates)); } /* Test data for test_metric_conditions. */ diff --git a/gcc/spellcheck.h b/gcc/spellcheck.h index b48cfbc4072..41c9308c2a1 100644 --- a/gcc/spellcheck.h +++ b/gcc/spellcheck.h @@ -165,6 +165,16 @@ class best_match if (m_best_distance > cutoff) return NULL; } + + /* If the goal string somehow makes it into the candidate list, offering + it as a suggestion will be nonsensical e.g. + 'constexpr' does not name a type; did you mean 'constexpr'? + Ultimately such suggestions are due to bugs in constructing the + candidate list, but as a band-aid, do not offer suggestions for + distance == 0 (where candidate == goal). */ + if (m_best_distance == 0) + return NULL; + return m_best_candidate; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 71b86849e0c..2107f7eacc1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2016-11-29 David Malcolm + + PR c++/72774 + PR c++/72786 + PR c++/77922 + PR c++/78313 + * g++.dg/spellcheck-c++-11-keyword.C: New test case. + * g++.dg/spellcheck-macro-ordering.C: New test case. + * g++.dg/spellcheck-pr78313.C: New test case. + 2016-11-29 Tamar Christina * gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h diff --git a/gcc/testsuite/g++.dg/spellcheck-c++-11-keyword.C b/gcc/testsuite/g++.dg/spellcheck-c++-11-keyword.C new file mode 100644 index 00000000000..0984af9d72e --- /dev/null +++ b/gcc/testsuite/g++.dg/spellcheck-c++-11-keyword.C @@ -0,0 +1,15 @@ +/* c++/77922: "constexpr" is only available from C++11 onwards. + We shouldn't offer it as a spellcheck suggestion in C++98. */ +// { dg-options "-std=c++98" } + +constexpr int a = 1; // { dg-bogus "did you mean" } +// { dg-error ".constexpr. does not name a type" "" { target *-*-* } .-1 } +// { dg-message "C\\+\\+11 .constexpr. only available with -std=c\\+\\+11 or -std=gnu\\+\\+11" "" { target *-*-* } .-2 } + +/* If the user typos "constexpr" (here as "consexpr"), don't offer it as a + spelling suggestion in C++98 mode. */ +consexpr int a = 1; // { dg-bogus "did you mean" } +// { dg-error ".consexpr. does not name a type" "" { target *-*-* } .-1 } + +decltype i = 0; // { dg-bogus "did you mean" } +// { dg-error ".decltype. does not name a type" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/g++.dg/spellcheck-macro-ordering.C b/gcc/testsuite/g++.dg/spellcheck-macro-ordering.C new file mode 100644 index 00000000000..3b888c6dcb3 --- /dev/null +++ b/gcc/testsuite/g++.dg/spellcheck-macro-ordering.C @@ -0,0 +1,15 @@ +// PR c++/72786 + +/* Example of a macro-ordering issue, where the use is before the defn. */ + +class DocTargetDriver { + virtual void clone() const OVERRIDE { } + /* Offering "OVERRIDE" as a spelling suggestion for "OVERRIDE" would be + nonsensical. */ + // { dg-bogus "did you mean" "" { target *-*-* } .-3 } + // { dg-error "expected .;. at end of member declaration" "" { target *-*-* } .-4 } + // { dg-error ".OVERRIDE. does not name a type" "" { target *-*-* } .-5 } +}; + +#define OVERRIDE override + diff --git a/gcc/testsuite/g++.dg/spellcheck-pr78313.C b/gcc/testsuite/g++.dg/spellcheck-pr78313.C new file mode 100644 index 00000000000..e34176d5f74 --- /dev/null +++ b/gcc/testsuite/g++.dg/spellcheck-pr78313.C @@ -0,0 +1,11 @@ +// PR c++/78313 (see also PR c++/72774) +// { dg-do compile } + +void baz (); +namespace A { void foo (); } +void bar () +{ + using A::foo; + 0 ? static_cast (0) : baz; // { dg-bogus "did you mean" } + // { dg-error "does not name a type" "" { target *-*-* } .-1 } +}