1 | // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s |
2 | |
3 | #if defined(INCLUDE) |
4 | // ------- |
5 | // This section acts like a header file. |
6 | // ------- |
7 | |
8 | // Check the use of static variables in non-static inline functions. |
9 | static int staticVar; // expected-note + {{'staticVar' declared here}} |
10 | static int staticFunction(); // expected-note + {{'staticFunction' declared here}} |
11 | static struct { int x; } staticStruct; // expected-note + {{'staticStruct' declared here}} |
12 | |
13 | inline int useStatic () { // expected-note 3 {{use 'static' to give inline function 'useStatic' internal linkage}} |
14 | staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} |
15 | (void)staticStruct.x; // expected-warning{{static variable 'staticStruct' is used in an inline function with external linkage}} |
16 | return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} |
17 | } |
18 | |
19 | extern inline int useStaticFromExtern () { // no suggestions |
20 | staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} |
21 | return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} |
22 | } |
23 | |
24 | static inline int useStaticFromStatic () { |
25 | staticFunction(); // no-warning |
26 | return staticVar; // no-warning |
27 | } |
28 | |
29 | extern inline int useStaticInlineFromExtern () { |
30 | // Heuristic: if the function we're using is also inline, don't warn. |
31 | // This can still be wrong (in this case, we end up inlining calls to |
32 | // staticFunction and staticVar) but this got very noisy even using |
33 | // standard headers. |
34 | return useStaticFromStatic(); // no-warning |
35 | } |
36 | |
37 | static int constFunction() __attribute__((const)); |
38 | |
39 | inline int useConst () { |
40 | return constFunction(); // no-warning |
41 | } |
42 | |
43 | #else |
44 | // ------- |
45 | // This is the main source file. |
46 | // ------- |
47 | |
48 | #define INCLUDE |
49 | #include "inline.c" |
50 | |
51 | // Check that we don't allow illegal uses of inline |
52 | inline int a; // expected-error{{'inline' can only appear on functions}} |
53 | typedef inline int b; // expected-error{{'inline' can only appear on functions}} |
54 | int d(inline int a); // expected-error{{'inline' can only appear on functions}} |
55 | |
56 | // Check that the warnings from the "header file" aren't on by default in |
57 | // the main source file. |
58 | |
59 | inline int useStaticMainFile () { |
60 | staticFunction(); // no-warning |
61 | return staticVar; // no-warning |
62 | } |
63 | |
64 | // Check that the warnings show up when explicitly requested. |
65 | |
66 | #pragma clang diagnostic push |
67 | #pragma clang diagnostic warning "-Wstatic-in-inline" |
68 | |
69 | inline int useStaticAgain () { // expected-note 2 {{use 'static' to give inline function 'useStaticAgain' internal linkage}} |
70 | staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} |
71 | return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} |
72 | } |
73 | |
74 | #pragma clang diagnostic pop |
75 | |
76 | inline void defineStaticVar() { // expected-note {{use 'static' to give inline function 'defineStaticVar' internal linkage}} |
77 | static const int x = 0; // ok |
78 | static int y = 0; // expected-warning {{non-constant static local variable in inline function may be different in different files}} |
79 | } |
80 | |
81 | extern inline void defineStaticVarInExtern() { |
82 | static const int x = 0; // ok |
83 | static int y = 0; // ok |
84 | } |
85 | |
86 | // Check behavior of line markers. |
87 | # 1 "XXX.h" 1 |
88 | inline int useStaticMainFileInLineMarker() { // expected-note 2 {{use 'static' to give inline function 'useStaticMainFileInLineMarker' internal linkage}} |
89 | staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} |
90 | return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} |
91 | } |
92 | # 100 "inline.c" 2 |
93 | |
94 | inline int useStaticMainFileAfterLineMarker() { |
95 | staticFunction(); // no-warning |
96 | return staticVar; // no-warning |
97 | } |
98 | |
99 | #endif |
100 | |
101 | |
102 | |