Home | History | Annotate | Download | only in Sema
      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