inline.c 3.9 KB

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