xref: /minix3/external/bsd/llvm/dist/clang/test/Sema/inline.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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 Sambuc inline 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 Sambuc extern 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 Sambuc static 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 Sambuc extern 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 Sambuc inline 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 Sambuc inline 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 Sambuc inline 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 Sambuc inline 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 Sambuc extern 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 Sambuc inline 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 Sambuc inline 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