1 // RUN: %clang_cc1 -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 #endif 87 88 89