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