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