Bug 95445 - diagnose incompatible calls to functions declared without prototype [-Wdeprecated-non-prototype]
Summary: diagnose incompatible calls to functions declared without prototype [-Wdeprec...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 10.0
: P3 enhancement
Target Milestone: 15.0
Assignee: Florian Weimer
URL: https://gcc.gnu.org/pipermail/gcc-pat...
Keywords: diagnostic, patch
Depends on:
Blocks: new-warning, new_warning
  Show dependency treegraph
 
Reported: 2020-05-30 22:32 UTC by Martin Sebor
Modified: 2024-11-17 18:45 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-11-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2020-05-30 22:32:07 UTC
GCC silently accepts calls to built-in functions declared without a prototype as long as the arguments match the expected types (based on the prototype hardcoded into GCC), but issues warnings for calls where the arguments don't match.

But GCC makes no attempt to make sure that in calls to other (i.e., non-built-in) functions declared without prototype provided arguments have the same type across all the calls.  Diagnosing mismatches as suggested in the comments below would help detect bugs caused by their incompatibily.

This enhancement is different from pr92212 which is about calls to K&R functions defined in the same translation unit.

$ cat x.c && gcc -O2 -S -Wall x.c
char* strchr ();

char* f0 (const char *s)
{
  return strchr (s, 'x');    // no warning (okay)
}

char* f1 (const char *s)
{
  return strchr (s, "y");    // warning (good)
}

void g ();

void h (void)
{
  g (1);                     // (presumably) okay, f's type is 'void (int)'
  g ("foo");                 // should be diagnosed
  g (1, "bar");              // ditto
}
x.c: In function ‘f1’:
x.c:10:21: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [-Wint-conversion]
   10 |   return strchr (s, "y");    // warning (good)
      |                     ^~~
      |                     |
      |                     char *
x.c:1:7: note: expected ‘int’ but argument is of type ‘char *’
    1 | char* strchr ();
      |       ^~~~~~
Comment 1 Eric Gallager 2021-10-27 05:21:02 UTC
Is this like clang's -Wknr-promoted-parameter? https://clang.llvm.org/docs/DiagnosticsReference.html#wknr-promoted-parameter
Comment 2 Florian Weimer 2023-05-12 15:54:03 UTC
Current Clang warns like this:

t.c:17:5: warning: passing arguments to 'g' without a prototype is deprecated in all versions of C and is not supported in C2x [-Wdeprecated-non-prototype]
  g (1);                     // (presumably) okay, f's type is 'void (int)'
    ^
t.c:18:5: warning: passing arguments to 'g' without a prototype is deprecated in all versions of C and is not supported in C2x [-Wdeprecated-non-prototype]
  g ("foo");                 // should be diagnosed
    ^
t.c:19:5: warning: passing arguments to 'g' without a prototype is deprecated in all versions of C and is not supported in C2x [-Wdeprecated-non-prototype]
  g (1, "bar");              // ditto
    ^

Maybe that's sufficient?

Trying to infer the type of g from its uses seems to be rather questionable. For K&R projects, GCC already has -flto -Wlto-type-mismatch, which can diagnose violations across translation units.
Comment 3 Sam James 2023-05-12 16:29:03 UTC
I don't think we need to go beyond that (I don't really care about the uses).

That'll make this a dupe of/depends on PR108694?
Comment 4 Florian Weimer 2024-11-15 23:18:10 UTC
Patch posted:

[PATCH] c: Implement -Wdeprecated-non-prototype
<https://inbox.sourceware.org/gcc-patches/87plmwyue3.fsf@oldenburg.str.redhat.com/>

This is what the new warning produces for the input from the description:

t.c: In function ‘f0’:
t.c:5:10: warning: ISO C23 does not allow arguments for function ‘strchr’ declared without parameters [-Wdeprecated-non-prototype]
    5 |   return strchr (s, 'x');    // no warning (okay)
      |          ^~~~~~
