xref: /llvm-project/clang/test/SemaCXX/warn-global-constructors.cpp (revision dd6a58babc853d180b9a7e5bd709ae12477da004)
1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wglobal-constructors %s -verify=expected,cxx11
2 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -Wglobal-constructors %s -verify=expected
3 
4 int opaque_int();
5 
6 namespace test0 {
7   // These should never require global constructors.
8   int a;
9   int b = 20;
10   float c = 5.0f;
11 
12   // This global constructor is avoidable based on initialization order.
13   int d = b; // expected-warning {{global constructor}}
14 
15   // These global constructors are unavoidable.
16   int e = opaque_int(); // expected-warning {{global constructor}}
17   int f = b; // expected-warning {{global constructor}}
18 }
19 
20 namespace test1 {
21   struct A { int x; };
22   A a;
23   A b = A();
24   A c = { 10 };
25   A d = { opaque_int() }; // expected-warning {{global constructor}}
26   A e = A(A());
27   A f = A(a); // expected-warning {{global constructor}}
28   A g(a); // expected-warning {{global constructor}}
29   A h((A()));  // elided
30   A i((A(A()))); // elided
31 }
32 
33 namespace test2 {
34   struct A { A(); };
35   A a; // expected-warning {{global constructor}}
36   A b[10]; // expected-warning {{global constructor}}
37   A c[10][10]; // expected-warning {{global constructor}}
38 
39   A &d = a;
40   A &e = b[5];
41   A &f = c[5][7];
42 }
43 
44 namespace test3 {
45   struct A { ~A(); };
46   A a; // expected-warning {{global destructor}}
47   A b[10]; // expected-warning {{global destructor}}
48   A c[10][10]; // expected-warning {{global destructor}}
49 
50   A &d = a;
51   A &e = b[5];
52   A &f = c[5][7];
53 }
54 
55 namespace test4 {
56   char a[] = "hello";
57   char b[6] = "hello";
58   char c[][6] = { "hello" };
59 }
60 
61 namespace test5 {
62   struct A { A(); };
63 
f1()64   void f1() {
65     static A a;
66   }
f2()67   void f2() {
68     static A& a = *new A;
69   }
70 }
71 
72 namespace test6 {
73   struct A { ~A(); };
74 
f1()75   void f1() {
76     static A a;
77   }
f2()78   void f2() {
79     static A& a = *new A;
80   }
81 }
82 
83 namespace pr8095 {
84   struct Foo {
85     int x;
Foopr8095::Foo86     Foo(int x1) : x(x1) {}
87   };
foo()88   void foo() {
89     static Foo a(0);
90   }
91 
92   struct Bar {
93     ~Bar();
94   };
bar()95   void bar() {
96     static Bar b;
97   }
98 }
99 
100 namespace referencemember {
101   struct A { int &a; };
102   int a;
103   A b = { a };
104 }
105 
106 namespace pr19253 {
107   struct A { ~A() = default; };
108   A a;
109 
110   struct B { ~B(); };
111   struct C : B { ~C() = default; };
112   C c; // expected-warning {{global destructor}}
113 
114   class D {
115     friend struct E;
116     ~D() = default;
117   };
118   struct E : D {
119     D d;
120     ~E() = default;
121   };
122   E e;
123 }
124 
125 namespace pr20420 {
126 // No warning is expected. This used to crash.
127 void *array_storage[1];
128 const int &global_reference = *(int *)array_storage;
129 }
130 
131 namespace bitfields {
132   struct HasUnnamedBitfield {
133     unsigned a;
134     unsigned : 20;
135     unsigned b;
136 
HasUnnamedBitfieldbitfields::HasUnnamedBitfield137     constexpr HasUnnamedBitfield() : a(), b() {}
HasUnnamedBitfieldbitfields::HasUnnamedBitfield138     constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {}
HasUnnamedBitfieldbitfields::HasUnnamedBitfield139     explicit HasUnnamedBitfield(unsigned a) {}
140   };
141 
142   const HasUnnamedBitfield zeroConst{};
143   HasUnnamedBitfield zeroMutable{};
144   const HasUnnamedBitfield explicitConst{1, 2};
145   HasUnnamedBitfield explicitMutable{1, 2};
146   const HasUnnamedBitfield nonConstexprConst{1}; // expected-warning {{global constructor}}
147   HasUnnamedBitfield nonConstexprMutable{1}; // expected-warning {{global constructor}}
148 }
149 
150 namespace test7 {
151 #if __cplusplus >= 202002L
152 #define CPP20_CONSTEXPR constexpr
153 #else
154 #define CPP20_CONSTEXPR
155 #endif
156   struct S {
~Stest7::S157     CPP20_CONSTEXPR ~S() {}
158   };
159   S s; // cxx11-warning {{global destructor}}
160 
161   struct T {
~Ttest7::T162     CPP20_CONSTEXPR ~T() { if (b) {} }
163     bool b;
164   };
165   T t; // expected-warning {{global destructor}}
166 #undef CPP20_CONSTEXPR
167 }
168