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