152
|
1 // PERMUTE_ARGS: -g
|
|
2 // EXTRA_CPP_SOURCES: cppb.cpp
|
|
3
|
|
4 import core.stdc.stdio;
|
|
5 import core.stdc.stdarg;
|
|
6 import core.stdc.config;
|
|
7
|
|
8 extern (C++)
|
|
9 int foob(int i, int j, int k);
|
|
10
|
|
11 class C
|
|
12 {
|
|
13 extern (C++) int bar(int i, int j, int k)
|
|
14 {
|
|
15 printf("this = %p\n", this);
|
|
16 printf("i = %d\n", i);
|
|
17 printf("j = %d\n", j);
|
|
18 printf("k = %d\n", k);
|
|
19 return 1;
|
|
20 }
|
|
21 }
|
|
22
|
|
23
|
|
24 extern (C++)
|
|
25 int foo(int i, int j, int k)
|
|
26 {
|
|
27 printf("i = %d\n", i);
|
|
28 printf("j = %d\n", j);
|
|
29 printf("k = %d\n", k);
|
|
30 assert(i == 1);
|
|
31 assert(j == 2);
|
|
32 assert(k == 3);
|
|
33 return 1;
|
|
34 }
|
|
35
|
|
36 void test1()
|
|
37 {
|
|
38 foo(1, 2, 3);
|
|
39
|
|
40 auto i = foob(1, 2, 3);
|
|
41 assert(i == 7);
|
|
42
|
|
43 C c = new C();
|
|
44 c.bar(4, 5, 6);
|
|
45 }
|
|
46
|
|
47 /****************************************/
|
|
48
|
|
49 extern (C++) interface D
|
|
50 {
|
|
51 int bar(int i, int j, int k);
|
|
52 }
|
|
53
|
|
54 extern (C++) D getD();
|
|
55
|
|
56 void test2()
|
|
57 {
|
|
58 D d = getD();
|
|
59 int i = d.bar(9,10,11);
|
|
60 assert(i == 8);
|
|
61 }
|
|
62
|
|
63 /****************************************/
|
|
64
|
|
65 extern (C++) int callE(E);
|
|
66
|
|
67 extern (C++) interface E
|
|
68 {
|
|
69 int bar(int i, int j, int k);
|
|
70 }
|
|
71
|
|
72 class F : E
|
|
73 {
|
|
74 extern (C++) int bar(int i, int j, int k)
|
|
75 {
|
|
76 printf("F.bar: i = %d\n", i);
|
|
77 printf("F.bar: j = %d\n", j);
|
|
78 printf("F.bar: k = %d\n", k);
|
|
79 assert(i == 11);
|
|
80 assert(j == 12);
|
|
81 assert(k == 13);
|
|
82 return 8;
|
|
83 }
|
|
84 }
|
|
85
|
|
86 void test3()
|
|
87 {
|
|
88 F f = new F();
|
|
89 int i = callE(f);
|
|
90 assert(i == 8);
|
|
91 }
|
|
92
|
|
93 /****************************************/
|
|
94
|
|
95 extern (C++) void foo4(char* p);
|
|
96
|
|
97 void test4()
|
|
98 {
|
|
99 foo4(null);
|
|
100 }
|
|
101
|
|
102 /****************************************/
|
|
103
|
|
104 extern(C++)
|
|
105 {
|
|
106 struct foo5 { int i; int j; void* p; }
|
|
107
|
|
108 interface bar5{
|
|
109 foo5 getFoo(int i);
|
|
110 }
|
|
111
|
|
112 bar5 newBar();
|
|
113 }
|
|
114
|
|
115 void test5()
|
|
116 {
|
|
117 bar5 b = newBar();
|
|
118 foo5 f = b.getFoo(4);
|
|
119 printf("f.p = %p, b = %p\n", f.p, cast(void*)b);
|
|
120 assert(f.p == cast(void*)b);
|
|
121 }
|
|
122
|
|
123
|
|
124 /****************************************/
|
|
125
|
|
126 extern(C++)
|
|
127 {
|
|
128 struct S6
|
|
129 {
|
|
130 int i;
|
|
131 double d;
|
|
132 }
|
|
133
|
|
134 union S6_2
|
|
135 {
|
|
136 int i;
|
|
137 double d;
|
|
138 }
|
|
139
|
|
140 enum S6_3
|
|
141 {
|
|
142 A, B
|
|
143 }
|
|
144
|
|
145 S6 foo6();
|
|
146 S6_2 foo6_2();
|
|
147 S6_3 foo6_3();
|
|
148 }
|
|
149
|
|
150 extern (C) int foosize6();
|
|
151
|
|
152 void test6()
|
|
153 {
|
|
154 S6 f = foo6();
|
|
155 printf("%d %d\n", foosize6(), S6.sizeof);
|
|
156 assert(foosize6() == S6.sizeof);
|
|
157 version (X86)
|
|
158 {
|
|
159 assert(f.i == 42);
|
|
160 printf("f.d = %g\n", f.d);
|
|
161 assert(f.d == 2.5);
|
|
162 assert(foo6_2().i == 42);
|
|
163 assert(foo6_3() == S6_3.A);
|
|
164 }
|
|
165 }
|
|
166
|
|
167 /****************************************/
|
|
168
|
|
169 extern (C) int foo7();
|
|
170
|
|
171 struct S
|
|
172 {
|
|
173 int i;
|
|
174 long l;
|
|
175 }
|
|
176
|
|
177 void test7()
|
|
178 {
|
|
179 printf("%d %d\n", foo7(), S.sizeof);
|
|
180 assert(foo7() == S.sizeof);
|
|
181 }
|
|
182
|
|
183 /****************************************/
|
|
184
|
|
185 extern (C++) void foo8(const(char)*);
|
|
186
|
|
187 void test8()
|
|
188 {
|
|
189 char c;
|
|
190 foo8(&c);
|
|
191 }
|
|
192
|
|
193 /****************************************/
|
|
194 // 4059
|
|
195
|
|
196 struct elem9 { }
|
|
197
|
|
198 extern(C++) void foobar9(elem9*, elem9*);
|
|
199
|
|
200 void test9()
|
|
201 {
|
|
202 elem9 *a;
|
|
203 foobar9(a, a);
|
|
204 }
|
|
205
|
|
206 /****************************************/
|
|
207
|
|
208
|
|
209 struct A11802;
|
|
210 struct B11802;
|
|
211
|
|
212 extern(C++) class C11802
|
|
213 {
|
|
214 int x;
|
|
215 void fun(A11802*) { x += 2; }
|
|
216 void fun(B11802*) { x *= 2; }
|
|
217 }
|
|
218
|
|
219 extern(C++) class D11802 : C11802
|
|
220 {
|
|
221 override void fun(A11802*) { x += 3; }
|
|
222 override void fun(B11802*) { x *= 3; }
|
|
223 }
|
|
224
|
|
225 extern(C++) void test11802x(D11802);
|
|
226
|
|
227 void test11802()
|
|
228 {
|
|
229 auto x = new D11802();
|
|
230 x.x = 0;
|
|
231 test11802x(x);
|
|
232 assert(x.x == 9);
|
|
233 }
|
|
234
|
|
235
|
|
236 /****************************************/
|
|
237
|
|
238 struct S13956
|
|
239 {
|
|
240 }
|
|
241
|
|
242 extern(C++) void func13956(S13956 arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);
|
|
243
|
|
244 extern(C++) void check13956(S13956 arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
|
|
245 {
|
|
246 assert(arg0 == S13956());
|
|
247 assert(arg1 == 1);
|
|
248 assert(arg2 == 2);
|
|
249 assert(arg3 == 3);
|
|
250 assert(arg4 == 4);
|
|
251 assert(arg5 == 5);
|
|
252 version (OSX)
|
|
253 {
|
|
254 version (D_LP64)
|
|
255 assert(arg6 == 6);
|
|
256 // fails on OSX 32-bit
|
|
257 }
|
|
258 else
|
|
259 assert(arg6 == 6);
|
|
260 }
|
|
261
|
|
262 void test13956()
|
|
263 {
|
|
264 func13956(S13956(), 1, 2, 3, 4, 5, 6);
|
|
265 }
|
|
266
|
|
267 /****************************************/
|
|
268 // 5148
|
|
269
|
|
270 extern (C++)
|
|
271 {
|
|
272 void foo10(const(char)*, const(char)*);
|
|
273 void foo10(const int, const int);
|
|
274 void foo10(const char, const char);
|
|
275 void foo10(bool, bool);
|
|
276
|
|
277 struct MyStructType { }
|
|
278 void foo10(const MyStructType s, const MyStructType t);
|
|
279
|
|
280 enum MyEnumType { onemember }
|
|
281 void foo10(const MyEnumType s, const MyEnumType t);
|
|
282 }
|
|
283
|
|
284 void test10()
|
|
285 {
|
|
286 char* p;
|
|
287 foo10(p, p);
|
|
288 foo10(1,2);
|
|
289 foo10('c','d');
|
|
290 MyStructType s;
|
|
291 foo10(s,s);
|
|
292 MyEnumType e;
|
|
293 foo10(e,e);
|
|
294 }
|
|
295
|
|
296 /****************************************/
|
|
297
|
|
298 extern (C++, N11.M) { void bar11(); }
|
|
299
|
|
300 extern (C++, A11.B) { extern (C++, C) { void bar(); }}
|
|
301
|
|
302 void test11()
|
|
303 {
|
|
304 bar11();
|
|
305 A11.B.C.bar();
|
|
306 }
|
|
307 /****************************************/
|
|
308
|
|
309 struct Struct10071
|
|
310 {
|
|
311 void *p;
|
|
312 c_long_double r;
|
|
313 }
|
|
314
|
|
315 extern(C++) size_t offset10071();
|
|
316 void test10071()
|
|
317 {
|
|
318 assert(offset10071() == Struct10071.r.offsetof);
|
|
319 }
|
|
320
|
|
321 /****************************************/
|
|
322
|
|
323 char[100] valistbuffer;
|
|
324
|
|
325 extern(C++) void myvprintfx(const(char)* format, va_list va)
|
|
326 {
|
|
327 vsprintf(valistbuffer.ptr, format, va);
|
|
328 }
|
|
329 extern(C++) void myvprintf(const(char)*, va_list);
|
|
330 extern(C++) void myprintf(const(char)* format, ...)
|
|
331 {
|
|
332 va_list ap;
|
|
333 va_start(ap, format);
|
|
334 myvprintf(format, ap);
|
|
335 va_end(ap);
|
|
336 }
|
|
337
|
|
338 void testvalist()
|
|
339 {
|
|
340 myprintf("hello %d", 999);
|
|
341 assert(valistbuffer[0..9] == "hello 999");
|
|
342 }
|
|
343
|
|
344 /****************************************/
|
|
345 // 12825
|
|
346
|
|
347 extern(C++) class C12825
|
|
348 {
|
|
349 uint a = 0x12345678;
|
|
350 }
|
|
351
|
|
352 void test12825()
|
|
353 {
|
|
354 auto c = new C12825();
|
|
355 }
|
|
356
|
|
357 /****************************************/
|
|
358
|
|
359 struct S13955a
|
|
360 {
|
|
361 float a;
|
|
362 double b;
|
|
363 }
|
|
364
|
|
365 struct S13955b
|
|
366 {
|
|
367 double a;
|
|
368 float b;
|
|
369 }
|
|
370
|
|
371 struct S13955c
|
|
372 {
|
|
373 float a;
|
|
374 float b;
|
|
375 }
|
|
376
|
|
377 struct S13955d
|
|
378 {
|
|
379 double a;
|
|
380 double b;
|
|
381 }
|
|
382
|
|
383 extern(C++) void check13955(S13955a a, S13955b b, S13955c c, S13955d d)
|
|
384 {
|
|
385 assert(a.a == 2);
|
|
386 assert(a.b == 4);
|
|
387 assert(b.a == 8);
|
|
388 assert(b.b == 16);
|
|
389 assert(c.a == 32);
|
|
390 assert(c.b == 64);
|
|
391 assert(d.a == 128);
|
|
392 assert(d.b == 256);
|
|
393 }
|
|
394
|
|
395 extern(C++) void func13955(S13955a a, S13955b b, S13955c c, S13955d d);
|
|
396
|
|
397 void test13955()
|
|
398 {
|
|
399 func13955(S13955a(2, 4), S13955b(8, 16), S13955c(32, 64), S13955d(128, 256));
|
|
400 }
|
|
401
|
|
402 /****************************************/
|
|
403
|
|
404 extern(C++) class C13161
|
|
405 {
|
|
406 void dummyfunc();
|
|
407 long val_5;
|
|
408 uint val_9;
|
|
409 }
|
|
410
|
|
411 extern(C++) class Test : C13161
|
|
412 {
|
|
413 uint val_0;
|
|
414 long val_1;
|
|
415 }
|
|
416
|
|
417 extern(C++) size_t getoffset13161();
|
|
418
|
|
419 extern(C++) class C13161a
|
|
420 {
|
|
421 void dummyfunc();
|
|
422 c_long_double val_5;
|
|
423 uint val_9;
|
|
424 }
|
|
425
|
|
426 extern(C++) class Testa : C13161a
|
|
427 {
|
|
428 bool val_0;
|
|
429 }
|
|
430
|
|
431 extern(C++) size_t getoffset13161a();
|
|
432
|
|
433 void test13161()
|
|
434 {
|
|
435 assert(getoffset13161() == Test.val_0.offsetof);
|
|
436 assert(getoffset13161a() == Testa.val_0.offsetof);
|
|
437 }
|
|
438
|
|
439 /****************************************/
|
|
440
|
|
441 version (linux)
|
|
442 {
|
|
443 extern(C++, __gnu_cxx)
|
|
444 {
|
|
445 struct new_allocator(T)
|
|
446 {
|
|
447 alias size_type = size_t;
|
|
448 static if (is(T : char))
|
|
449 void deallocate(T*, size_type) { }
|
|
450 else
|
|
451 void deallocate(T*, size_type);
|
|
452 }
|
|
453 }
|
|
454 }
|
|
455
|
|
456 extern (C++, std)
|
|
457 {
|
|
458 struct allocator(T)
|
|
459 {
|
|
460 version (linux)
|
|
461 {
|
|
462 alias size_type = size_t;
|
|
463 void deallocate(T* p, size_type sz)
|
|
464 { (cast(__gnu_cxx.new_allocator!T*)&this).deallocate(p, sz); }
|
|
465 }
|
|
466 }
|
|
467
|
|
468 version (linux)
|
|
469 {
|
|
470 class vector(T, A = allocator!T)
|
|
471 {
|
|
472 final void push_back(ref const T);
|
|
473 }
|
|
474
|
|
475 struct char_traits(T)
|
|
476 {
|
|
477 }
|
|
478
|
|
479 // https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
|
|
480 version (none)
|
|
481 {
|
|
482 extern (C++, __cxx11)
|
|
483 {
|
|
484 struct basic_string(T, C = char_traits!T, A = allocator!T)
|
|
485 {
|
|
486 }
|
|
487 }
|
|
488 }
|
|
489 else
|
|
490 {
|
|
491 struct basic_string(T, C = char_traits!T, A = allocator!T)
|
|
492 {
|
|
493 }
|
|
494 }
|
|
495
|
|
496 struct basic_istream(T, C = char_traits!T)
|
|
497 {
|
|
498 }
|
|
499
|
|
500 struct basic_ostream(T, C = char_traits!T)
|
|
501 {
|
|
502 }
|
|
503
|
|
504 struct basic_iostream(T, C = char_traits!T)
|
|
505 {
|
|
506 }
|
|
507 }
|
|
508
|
|
509 class exception { }
|
|
510
|
|
511 // 14956
|
|
512 extern(C++, N14956)
|
|
513 {
|
|
514 struct S14956 { }
|
|
515 }
|
|
516 }
|
|
517
|
|
518 extern (C++)
|
|
519 {
|
|
520 version (linux)
|
|
521 {
|
|
522 void foo14(std.vector!(int) p);
|
|
523 void foo14a(std.basic_string!(char) *p);
|
|
524 void foo14b(std.basic_string!(int) *p);
|
|
525 void foo14c(std.basic_istream!(char) *p);
|
|
526 void foo14d(std.basic_ostream!(char) *p);
|
|
527 void foo14e(std.basic_iostream!(char) *p);
|
|
528
|
|
529 void foo14f(std.char_traits!char* x, std.basic_string!char* p, std.basic_string!char* q);
|
|
530 }
|
|
531 }
|
|
532
|
|
533 void test14()
|
|
534 {
|
|
535 version (linux)
|
|
536 {
|
|
537 std.vector!int p;
|
|
538 foo14(p);
|
|
539
|
|
540 foo14a(null);
|
|
541 foo14b(null);
|
|
542 foo14c(null);
|
|
543 foo14d(null);
|
|
544 foo14e(null);
|
|
545 foo14f(null, null, null);
|
|
546 }
|
|
547 }
|
|
548
|
|
549 version (linux)
|
|
550 {
|
|
551 void test14a(std.allocator!int * pa)
|
|
552 {
|
|
553 pa.deallocate(null, 0);
|
|
554 }
|
|
555
|
|
556 void gun(std.vector!int pa)
|
|
557 {
|
|
558 int x = 42;
|
|
559 pa.push_back(x);
|
|
560 }
|
|
561 }
|
|
562
|
|
563 void test13289()
|
|
564 {
|
|
565 assert(f13289_cpp_wchar_t('a') == 'A');
|
|
566 assert(f13289_cpp_wchar_t('B') == 'B');
|
|
567 assert(f13289_d_wchar('c') == 'C');
|
|
568 assert(f13289_d_wchar('D') == 'D');
|
|
569 assert(f13289_d_dchar('e') == 'E');
|
|
570 assert(f13289_d_dchar('F') == 'F');
|
|
571 assert(f13289_cpp_test());
|
|
572 }
|
|
573
|
|
574 extern(C++)
|
|
575 {
|
|
576 bool f13289_cpp_test();
|
|
577
|
|
578 version(Posix)
|
|
579 {
|
|
580 dchar f13289_cpp_wchar_t(dchar);
|
|
581 }
|
|
582 else version(Windows)
|
|
583 {
|
|
584 wchar f13289_cpp_wchar_t(wchar);
|
|
585 }
|
|
586
|
|
587 wchar f13289_d_wchar(wchar ch)
|
|
588 {
|
|
589 if (ch <= 'z' && ch >= 'a')
|
|
590 {
|
|
591 return cast(wchar)(ch - ('a' - 'A'));
|
|
592 }
|
|
593 else
|
|
594 {
|
|
595 return ch;
|
|
596 }
|
|
597 }
|
|
598 dchar f13289_d_dchar(dchar ch)
|
|
599 {
|
|
600 if (ch <= 'z' && ch >= 'a')
|
|
601 {
|
|
602 return ch - ('a' - 'A');
|
|
603 }
|
|
604 else
|
|
605 {
|
|
606 return ch;
|
|
607 }
|
|
608 }
|
|
609 }
|
|
610
|
|
611 /****************************************/
|
|
612
|
|
613 version (CRuntime_Microsoft)
|
|
614 {
|
|
615 enum __c_long_double : double;
|
|
616 alias __c_long_double myld;
|
|
617 }
|
|
618 else
|
|
619 alias c_long_double myld;
|
|
620
|
|
621 extern (C++) myld testld(myld);
|
|
622 extern (C++) myld testldld(myld, myld);
|
|
623
|
|
624
|
|
625 void test15()
|
|
626 {
|
|
627 myld ld = 5.0;
|
|
628 ld = testld(ld);
|
|
629 assert(ld == 6.0);
|
|
630
|
|
631 myld ld2 = 5.0;
|
|
632 ld2 = testldld(ld2, ld2);
|
|
633 assert(ld2 == 6.0);
|
|
634 }
|
|
635
|
|
636 /****************************************/
|
|
637
|
|
638 version( Windows )
|
|
639 {
|
|
640 alias int x_long;
|
|
641 alias uint x_ulong;
|
|
642 }
|
|
643 else
|
|
644 {
|
|
645 static if( (void*).sizeof > int.sizeof )
|
|
646 {
|
|
647 alias long x_long;
|
|
648 alias ulong x_ulong;
|
|
649 }
|
|
650 else
|
|
651 {
|
|
652 alias int x_long;
|
|
653 alias uint x_ulong;
|
|
654 }
|
|
655 }
|
|
656
|
|
657 enum __c_long : x_long;
|
|
658 enum __c_ulong : x_ulong;
|
|
659 alias __c_long mylong;
|
|
660 alias __c_ulong myulong;
|
|
661
|
|
662 extern (C++) mylong testl(mylong);
|
|
663 extern (C++) myulong testul(myulong);
|
|
664
|
|
665
|
|
666 void test16()
|
|
667 {
|
|
668 {
|
|
669 mylong ld = 5;
|
|
670 ld = testl(ld);
|
|
671 assert(ld == 5 + mylong.sizeof);
|
|
672 }
|
|
673 {
|
|
674 myulong ld = 5;
|
|
675 ld = testul(ld);
|
|
676 assert(ld == 5 + myulong.sizeof);
|
|
677 }
|
|
678
|
|
679 static if (__c_long.sizeof == long.sizeof)
|
|
680 {
|
|
681 static assert(__c_long.max == long.max);
|
|
682 static assert(__c_long.min == long.min);
|
|
683 static assert(__c_long.init == long.init);
|
|
684 static assert(__c_ulong.max == ulong.max);
|
|
685 static assert(__c_ulong.min == ulong.min);
|
|
686 static assert(__c_ulong.init == ulong.init);
|
|
687 __c_long cl = 0;
|
|
688 cl = cl + 1;
|
|
689 long l = cl;
|
|
690 cl = l;
|
|
691 __c_ulong cul = 0;
|
|
692 cul = cul + 1;
|
|
693 ulong ul = cul;
|
|
694 cul = ul;
|
|
695 }
|
|
696 else static if (__c_long.sizeof == int.sizeof)
|
|
697 {
|
|
698 static assert(__c_long.max == int.max);
|
|
699 static assert(__c_long.min == int.min);
|
|
700 static assert(__c_long.init == int.init);
|
|
701 static assert(__c_ulong.max == uint.max);
|
|
702 static assert(__c_ulong.min == uint.min);
|
|
703 static assert(__c_ulong.init == uint.init);
|
|
704 __c_long cl = 0;
|
|
705 cl = cl + 1;
|
|
706 int i = cl;
|
|
707 cl = i;
|
|
708 __c_ulong cul = 0;
|
|
709 cul = cul + 1;
|
|
710 uint u = cul;
|
|
711 cul = u;
|
|
712 }
|
|
713 else
|
|
714 static assert(0);
|
|
715 }
|
|
716
|
|
717 /****************************************/
|
|
718
|
|
719 struct S13707
|
|
720 {
|
|
721 void* a;
|
|
722 void* b;
|
|
723 this(void* a, void* b)
|
|
724 {
|
|
725 this.a = a;
|
|
726 this.b = b;
|
|
727 }
|
|
728 }
|
|
729
|
|
730 extern(C++) S13707 func13707();
|
|
731
|
|
732 void test13707()
|
|
733 {
|
|
734 auto p = func13707();
|
|
735 assert(p.a == null);
|
|
736 assert(p.b == null);
|
|
737 }
|
|
738
|
|
739 /****************************************/
|
|
740
|
|
741 struct S13932(int x)
|
|
742 {
|
|
743 int member;
|
|
744 }
|
|
745
|
|
746 extern(C++) void func13932(S13932!(-1) s);
|
|
747
|
|
748 /****************************************/
|
|
749
|
|
750 extern(C++, N13337.M13337)
|
|
751 {
|
|
752 struct S13337{}
|
|
753 void foo13337(S13337 s);
|
|
754 }
|
|
755
|
|
756 /****************************************/
|
|
757 // 14195
|
|
758
|
|
759 struct Delegate1(T) {}
|
|
760 struct Delegate2(T1, T2) {}
|
|
761
|
|
762 template Signature(T)
|
|
763 {
|
|
764 alias Signature = typeof(*(T.init));
|
|
765 }
|
|
766
|
|
767 extern(C++)
|
|
768 {
|
|
769 alias del1_t = Delegate1!(Signature!(void function()));
|
|
770 alias del2_t = Delegate2!(Signature!(int function(float, double)), Signature!(int function(float, double)));
|
|
771 void test14195a(del1_t);
|
|
772 void test14195b(del2_t);
|
|
773 }
|
|
774
|
|
775 void test14195()
|
|
776 {
|
|
777 test14195a(del1_t());
|
|
778 test14195b(del2_t());
|
|
779 }
|
|
780
|
|
781
|
|
782 /****************************************/
|
|
783 // 14200
|
|
784
|
|
785 template Tuple14200(T...)
|
|
786 {
|
|
787 alias Tuple14200 = T;
|
|
788 }
|
|
789
|
|
790 extern(C++) void test14200a(Tuple14200!(int));
|
|
791 extern(C++) void test14200b(float, Tuple14200!(int, double));
|
|
792
|
|
793 void test14200()
|
|
794 {
|
|
795 test14200a(1);
|
|
796 test14200b(1.0f, 1, 1.0);
|
|
797 }
|
|
798
|
|
799 /****************************************/
|
|
800 // 14956
|
|
801
|
|
802 extern(C++) void test14956(S14956 s);
|
|
803
|
|
804 /****************************************/
|
|
805 // check order of overloads in vtable
|
|
806
|
|
807 extern (C++) class Statement {}
|
|
808 extern (C++) class ErrorStatement {}
|
|
809 extern (C++) class PeelStatement {}
|
|
810 extern (C++) class ExpStatement {}
|
|
811 extern (C++) class DtorExpStatement {}
|
|
812
|
|
813 extern (C++) class Visitor
|
|
814 {
|
|
815 public:
|
|
816 int visit(Statement) { return 1; }
|
|
817 int visit(ErrorStatement) { return 2; }
|
|
818 int visit(PeelStatement) { return 3; }
|
|
819 }
|
|
820
|
|
821 extern (C++) class Visitor2 : Visitor
|
|
822 {
|
|
823 int visit2(ExpStatement) { return 4; }
|
|
824 int visit2(DtorExpStatement) { return 5; }
|
|
825 }
|
|
826
|
|
827 extern(C++) bool testVtableCpp(Visitor2 sv);
|
|
828 extern(C++) Visitor2 getVisitor2();
|
|
829
|
|
830 bool testVtableD(Visitor2 sv)
|
|
831 {
|
|
832 Statement s1;
|
|
833 ErrorStatement s2;
|
|
834 PeelStatement s3;
|
|
835 ExpStatement s4;
|
|
836 DtorExpStatement s5;
|
|
837
|
|
838 if (sv.visit(s1) != 1) return false;
|
|
839 if (sv.visit(s2) != 2) return false;
|
|
840 if (sv.visit(s3) != 3) return false;
|
|
841 if (sv.visit2(s4) != 4) return false;
|
|
842 if (sv.visit2(s5) != 5) return false;
|
|
843 return true;
|
|
844 }
|
|
845
|
|
846 void testVtable()
|
|
847 {
|
|
848 Visitor2 dinst = new Visitor2;
|
|
849 if (!testVtableCpp(dinst))
|
|
850 assert(0);
|
|
851
|
|
852 Visitor2 cppinst = getVisitor2();
|
|
853 if (!testVtableD(cppinst))
|
|
854 assert(0);
|
|
855 }
|
|
856
|
|
857 /****************************************/
|
|
858 /* problems detected by fuzzer */
|
|
859 extern(C++) void fuzz1_cppvararg(long arg10, long arg11, bool arg12);
|
|
860 extern(C++) void fuzz1_dvararg(long arg10, long arg11, bool arg12)
|
|
861 {
|
|
862 fuzz1_checkValues(arg10, arg11, arg12);
|
|
863 }
|
|
864
|
|
865 extern(C++) void fuzz1_checkValues(long arg10, long arg11, bool arg12)
|
|
866 {
|
|
867 assert(arg10 == 103);
|
|
868 assert(arg11 == 104);
|
|
869 assert(arg12 == false);
|
|
870 }
|
|
871
|
|
872 void fuzz1()
|
|
873 {
|
|
874 long arg10 = 103;
|
|
875 long arg11 = 104;
|
|
876 bool arg12 = false;
|
|
877 fuzz1_dvararg(arg10, arg11, arg12);
|
|
878 fuzz1_cppvararg(arg10, arg11, arg12);
|
|
879 }
|
|
880
|
|
881 ////////
|
|
882 extern(C++) void fuzz2_cppvararg(ulong arg10, ulong arg11, bool arg12);
|
|
883 extern(C++) void fuzz2_dvararg(ulong arg10, ulong arg11, bool arg12)
|
|
884 {
|
|
885 fuzz2_checkValues(arg10, arg11, arg12);
|
|
886 }
|
|
887
|
|
888 extern(C++) void fuzz2_checkValues(ulong arg10, ulong arg11, bool arg12)
|
|
889 {
|
|
890 assert(arg10 == 103);
|
|
891 assert(arg11 == 104);
|
|
892 assert(arg12 == false);
|
|
893 }
|
|
894
|
|
895 void fuzz2()
|
|
896 {
|
|
897 ulong arg10 = 103;
|
|
898 ulong arg11 = 104;
|
|
899 bool arg12 = false;
|
|
900 fuzz2_dvararg(arg10, arg11, arg12);
|
|
901 fuzz2_cppvararg(arg10, arg11, arg12);
|
|
902 }
|
|
903
|
|
904 ////////
|
|
905 extern(C++) void fuzz3_cppvararg(wchar arg10, wchar arg11, bool arg12);
|
|
906 extern(C++) void fuzz3_dvararg(wchar arg10, wchar arg11, bool arg12)
|
|
907 {
|
|
908 fuzz2_checkValues(arg10, arg11, arg12);
|
|
909 }
|
|
910
|
|
911 extern(C++) void fuzz3_checkValues(wchar arg10, wchar arg11, bool arg12)
|
|
912 {
|
|
913 assert(arg10 == 103);
|
|
914 assert(arg11 == 104);
|
|
915 assert(arg12 == false);
|
|
916 }
|
|
917
|
|
918 void fuzz3()
|
|
919 {
|
|
920 wchar arg10 = 103;
|
|
921 wchar arg11 = 104;
|
|
922 bool arg12 = false;
|
|
923 fuzz3_dvararg(arg10, arg11, arg12);
|
|
924 fuzz3_cppvararg(arg10, arg11, arg12);
|
|
925 }
|
|
926
|
|
927 void fuzz()
|
|
928 {
|
|
929 fuzz1();
|
|
930 fuzz2();
|
|
931 fuzz3();
|
|
932 }
|
|
933
|
|
934 /****************************************/
|
|
935
|
|
936 extern (C++)
|
|
937 {
|
|
938 void throwit();
|
|
939 }
|
|
940
|
|
941 void testeh()
|
|
942 {
|
|
943 printf("testeh()\n");
|
|
944 version (linux)
|
|
945 {
|
|
946 version (X86_64)
|
|
947 {
|
|
948 bool caught;
|
|
949 try
|
|
950 {
|
|
951 throwit();
|
|
952 }
|
|
953 catch (std.exception e)
|
|
954 {
|
|
955 caught = true;
|
|
956 }
|
|
957 assert(caught);
|
|
958 }
|
|
959 }
|
|
960 }
|
|
961
|
|
962 /****************************************/
|
|
963
|
|
964 version (linux)
|
|
965 {
|
|
966 version (X86_64)
|
|
967 {
|
|
968 bool raii_works = false;
|
|
969 struct RAIITest
|
|
970 {
|
|
971 ~this()
|
|
972 {
|
|
973 raii_works = true;
|
|
974 }
|
|
975 }
|
|
976
|
|
977 void dFunction()
|
|
978 {
|
|
979 RAIITest rt;
|
|
980 throwit();
|
|
981 }
|
|
982
|
|
983 void testeh2()
|
|
984 {
|
|
985 printf("testeh2()\n");
|
|
986 try
|
|
987 {
|
|
988 dFunction();
|
|
989 }
|
|
990 catch(std.exception e)
|
|
991 {
|
|
992 assert(raii_works);
|
|
993 }
|
|
994 }
|
|
995 }
|
|
996 else
|
|
997 void testeh2() { }
|
|
998 }
|
|
999 else
|
|
1000 void testeh2() { }
|
|
1001
|
|
1002 /****************************************/
|
|
1003
|
|
1004 extern (C++) { void throwle(); void throwpe(); }
|
|
1005
|
|
1006 void testeh3()
|
|
1007 {
|
|
1008 printf("testeh3()\n");
|
|
1009 version (linux)
|
|
1010 {
|
|
1011 version (X86_64)
|
|
1012 {
|
|
1013 bool caught = false;
|
|
1014 try
|
|
1015 {
|
|
1016 throwle();
|
|
1017 }
|
|
1018 catch (std.exception e) //polymorphism test.
|
|
1019 {
|
|
1020 caught = true;
|
|
1021 }
|
|
1022 assert(caught);
|
|
1023 }
|
|
1024 }
|
|
1025 }
|
|
1026
|
|
1027 /****************************************/
|
|
1028 // 15576
|
|
1029
|
|
1030 extern (C++, ns15576)
|
|
1031 {
|
|
1032 extern __gshared int global15576;
|
|
1033
|
|
1034 extern (C++, ns)
|
|
1035 {
|
|
1036 extern __gshared int n_global15576;
|
|
1037 }
|
|
1038 }
|
|
1039
|
|
1040 void test15576()
|
|
1041 {
|
|
1042 global15576 = n_global15576 = 123;
|
|
1043 }
|
|
1044
|
|
1045 /****************************************/
|
|
1046 // 15579
|
|
1047
|
|
1048 extern (C++)
|
|
1049 {
|
|
1050 class Base
|
|
1051 {
|
|
1052 //~this() {}
|
|
1053 void based() { }
|
|
1054 ubyte x = 4;
|
|
1055 }
|
|
1056
|
|
1057 interface Interface
|
|
1058 {
|
|
1059 int MethodCPP();
|
|
1060 int MethodD();
|
|
1061 }
|
|
1062
|
|
1063 class Derived : Base, Interface
|
|
1064 {
|
|
1065 short y = 5;
|
|
1066 int MethodCPP();
|
|
1067 int MethodD() {
|
|
1068 printf("Derived.MethodD(): this = %p, x = %d, y = %d\n", this, x, y);
|
|
1069 Derived p = this;
|
|
1070 //p = cast(Derived)(cast(void*)p - 16);
|
|
1071 assert(p.x == 4 || p.x == 7);
|
|
1072 assert(p.y == 5 || p.y == 8);
|
|
1073 return 3;
|
|
1074 }
|
|
1075 int Method() { return 6; }
|
|
1076 }
|
|
1077
|
|
1078 Derived cppfoo(Derived);
|
|
1079 Interface cppfooi(Interface);
|
|
1080 }
|
|
1081
|
|
1082 void test15579()
|
|
1083 {
|
|
1084 Derived d = new Derived();
|
|
1085 printf("d = %p\n", d);
|
|
1086 assert(d.x == 4);
|
|
1087 assert(d.y == 5);
|
|
1088 assert((cast(Interface)d).MethodCPP() == 30);
|
|
1089 assert((cast(Interface)d).MethodD() == 3);
|
|
1090 assert(d.MethodCPP() == 30);
|
|
1091 assert(d.MethodD() == 3);
|
|
1092 assert(d.Method() == 6);
|
|
1093
|
|
1094 d = cppfoo(d);
|
|
1095 assert(d.x == 7);
|
|
1096 assert(d.y == 8);
|
|
1097
|
|
1098 printf("d2 = %p\n", d);
|
|
1099
|
|
1100 /* Casting to an interface involves thunks in the vtbl[].
|
|
1101 * g++ puts the thunks for MethodD in the same COMDAT as MethodD.
|
|
1102 * But D doesn't, so when the linker "picks one" of the D generated MethodD
|
|
1103 * or the g++ generated MethodD, it may wind up with a messed up thunk,
|
|
1104 * resulting in a seg fault. The solution is to not expect objects of the same
|
|
1105 * type to be constructed on both sides of the D/C++ divide if the same member
|
|
1106 * function (in this case, MethodD) is also defined on both sides.
|
|
1107 */
|
|
1108 version (Windows)
|
|
1109 {
|
|
1110 assert((cast(Interface)d).MethodD() == 3);
|
|
1111 }
|
|
1112 assert((cast(Interface)d).MethodCPP() == 30);
|
|
1113
|
|
1114 assert(d.Method() == 6);
|
|
1115
|
|
1116 printf("d = %p, i = %p\n", d, cast(Interface)d);
|
|
1117 version (Windows)
|
|
1118 {
|
|
1119 Interface i = cppfooi(d);
|
|
1120 printf("i2: %p\n", i);
|
|
1121 assert(i.MethodD() == 3);
|
|
1122 assert(i.MethodCPP() == 30);
|
|
1123 }
|
|
1124 printf("test15579() done\n");
|
|
1125 }
|
|
1126
|
|
1127 /****************************************/
|
|
1128 // 15610
|
|
1129
|
|
1130 extern(C++) class Base2
|
|
1131 {
|
|
1132 int i;
|
|
1133 void baser() { }
|
|
1134 }
|
|
1135
|
|
1136 extern(C++) interface Interface2 { abstract void f(); }
|
|
1137
|
|
1138 extern(C++) class Derived2 : Base2, Interface2
|
|
1139 {
|
|
1140 final
|
|
1141 override void f();
|
|
1142 }
|
|
1143
|
|
1144
|
|
1145 void test15610()
|
|
1146 {
|
|
1147 auto c = new Derived2();
|
|
1148 printf("test15610(): c = %p\n", c);
|
|
1149 c.i = 3;
|
|
1150 c.f();
|
|
1151 }
|
|
1152
|
|
1153 /******************************************/
|
|
1154 // 15455
|
|
1155
|
|
1156 struct X6
|
|
1157 {
|
|
1158 ushort a;
|
|
1159 ushort b;
|
|
1160 ubyte c;
|
|
1161 ubyte d;
|
|
1162 }
|
|
1163
|
|
1164 static assert(X6.sizeof == 6);
|
|
1165
|
|
1166 struct X8
|
|
1167 {
|
|
1168 ushort a;
|
|
1169 X6 b;
|
|
1170 }
|
|
1171
|
|
1172 static assert(X8.sizeof == 8);
|
|
1173
|
|
1174 void test15455a(X8 s)
|
|
1175 {
|
|
1176 assert(s.a == 1);
|
|
1177 assert(s.b.a == 2);
|
|
1178 assert(s.b.b == 3);
|
|
1179 assert(s.b.c == 4);
|
|
1180 assert(s.b.d == 5);
|
|
1181 }
|
|
1182
|
|
1183 extern (C++) void test15455b(X8 s);
|
|
1184
|
|
1185 void test15455()
|
|
1186 {
|
|
1187 X8 s;
|
|
1188
|
|
1189 s.a = 1;
|
|
1190 s.b.a = 2;
|
|
1191 s.b.b = 3;
|
|
1192 s.b.c = 4;
|
|
1193 s.b.d = 5;
|
|
1194 test15455a(s);
|
|
1195 test15455b(s);
|
|
1196 }
|
|
1197
|
|
1198 /****************************************/
|
|
1199 // 15372
|
|
1200
|
|
1201 extern(C++) int foo15372(T)(T v);
|
|
1202
|
|
1203 void test15372()
|
|
1204 {
|
|
1205 version(Windows){}
|
|
1206 else
|
|
1207 assert(foo15372!int(1) == 1);
|
|
1208 }
|
|
1209
|
|
1210 /****************************************/
|
|
1211 // 15802
|
|
1212
|
|
1213 extern(C++) {
|
|
1214 template Foo15802(T) {
|
|
1215 static int boo(T v);
|
|
1216 }
|
|
1217 }
|
|
1218
|
|
1219 void test15802()
|
|
1220 {
|
|
1221 version(Windows){}
|
|
1222 else
|
|
1223 assert(Foo15802!(int).boo(1) == 1);
|
|
1224 }
|
|
1225
|
|
1226 /****************************************/
|
|
1227 // 16536 - mangling mismatch on OSX
|
|
1228
|
|
1229 version(OSX) extern(C++) ulong pass16536(ulong);
|
|
1230
|
|
1231 void test16536()
|
|
1232 {
|
|
1233 version(OSX) assert(pass16536(123) == 123);
|
|
1234 }
|
|
1235
|
|
1236 /****************************************/
|
|
1237
|
|
1238 void main()
|
|
1239 {
|
|
1240 test1();
|
|
1241 test2();
|
|
1242 test3();
|
|
1243 test4();
|
|
1244 test13956();
|
|
1245 test5();
|
|
1246 test6();
|
|
1247 test10071();
|
|
1248 test7();
|
|
1249 test8();
|
|
1250 test11802();
|
|
1251 test9();
|
|
1252 test10();
|
|
1253 test13955();
|
|
1254 test11();
|
|
1255 testvalist();
|
|
1256 test12825();
|
|
1257 test13161();
|
|
1258 test14();
|
|
1259 test13289();
|
|
1260 test15();
|
|
1261 test16();
|
|
1262 func13707();
|
|
1263 func13932(S13932!(-1)(0));
|
|
1264 foo13337(S13337());
|
|
1265 test14195();
|
|
1266 test14200();
|
|
1267 test14956(S14956());
|
|
1268 testVtable();
|
|
1269 fuzz();
|
|
1270 testeh();
|
|
1271 testeh2();
|
|
1272 testeh3();
|
|
1273 test15576();
|
|
1274 test15579();
|
|
1275 test15610();
|
|
1276 test15455();
|
|
1277 test15372();
|
|
1278 test15802();
|
|
1279 test16536();
|
|
1280
|
|
1281 printf("Success\n");
|
|
1282 }
|