t.c:1:7: note: declared here
    1 | char* strchr ();
      |       ^~~~~~
t.c: In function ‘f1’:
t.c:10:10: warning: ISO C23 does not allow arguments for function ‘strchr’ declared without parameters [-Wdeprecated-non-prototype]
   10 |   return strchr (s, "y");    // warning (good)
      |          ^~~~~~
t.c:1:7: note: declared here
    1 | char* strchr ();
      |       ^~~~~~
t.c:10:21: error: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [-Wint-conversion]
   10 |   return strchr (s, "y");    // warning (good)
      |                     ^~~
      |                     |
      |                     char *
t.c:1:7: note: expected ‘int’ but argument is of type ‘char *’
    1 | char* strchr ();
      |       ^~~~~~
t.c: In function ‘h’:
t.c:17:3: warning: ISO C23 does not allow arguments for function ‘g’ declared without parameters [-Wdeprecated-non-prototype]
   17 |   g (1);                     // (presumably) okay, f's type is 'void (int)'
      |   ^
t.c:13:6: note: declared here
   13 | void g ();
      |      ^
t.c:18:3: warning: ISO C23 does not allow arguments for function ‘g’ declared without parameters [-Wdeprecated-non-prototype]
   18 |   g ("foo");                 // should be diagnosed
      |   ^
t.c:13:6: note: declared here
   13 | void g ();
      |      ^
t.c:19:3: warning: ISO C23 does not allow arguments for function ‘g’ declared without parameters [-Wdeprecated-non-prototype]
   19 |   g (1, "bar");              // ditto
      |   ^
t.c:13:6: note: declared here
   13 | void g ();
      |      ^
Comment 5 GCC Commits 2024-11-17 18:42:53 UTC
The trunk branch has been updated by Florian Weimer <fw@gcc.gnu.org>:

https://gcc.gnu.org/g:701d8e7e60b85809cae348c1e9edb3b0f4924325

commit r15-5369-g701d8e7e60b85809cae348c1e9edb3b0f4924325
Author: Florian Weimer <fweimer@redhat.com>
Date:   Sun Nov 17 19:42:33 2024 +0100

    c: Implement -Wdeprecated-non-prototype
    
    This warning covers the C23 incompibilities resulting from using
    () as parameter lists in function declarations.
    
    The warning name comes from Clang.  The implementation is not
    perfect because GCC treats these two declarations as equivalent:
    
      void f ();
      void f (not_a_type);
    
    This is a bit confusing because they are clearly visually distinct.
    However, as of GCC 14, the second form is an error by default, so
    treating both the same as far as  -Wdeprecated-non-prototype does
    not seem so bad from a user experience view.
    
    gcc/c-family/
    
            PR c/95445
            * c-opts.cc (c_common_post_options): Initialize
            warn_deprecated_non_prototype.
            * c.opt (Wdeprecated-non-prototype): New option.
            * c.opt.urls: Regenerate.
    
    gcc/c/
    
            PR c/95445
            * c-decl.cc (start_function): Warn about parameters
            after parameter-less declaration.
            * c-typeck.cc (build_function_call_vec): Pass fntype
            to convert_arguments.
            (convert_arguments): Change argument to fntype and
            compute typelist.  Warn about parameter list mismatches
            on first parameter.
    
    gcc/
    
            PR c/95445
            * doc/invoke.texi: Document -Wdeprecated-non-prototype.
    
    gcc/testsuite/
    
            PR c/95445
            * gcc.dg/Wdeprecated-non-prototype-1.c: New test.
            * gcc.dg/Wdeprecated-non-prototype-2.c: New test.
            * gcc.dg/Wdeprecated-non-prototype-3.c: New test.
            * gcc.dg/Wdeprecated-non-prototype-4.c: New test.
Comment 6 Florian Weimer 2024-11-17 18:45:21 UTC
Fixed for GCC 15.