1- /*
2- REQUIRED_ARGS: -betterC
3- */
1+ // PERMUTE_ARGS:
2+
3+ extern (C ) int printf(const char * , ... );
4+
5+ class Foo : Object
6+ {
7+ void test () { }
8+
9+ invariant ()
10+ {
11+ printf(" in invariant %p\n " , this );
12+ }
13+ }
14+
15+ int testinvariant ()
16+ {
17+ printf(" hello\n " );
18+ Foo f = new Foo ();
19+ printf(" f = %p\n " , f);
20+ printf(" f.sizeof = x%zx\n " , Foo .sizeof);
21+ printf(" f.classinfo = %p\n " , f.classinfo);
22+ printf(" f.classinfo._invariant = %p\n " , f.classinfo.base);
23+ f.test();
24+ printf(" world\n " );
25+ return 0 ;
26+ }
27+
28+ /* **************************************************/
29+ // https://issues.dlang.org/show_bug.cgi?id=6453
30+
31+ void test6453 ()
32+ {
33+ static class C
34+ {
35+ static uint called;
36+ invariant () { called += 1 ; }
37+ invariant () { called += 4 ; }
38+ invariant () { called += 16 ; }
39+
40+ void publicMember () { assert (called == 21 ); }
41+ }
42+
43+ static struct S
44+ {
45+ static uint called;
46+ invariant () { called += 1 ; }
47+ invariant () { called += 4 ; }
48+ invariant () { called += 16 ; }
49+
50+ void publicMember () { assert (called == 21 ); }
51+ }
52+
53+ auto c = new C();
54+ C.called = 0 ;
55+ c.publicMember();
56+ assert (C.called == 42 );
57+
58+ auto s = new S();
59+ S.called = 0 ;
60+ s.publicMember();
61+ assert (S.called == 42 );
62+
63+ // Defined symbols in one invariant cannot be seen from others.
64+ static struct S6453
65+ {
66+ invariant ()
67+ {
68+ struct S {}
69+ int x;
70+ static assert (! __traits(compiles, y));
71+ static assert (! __traits(compiles, z));
72+ }
73+ invariant ()
74+ {
75+ struct S {}
76+ int y;
77+ static assert (! __traits(compiles, x));
78+ static assert (! __traits(compiles, z));
79+ }
80+ invariant ()
81+ {
82+ struct S {}
83+ int z;
84+ static assert (! __traits(compiles, x));
85+ static assert (! __traits(compiles, y));
86+ }
87+ }
88+
89+ static struct S6453a
90+ {
91+ pure invariant () {}
92+ nothrow invariant () {}
93+ @safe invariant () {}
94+ }
95+ static struct S6453b
96+ {
97+ pure shared invariant () {}
98+ nothrow shared invariant () {}
99+ @safe shared invariant () {}
100+ }
101+ static class C6453c
102+ {
103+ pure synchronized invariant () {}
104+ nothrow synchronized invariant () {}
105+ @safe synchronized invariant () {}
106+ }
107+ }
108+
109+ /* **************************************************/
110+ // https://issues.dlang.org/show_bug.cgi?id=13113
111+
112+ struct S13113
113+ {
114+ static int count;
115+ invariant () // impure, throwable, system, and gc-able
116+ {
117+ ++ count; // impure
118+ }
119+
120+ this (int ) pure nothrow @safe @nogc {}
121+ // post invaiant is called directly but doesn't interfere with constructor attributes
122+
123+ ~this () pure nothrow @safe @nogc {}
124+ // pre invaiant is called directly but doesn't interfere with destructor attributes
125+
126+ void foo () pure nothrow @safe @nogc {}
127+ // pre & post invariant calls don't interfere with method attributes
128+ }
129+
130+ void test13113 ()
131+ {
132+ assert (S13113 .count == 0 );
133+ {
134+ auto s = S13113 (1 );
135+ assert (S13113 .count == 1 );
136+ s.foo();
137+ assert (S13113 .count == 3 );
138+ }
139+ assert (S13113 .count == 4 );
140+ }
141+
142+ /* **************************************************/
143+ // https://issues.dlang.org/show_bug.cgi?id=13147
144+
145+ version (D_InlineAsm_X86 )
146+ enum x86iasm = true ;
147+ else version (D_InlineAsm_X86_64 )
148+ enum x86iasm = true ;
149+ else
150+ enum x86iasm = false ;
151+
152+ class C13147
153+ {
154+ extern (C++ ) C13147 test()
155+ {
156+ static if (x86iasm)
157+ asm { naked; ret; }
158+ return this ;
159+ }
160+ }
161+
162+ struct S13147
163+ {
164+ void test ()
165+ {
166+ static if (x86iasm)
167+ asm { naked; ret; }
168+ }
169+ }
170+
171+ void test13147 ()
172+ {
173+ auto c = new C13147 ();
174+ c.test();
175+ S13147 s;
176+ s.test();
177+ }
178+
179+ /* **************************************************/
180+ // https://issues.dlang.org/show_bug.cgi?id=16384
181+
182+ struct S (T)
183+ {
184+ T x = 5 ;
185+ invariant { assert (x == 6 ); }
186+ invariant { assert (x > 0 ); }
187+
188+ void foo () {}
189+ }
190+
191+ void f (int i) pure { assert ( i == 6 ); }
192+
193+ struct S2 (T)
194+ {
195+ T x = 5 ;
196+ invariant { f(x); }
197+ invariant { assert (x > 0 ); }
198+
199+ void foo () {}
200+ }
201+
202+ void test16384 ()
203+ {
204+ string s;
205+ S! int y;
206+ try
207+ {
208+ y.foo();
209+ }
210+ catch (Error)
211+ {
212+ s = " needs to be thrown" ;
213+ }
214+
215+ assert (s == " needs to be thrown" );
216+
217+ S2 ! int y2;
218+
219+ try
220+ {
221+ y2.foo();
222+ }
223+ catch (Error)
224+ {
225+ s = " needs to be thrown2" ;
226+ }
227+
228+ assert (s == " needs to be thrown2" );
229+ }
230+
231+ /* **************************************************/
4232// Fix: https://github.com/dlang/dmd/issues/20924 (invariant not called on extern(C++) classes)
5233
6234extern (C++ ) class C
@@ -15,15 +243,15 @@ extern(D) class D
15243 void f () {}
16244}
17245
18- // This function runs tests on extern(C++) class
19- void testCppClass ()
246+ void test20924 ()
20247{
21248 import core.exception : AssertError ;
22249
250+ // Test extern(C++) class invariant
23251 try
24252 {
25253 auto c = new C();
26- c.f(); // Should trigger invariant
254+ c.f(); // Trigger invariant
27255 assert (false , " Failed: invariant in extern(C++) class not checked" );
28256 }
29257 catch (AssertError e)
@@ -32,17 +260,12 @@ void testCppClass()
32260 return ;
33261 }
34262 assert (0 , " Invariant in extern(C++) class was not checked" );
35- }
36263
37- // Runs tests on extern(D) class for comparison
38- void testDClass ()
39- {
40- import core.exception : AssertError ;
41-
264+ // Test extern(D) class invariant
42265 try
43266 {
44267 auto d = new D();
45- d.f(); // Should trigger invariant
268+ d.f(); // Trigger invariant
46269 assert (false , " Failed: invariant in extern(D) class not checked" );
47270 }
48271 catch (AssertError e)
@@ -55,9 +278,10 @@ void testDClass()
55278
56279void main ()
57280{
58- // Test both class types
59- testDClass();
60- testCppClass();
61- }
62-
63-
281+ testinvariant();
282+ test6453();
283+ test16384();
284+ test13113();
285+ test13147();
286+ test20924();
287+ }
0 commit comments