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