xref: /llvm-project/clang/test/SemaCXX/inline.cpp (revision 28cd12f26533cf7ab6e21c20aaebe153c6a53ccf)
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 const int constVar = 0; // no-warning
12 
13 namespace {
14   int anonVar; // expected-note + {{'anonVar' declared here}}
15   int anonFunction(); // expected-note + {{'anonFunction' declared here}}
16   const int anonConstVar = 0; // no-warning
17 
18   class Anon {
19   public:
20     static int var; // expected-note + {{'var' declared here}}
21     static const int constVar = 0; // no-warning
22   };
23 }
24 
25 inline void useStatic() { // expected-note + {{use 'static' to give inline function 'useStatic' internal linkage}}
26   staticFunction(); // expected-warning{{function 'staticFunction' has internal linkage but is used in an inline function with external linkage}}
27   (void)staticVar; // expected-warning{{variable 'staticVar' has internal linkage but is used in an inline function with external linkage}}
28   anonFunction(); // expected-warning{{function 'anonFunction' is in an anonymous namespace but is used in an inline function with external linkage}}
29   (void)anonVar; // expected-warning{{variable 'anonVar' is in an anonymous namespace but is used in an inline function with external linkage}}
30   (void)Anon::var; // expected-warning{{variable 'var' is in an anonymous namespace but is used in an inline function with external linkage}}
31 
32   (void)constVar; // no-warning
33   (void)anonConstVar; // no-warning
34   (void)Anon::constVar; // no-warning
35 }
36 
37 extern inline int useStaticFromExtern() { // no suggestions
38   staticFunction(); // expected-warning{{function 'staticFunction' has internal linkage but is used in an inline function with external linkage}}
39   return staticVar; // expected-warning{{variable 'staticVar' has internal linkage but is used in an inline function with external linkage}}
40 }
41 
42 class A {
43 public:
44   static inline int useInClass() { // no suggestions
45     return staticFunction(); // expected-warning{{function 'staticFunction' has internal linkage but is used in an inline method with external linkage}}
46   }
47   inline int useInInstance() { // no suggestions
48     return staticFunction(); // expected-warning{{function 'staticFunction' has internal linkage but is used in an inline method with external linkage}}
49   }
50 };
51 
52 static inline void useStaticFromStatic () {
53   // No warnings.
54   staticFunction();
55   (void)staticVar;
56   (void)constVar;
57   anonFunction();
58   (void)anonVar;
59   (void)anonConstVar;
60   (void)Anon::var;
61   (void)Anon::constVar;
62 }
63 
64 namespace {
65   inline void useStaticFromAnon() {
66     // No warnings.
67     staticFunction();
68     (void)staticVar;
69     (void)constVar;
70     anonFunction();
71     (void)anonVar;
72     (void)anonConstVar;
73     (void)Anon::var;
74     (void)Anon::constVar;
75   }
76 }
77 
78 #else
79 // -------
80 // This is the main source file.
81 // -------
82 
83 #define INCLUDE
84 #include "inline.cpp"
85 
86 // Check that we don't allow illegal uses of inline
87 // (checking C++-only constructs here)
88 struct c {inline int a;}; // expected-error{{'inline' can only appear on functions}}
89 
90 // Check that the warnings from the "header file" aren't on by default in
91 // the main source file.
92 
93 inline int useStaticMainFile () {
94   anonFunction(); // no-warning
95   return staticVar; // no-warning
96 }
97 
98 // Check that the warnings show up when explicitly requested.
99 
100 #pragma clang diagnostic push
101 #pragma clang diagnostic warning "-Winternal-linkage-in-inline"
102 
103 inline int useStaticAgain () { // expected-note 2 {{use 'static' to give inline function 'useStaticAgain' internal linkage}}
104   anonFunction(); // expected-warning{{function 'anonFunction' is in an anonymous namespace but is used in an inline function with external linkage}}
105   return staticVar; // expected-warning{{variable 'staticVar' has internal linkage but is used in an inline function with external linkage}}
106 }
107 
108 #pragma clang diagnostic pop
109 
110 #endif
111