| // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s |
| |
| #if defined(INCLUDE) |
| // ------- |
| // This section acts like a header file. |
| // ------- |
| |
| // Check the use of static variables in non-static inline functions. |
| static int staticVar; // expected-note + {{'staticVar' declared here}} |
| static int staticFunction(); // expected-note + {{'staticFunction' declared here}} |
| static struct { int x; } staticStruct; // expected-note + {{'staticStruct' declared here}} |
| |
| inline int useStatic () { // expected-note 3 {{use 'static' to give inline function 'useStatic' internal linkage}} |
| staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} |
| (void)staticStruct.x; // expected-warning{{static variable 'staticStruct' is used in an inline function with external linkage}} |
| return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} |
| } |
| |
| extern inline int useStaticFromExtern () { // no suggestions |
| staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} |
| return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} |
| } |
| |
| static inline int useStaticFromStatic () { |
| staticFunction(); // no-warning |
| return staticVar; // no-warning |
| } |
| |
| extern inline int useStaticInlineFromExtern () { |
| // Heuristic: if the function we're using is also inline, don't warn. |
| // This can still be wrong (in this case, we end up inlining calls to |
| // staticFunction and staticVar) but this got very noisy even using |
| // standard headers. |
| return useStaticFromStatic(); // no-warning |
| } |
| |
| static int constFunction() __attribute__((const)); |
| |
| inline int useConst () { |
| return constFunction(); // no-warning |
| } |
| |
| #else |
| // ------- |
| // This is the main source file. |
| // ------- |
| |
| #define INCLUDE |
| #include "inline.c" |
| |
| // Check that we don't allow illegal uses of inline |
| inline int a; // expected-error{{'inline' can only appear on functions}} |
| typedef inline int b; // expected-error{{'inline' can only appear on functions}} |
| int d(inline int a); // expected-error{{'inline' can only appear on functions}} |
| |
| // Check that the warnings from the "header file" aren't on by default in |
| // the main source file. |
| |
| inline int useStaticMainFile () { |
| staticFunction(); // no-warning |
| return staticVar; // no-warning |
| } |
| |
| // Check that the warnings show up when explicitly requested. |
| |
| #pragma clang diagnostic push |
| #pragma clang diagnostic warning "-Wstatic-in-inline" |
| |
| inline int useStaticAgain () { // expected-note 2 {{use 'static' to give inline function 'useStaticAgain' internal linkage}} |
| staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} |
| return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} |
| } |
| |
| #pragma clang diagnostic pop |
| |
| inline void defineStaticVar() { // expected-note {{use 'static' to give inline function 'defineStaticVar' internal linkage}} |
| static const int x = 0; // ok |
| static int y = 0; // expected-warning {{non-constant static local variable in inline function may be different in different files}} |
| } |
| |
| extern inline void defineStaticVarInExtern() { |
| static const int x = 0; // ok |
| static int y = 0; // ok |
| } |
| |
| // Check behavior of line markers. |
| # 1 "XXX.h" 1 |
| inline int useStaticMainFileInLineMarker() { // expected-note 2 {{use 'static' to give inline function 'useStaticMainFileInLineMarker' internal linkage}} |
| staticFunction(); // expected-warning{{static function 'staticFunction' is used in an inline function with external linkage}} |
| return staticVar; // expected-warning{{static variable 'staticVar' is used in an inline function with external linkage}} |
| } |
| # 100 "inline.c" 2 |
| |
| inline int useStaticMainFileAfterLineMarker() { |
| staticFunction(); // no-warning |
| return staticVar; // no-warning |
| } |
| |
| #endif |
| |
| |