xref: /llvm-project/clang/test/Sema/warn-deprecated-non-prototype.c (revision 9c4ade0623af842cda16e5c71b27fb794a3ff3db)
1 // RUN: %clang_cc1 -fsyntax-only -verify=both,expected %s
2 // RUN: %clang_cc1 -fsyntax-only -Wstrict-prototypes -verify=both,strict %s
3 
4 // Test both with and without -Wstrict-prototypes because there are complicated
5 // interactions between it and -Wdeprecated-non-prototype.
6 
7 // Off by default warnings, enabled by -pedantic or -Wstrict-prototypes
8 void other_func();   // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
other_func()9 void other_func() {} // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
10 
11 void never_defined(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
12 
13 typedef void (*fp)(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
14 
15 void blerp(
16   void (*func_ptr)() // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
17 );
18 
whatever(void)19 void whatever(void) {
20   extern void hoo_boy(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
21 }
22 
again()23 void again() {} // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
24 
25 // On by default warnings
26 void func();                 // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is treated as a zero-parameter prototype in C23, conflicting with a subsequent definition}} \
27                                 strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
func(a,b)28 void func(a, b) int a, b; {} // both-warning {{a function definition without a prototype is deprecated in all versions of C and is not supported in C23}}
29 
one_more(a,b)30 void one_more(a, b) int a, b; {} // both-warning {{a function definition without a prototype is deprecated in all versions of C and is not supported in C23}}
31 
32 void sheesh(int a);
sheesh(a)33 void sheesh(a) int a; {} // both-warning {{a function definition without a prototype is deprecated in all versions of C and is not supported in C23}}
34 
35 void another(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
36 
main(void)37 int main(void) {
38   another(1, 2);  // both-warning {{passing arguments to 'another' without a prototype is deprecated in all versions of C and is not supported in C23}}
39 }
40 
41 void order1();        // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is treated as a zero-parameter prototype in C23, conflicting with a subsequent declaration}} \
42                          strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
43 void order1(int i);   // both-note {{conflicting prototype is here}}
44 
45 void order2(int i);   // both-note {{conflicting prototype is here}}
46 void order2();        // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is treated as a zero-parameter prototype in C23, conflicting with a previous declaration}} \
47                          strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
48 
49 void order3();        // both-warning {{a function declaration without a prototype is deprecated in all versions of C and is treated as a zero-parameter prototype in C23, conflicting with a subsequent definition}} \
50                          strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
order3(int i)51 void order3(int i) {} // both-note {{conflicting prototype is here}}
52 
53 // Just because the prototype is variadic doesn't mean we shouldn't warn on the
54 // K&R C function definition; this still changes behavior in C23.
55 void test(char*,...);
test(fmt)56 void test(fmt)        // both-warning {{a function definition without a prototype is deprecated in all versions of C and is not supported in C23}}
57         char*fmt;
58 {
59 }
60 
61 void blapp(int); // both-note {{previous declaration is here}}
blapp()62 void blapp() { } // both-error {{conflicting types for 'blapp'}} \
63                  // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
64 
65 // Disable -Wdeprecated-non-prototype
66 #pragma GCC diagnostic push
67 #pragma GCC diagnostic ignored "-Wdeprecated-non-prototype"
68 void depr_non_prot(); // strict-warning {{a function declaration without a prototype is deprecated in all versions of C}}
69 #pragma GCC diagnostic pop
70 // Reenable it.
71 
72 // Disable -Wstrict-prototypes
73 #pragma GCC diagnostic push
74 #pragma GCC diagnostic ignored "-Wstrict-prototypes"
75 void strict_prot(); // OK
76 #pragma GCC diagnostic pop
77 // Reenable it.
78 
calls(void)79 void calls(void) {
80   // Ensure that we diagnose calls to functions without a prototype, but only
81   // if they pass arguments.
82   never_defined(); // OK
83   never_defined(1); // both-warning {{passing arguments to 'never_defined' without a prototype is deprecated in all versions of C and is not supported in C23}}
84 
85   // Ensure that calls to builtins without a traditional prototype are not
86   // diagnosed.
87   (void)__builtin_isless(1.0, 1.0); // OK
88 
89   // Calling a function whose prototype was provided by a function with an
90   // identifier list is still fine.
91   func(1, 2); // OK
92 
93   // Ensure that a call through a function pointer is still diagnosed properly.
94   fp f;
95   f(); // OK
96   f(1, 2); // both-warning {{passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23}}
97 
98   // Ensure that we don't diagnose when the diagnostic group is disabled.
99   depr_non_prot(1); // OK
100   strict_prot(1); // OK
101 
102   // Ensure we don't issue diagnostics if the function without a prototype was
103   // later given a prototype by a definintion. Also ensure we don't duplicate
104   // diagnostics if such a call is incorrect.
105   func(1, 2); // OK
106   func(1, 2, 3); // both-warning {{too many arguments in call to 'func'}}
107 }
108 
109 // Issue 58181 -- we would issue the warning about the function without a
110 // prototype twice when the function was declared static in the following
111 // example.
112 static int GH58181(int x, int y);
GH58181(x,y)113 static int GH58181(x, y) // both-warning {{a function definition without a prototype is deprecated in all versions of C and is not supported in C23}}
114     int x;
115     int y;
116 {
117     return x + y;
118 }
119