Hi!

When implicit_decl_warning is called, we know we are interested
in a function or function pointer (or macro), C doesn't support
int () like C++, or var () when var doesn't have function pointer type.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-07-14  Jakub Jelinek  <ja...@redhat.com>

        PR c/71858
        * c-common.h (enum lookup_name_fuzzy_kind): Add
        FUZZY_LOOKUP_FUNCTION_NAME.

        * c-decl.c (implicit_decl_warning): Use FUZZY_LOOKUP_FUNCTION_NAME
        instead of FUZZY_LOOKUP_NAME.
        (lookup_name_fuzzy): For FUZZY_LOOKUP_FUNCTION_NAME consider
        FUNCTION_DECLs, {VAR,PARM}_DECLs function pointers and macros.

        * gcc.dg/spellcheck-identifiers-3.c: New test.

--- gcc/c-family/c-common.h.jj  2016-06-24 12:59:21.000000000 +0200
+++ gcc/c-family/c-common.h     2016-07-14 10:07:18.526594783 +0200
@@ -994,6 +994,9 @@ enum lookup_name_fuzzy_kind {
   /* Names of types.  */
   FUZZY_LOOKUP_TYPENAME,
 
+  /* Names of function decls.  */
+  FUZZY_LOOKUP_FUNCTION_NAME,
+
   /* Any name.  */
   FUZZY_LOOKUP_NAME
 };
--- gcc/c/c-decl.c.jj   2016-07-13 22:40:23.000000000 +0200
+++ gcc/c/c-decl.c      2016-07-14 10:29:31.548376306 +0200
@@ -3090,7 +3090,7 @@ implicit_decl_warning (location_t loc, t
       bool warned;
       tree hint = NULL_TREE;
       if (!olddecl)
-       hint = lookup_name_fuzzy (id, FUZZY_LOOKUP_NAME);
+       hint = lookup_name_fuzzy (id, FUZZY_LOOKUP_FUNCTION_NAME);
 
       if (flag_isoc99)
        if (hint)
@@ -4028,9 +4028,30 @@ lookup_name_fuzzy (tree name, enum looku
        if (TREE_CODE (binding->decl) == FUNCTION_DECL)
          if (C_DECL_IMPLICIT (binding->decl))
            continue;
-       if (kind == FUZZY_LOOKUP_TYPENAME)
-         if (TREE_CODE (binding->decl) != TYPE_DECL)
-           continue;
+       switch (kind)
+         {
+         case FUZZY_LOOKUP_TYPENAME:
+           if (TREE_CODE (binding->decl) != TYPE_DECL)
+             continue;
+           break;
+
+         case FUZZY_LOOKUP_FUNCTION_NAME:
+           if (TREE_CODE (binding->decl) != FUNCTION_DECL)
+             {
+               /* Allow function pointers.  */
+               if ((VAR_P (binding->decl)
+                    || TREE_CODE (binding->decl) == PARM_DECL)
+                   && TREE_CODE (TREE_TYPE (binding->decl)) == POINTER_TYPE
+                   && (TREE_CODE (TREE_TYPE (TREE_TYPE (binding->decl)))
+                       == FUNCTION_TYPE))
+                 break;
+               continue;
+             }
+           break;
+
+         default:
+           break;
+         }
        bm.consider (binding->id);
       }
 
--- gcc/testsuite/gcc.dg/spellcheck-identifiers-3.c.jj  2016-07-14 
10:18:17.790090780 +0200
+++ gcc/testsuite/gcc.dg/spellcheck-identifiers-3.c     2016-07-14 
10:39:14.392829944 +0200
@@ -0,0 +1,45 @@
+/* PR c/71858 */
+/* Only consider function names, function pointers and macros for implicit 
function declarations.  */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-function-declaration -fdiagnostics-show-caret" } */
+
+void fn1abcd (void);
+
+void
+test_1 (int fn1bacd)
+{
+  fn1badc (); /* { dg-warning "3: implicit declaration of function .fn1badc.; 
did you mean .fn1abcd.?" } */
+  /* { dg-begin-multiline-output "" }
+   fn1badc ();
+   ^~~~~~~
+   fn1abcd
+   { dg-end-multiline-output "" } */
+}
+
+void fn2efgh (void);
+void (*fn2efhg) (void);
+
+void
+test_2 (void)
+{
+  fn2fehg (); /* { dg-warning "3: implicit declaration of function .fn2fehg.; 
did you mean .fn2efhg.?" } */
+  /* { dg-begin-multiline-output "" }
+   fn2fehg ();
+   ^~~~~~~
+   fn2efhg
+   { dg-end-multiline-output "" } */
+}
+
+void fn3ijkl (void);
+typedef int fn3ijlk;
+
+void
+test_3 (void)
+{
+  fn3jilk (); /* { dg-warning "3: implicit declaration of function .fn3jilk.; 
did you mean .fn3ijkl.?" } */
+  /* { dg-begin-multiline-output "" }
+   fn3jilk ();
+   ^~~~~~~
+   fn3ijkl
+   { dg-end-multiline-output "" } */
+}

        Jakub

Reply via email to