1 // RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify -std=c++17 %s
2 
3 // Variable declarations that should trigger a warning.
4 int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}
5 int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}}
6 
7 namespace x {
8   int vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}}
9 }
10 
11 // Variable declarations that should not trigger a warning.
12 static int vgood1;
13 extern int vgood2;
14 int vgood2;
15 static struct {
16   int mgood1;
17 } vgood3;
18 
19 // Functions should never trigger a warning.
20 void fgood1(void);
fgood2(void)21 void fgood2(void) {
22   int lgood1;
23   static int lgood2;
24 }
fgood3(void)25 static void fgood3(void) {
26   int lgood3;
27   static int lgood4;
28 }
29 
30 // Structures, namespaces and classes should be unaffected.
31 struct sgood1 {
32   int mgood2;
33 };
34 struct {
35   int mgood3;
36 } sgood2;
37 class CGood1 {
38   static int MGood1;
39 };
40 int CGood1::MGood1;
41 namespace {
42   int mgood4;
43 }
44 
45 class C {
test()46   void test() {
47     static int x = 0; // no-warn
48   }
49 };
50 
51 // There is also no need to use static in anonymous namespaces.
52 namespace {
53   int vgood4;
54 }
55 
56 inline int inline_var = 0;
57 const int const_var = 0;
58 constexpr int constexpr_var = 0;
59 inline constexpr int inline_constexpr_var = 0;
60 extern const int extern_const_var = 0; // expected-warning {{no previous extern declaration}}
61 extern constexpr int extern_constexpr_var = 0; // expected-warning {{no previous extern declaration}}
62 
63 template<typename> int var_template = 0;
64 template<typename> constexpr int const_var_template = 0;
65 template<typename> static int static_var_template = 0;
66 
67 template int var_template<int[1]>;
use_var_template()68 int use_var_template() { return var_template<int[2]>; }
69 template int var_template<int[3]>;
70 extern template int var_template<int[4]>;
71 template<> int var_template<int[5]>; // expected-warning {{no previous extern declaration}}
72 
73 // FIXME: We give this specialization internal linkage rather than inheriting
74 // the linkage from the template! We should not warn here.
75 template<> int static_var_template<int[5]>; // expected-warning {{no previous extern declaration}}
76