Ping for gcc 8.

On Fri, 2017-03-31 at 12:41 -0400, David Malcolm wrote:
> As noted in the PR, the C++ frontend currently offers a poor
> suggestion for this misspelling:
> 
> a.C: In function ‘void f()’:
> a.C:3:3: error: ‘static_assertion’ was not declared in this scope
>    static_assertion (1 == 0, "1 == 0");
>    ^~~~~~~~~~~~~~~~
> a.C:3:3: note: suggested alternative: ‘__cpp_static_assert’
>    static_assertion (1 == 0, "1 == 0");
>    ^~~~~~~~~~~~~~~~
>    __cpp_static_assert
> 
> when it ought to offer "static_assert" as a suggestion instead.
> 
> The root causes are two issues within lookup_name_fuzzy
> (called here with FUZZY_LOOKUP_NAME):
> 
> (a) If it finds a good enough match in the preprocessor it will
>     return the best match *before* considering reserved words,
>     rather than picking the closest match overall.
> 
>     The fix is to have merge all the results into one best_match
>     instance, and pick the overall winner.  However, given that
>     some candidates are identifiers (trees), and others are cpp
>     macros, the best_match instance's candidate type needs to
>     be converted from tree to const char *.  This has some minor
>     knock-on effects within name-lookup.c.  Sadly it means some
>     extra calls to strlen (one per candidate), but this will be
>     purely when error-handling.
> 
> (b) It rejects "static_assert" here:
> 
>       4998    if (!cp_keyword_starts_decl_specifier_p (resword->rid))
>       4999      continue;
> 
>     as "static_assert" doesn't start a decl specifier.
> 
>     The fix is to only apply this rejection criterion if we're
> looking
>     for typenames, rather than for names in general.
> 
> This patch addresses both issues and adds test coverage.
> 
> Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.
> Adds 7 PASS and 1 UNSUPPORTED (for -std=c++98) to g++.sum
> 
> OK for next stage 1?
> 
> gcc/cp/ChangeLog:
>       PR c++/80177
>       * name-lookup.c (suggest_alternative_in_explicit_scope):
> Convert
>       candidate type of bm from tree to const char *.
>       (consider_binding_level): Likewise.
>       (lookup_name_fuzzy): Likewise, using this to merge the best
>       result from the preprocessor into bm, rather than immediately
>       returning, so that better matches from reserved words can
> "win".
>       Guard the rejection of keywords that don't start decl
> -specifiers
>       so it only happens for FUZZY_LOOKUP_TYPENAME.
> 
> gcc/testsuite/ChangeLog:
>       PR c++/80177
>       * g++.dg/spellcheck-pr80177.C: New test case.
> ---
>  gcc/cp/name-lookup.c                      | 37 +++++++++++++--------
> ----------
>  gcc/testsuite/g++.dg/spellcheck-pr80177.C |  7 ++++++
>  2 files changed, 23 insertions(+), 21 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/spellcheck-pr80177.C
> 
> diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
> index 994f7f0..16ec0a1 100644
> --- a/gcc/cp/name-lookup.c
> +++ b/gcc/cp/name-lookup.c
> @@ -48,7 +48,8 @@ static bool lookup_using_namespace (tree, struct
> scope_binding *, tree,
>                                   tree, int);
>  static bool qualified_lookup_using_namespace (tree, tree,
>                                             struct scope_binding
> *, int);
> -static void consider_binding_level (tree name, best_match <tree,
> tree> &bm,
> +static void consider_binding_level (tree name,
> +                                 best_match <tree, const char *>
> &bm,
>                                   cp_binding_level *lvl,
>                                   bool look_within_fields,
>                                   enum lookup_name_fuzzy_kind
> kind);
> @@ -4550,14 +4551,13 @@ suggest_alternative_in_explicit_scope
> (location_t location, tree name,
>  
>    cp_binding_level *level = NAMESPACE_LEVEL (scope);
>  
> -  best_match <tree, tree> bm (name);
> +  best_match <tree, const char *> bm (name);
>    consider_binding_level (name, bm, level, false,
> FUZZY_LOOKUP_NAME);
>  
>    /* See if we have a good suggesion for the user.  */
> -  tree best_id = bm.get_best_meaningful_candidate ();
> -  if (best_id)
> +  const char *fuzzy_name = bm.get_best_meaningful_candidate ();
> +  if (fuzzy_name)
>      {
> -      const char *fuzzy_name = IDENTIFIER_POINTER (best_id);
>        gcc_rich_location richloc (location);
>        richloc.add_fixit_replace (fuzzy_name);
>        inform_at_rich_loc (&richloc, "suggested alternative: %qs",
> @@ -4797,7 +4797,7 @@ qualified_lookup_using_namespace (tree name,
> tree scope,
>     Traverse binding level LVL, looking for good name matches for
> NAME
>     (and BM).  */
>  static void
> -consider_binding_level (tree name, best_match <tree, tree> &bm,
> +consider_binding_level (tree name, best_match <tree, const char *>
> &bm,
>                       cp_binding_level *lvl, bool
> look_within_fields,
>                       enum lookup_name_fuzzy_kind kind)
>  {
> @@ -4809,7 +4809,7 @@ consider_binding_level (tree name, best_match
> <tree, tree> &bm,
>       tree best_matching_field
>         = lookup_member_fuzzy (type, name, want_type_p);
>       if (best_matching_field)
> -       bm.consider (best_matching_field);
> +       bm.consider (IDENTIFIER_POINTER (best_matching_field));
>        }
>  
>    for (tree t = lvl->names; t; t = TREE_CHAIN (t))
> @@ -4838,7 +4838,7 @@ consider_binding_level (tree name, best_match
> <tree, tree> &bm,
>        if (tree name = DECL_NAME (d))
>       /* Ignore internal names with spaces in them.  */
>       if (!strchr (IDENTIFIER_POINTER (name), ' '))
> -       bm.consider (DECL_NAME (d));
> +       bm.consider (IDENTIFIER_POINTER (name));
>      }
>  }
>  
> @@ -4851,7 +4851,7 @@ lookup_name_fuzzy (tree name, enum
> lookup_name_fuzzy_kind kind)
>  {
>    gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
>  
> -  best_match <tree, tree> bm (name);
> +  best_match <tree, const char *> bm (name);
>  
>    cp_binding_level *lvl;
>    for (lvl = scope_chain->class_bindings; lvl; lvl = lvl
> ->level_chain)
> @@ -4874,9 +4874,9 @@ lookup_name_fuzzy (tree name, enum
> lookup_name_fuzzy_kind kind)
>       the identifiers already checked.  */
>    best_macro_match bmm (name, bm.get_best_distance (), parse_in);
>    cpp_hashnode *best_macro = bmm.get_best_meaningful_candidate ();
> -  /* If a macro is the closest so far to NAME, suggest it.  */
> +  /* If a macro is the closest so far to NAME, consider it.  */
>    if (best_macro)
> -    return (const char *)best_macro->ident.str;
> +    bm.consider ((const char *)best_macro->ident.str);
>  
>    /* Try the "starts_decl_specifier_p" keywords to detect
>       "singed" vs "signed" typos.  */
> @@ -4884,8 +4884,9 @@ lookup_name_fuzzy (tree name, enum
> lookup_name_fuzzy_kind kind)
>      {
>        const c_common_resword *resword = &c_common_reswords[i];
>  
> -      if (!cp_keyword_starts_decl_specifier_p (resword->rid))
> -     continue;
> +      if (kind == FUZZY_LOOKUP_TYPENAME)
> +     if (!cp_keyword_starts_decl_specifier_p (resword->rid))
> +       continue;
>  
>        tree resword_identifier = ridpointers [resword->rid];
>        if (!resword_identifier)
> @@ -4897,16 +4898,10 @@ lookup_name_fuzzy (tree name, enum
> lookup_name_fuzzy_kind kind)
>        if (!C_IS_RESERVED_WORD (resword_identifier))
>       continue;
>  
> -      bm.consider (resword_identifier);
> +      bm.consider (IDENTIFIER_POINTER (resword_identifier));
>      }
>  
> -  /* See if we have a good suggesion for the user.  */
> -  tree best_id = bm.get_best_meaningful_candidate ();
> -  if (best_id)
> -    return IDENTIFIER_POINTER (best_id);
> -
> -  /* No meaningful suggestion available.  */
> -  return NULL;
> +  return bm.get_best_meaningful_candidate ();
>  }
>  
>  /* Subroutine of outer_binding.
> diff --git a/gcc/testsuite/g++.dg/spellcheck-pr80177.C
> b/gcc/testsuite/g++.dg/spellcheck-pr80177.C
> new file mode 100644
> index 0000000..2ff24e8
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/spellcheck-pr80177.C
> @@ -0,0 +1,7 @@
> +// { dg-do compile { target c++11 } }
> +
> +void pr80177 ()
> +{
> +  static_assertion (1 == 0, "1 == 0"); // { dg-error "3:
> 'static_assertion' was not declared in this scope" }
> +  // { dg-message "3: suggested alternative: 'static_assert'" "" {
> target *-*-* } .-1 }
> +}

Reply via email to