1 /** 2 Integration tests that stem from failues in real-life C projects 3 */ 4 module it.c.compile.projects; 5 6 import it; 7 8 @("nn_get_statistic") 9 @safe unittest { 10 shouldCompile( 11 C( 12 // the original uses regular uint64_t, let's beat any special cases 13 // defining our own 14 q{ 15 typedef unsigned long int __my_uint64_t; 16 typedef __my_uint64_t my_uint64_t; 17 my_uint64_t nn_get_statistic (int s, int stat); 18 } 19 ), 20 21 D( 22 q{ 23 int s; 24 int stat; 25 my_uint64_t ret = nn_get_statistic(s, stat); 26 } 27 ) 28 ); 29 } 30 31 @("__io_read_fn") 32 @safe unittest { 33 shouldCompile( 34 C( 35 q{ 36 typedef long long __ssize_t; 37 typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, long __nbytes); 38 } 39 ), 40 41 D( 42 q{ 43 void* cookie; 44 char[1024] buf; 45 __ssize_t ret = __io_read_fn.init(cookie, buf.ptr, buf.length); 46 } 47 ), 48 ); 49 } 50 51 @("timer_t") 52 @safe unittest { 53 shouldCompile( 54 C( 55 // the original uses regular uint64_t, let's beat any special cases 56 // defining our own 57 ` 58 #define __TIMER_T_TYPE void * 59 typedef __TIMER_T_TYPE __timer_t; 60 ` 61 ), 62 63 D( 64 q{ 65 __timer_t timer = null; 66 } 67 ), 68 ); 69 } 70 71 72 @("curl_multi_wait") 73 @safe unittest { 74 shouldCompile( 75 C( 76 q{ 77 typedef enum { CURLM_OK } CURLMcode; 78 typedef int curl_socket_t; 79 80 struct curl_waitfd { 81 curl_socket_t fd; 82 short events; 83 short revents; /* not supported yet */ 84 }; 85 86 typedef struct { int dummy; } CURLM; 87 CURLMcode curl_multi_wait(CURLM *multi_handle, 88 struct curl_waitfd extra_fds[], 89 unsigned int extra_nfds, 90 int timeout_ms, 91 int *ret); 92 } 93 ), 94 95 D( 96 q{ 97 CURLM handle; 98 curl_waitfd[] extra_fds; 99 int ret; 100 CURLMcode code = curl_multi_wait(&handle, extra_fds.ptr, 42u, 33, &ret); 101 } 102 ), 103 ); 104 } 105 106 @("__sigset_t") 107 @safe unittest { 108 shouldCompile( 109 // the original uses regular uint64_t, let's beat any special cases 110 // defining our own 111 C( 112 ` 113 #define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) 114 typedef struct 115 { 116 unsigned long int __val[_SIGSET_NWORDS]; 117 } __sigset_t; 118 ` 119 ), 120 D( 121 q{ 122 auto s = __sigset_t(); 123 ++s.__val[7]; 124 } 125 ), 126 ); 127 } 128 129 130 @("_IO_flockfile") 131 @safe unittest { 132 shouldCompile( 133 C( 134 ` 135 struct _IO_FILE { int dummy; }; 136 extern void _IO_flockfile (struct _IO_FILE *); 137 #define _IO_flockfile(_fp) 138 ` 139 ), 140 D( 141 q{ 142 _IO_FILE file; 143 _IO_flockfile(&file); 144 } 145 ), 146 ); 147 } 148 149 @Tags("notravis") 150 @("struct with union") 151 @safe unittest { 152 shouldCompile( 153 C( 154 q{ 155 struct Struct { 156 union { 157 void *ptr; 158 int i; 159 } data; 160 }; 161 typedef struct Struct Struct; 162 } 163 ), 164 165 D( 166 q{ 167 Struct s; 168 s.data.ptr = null; 169 s.data.i = 42; 170 } 171 ), 172 ); 173 } 174 175 @("const char* const") 176 @safe unittest { 177 shouldCompile( 178 C( 179 q{ 180 struct Struct { 181 const char * const *protocols; 182 }; 183 typedef struct Struct Struct; 184 } 185 ), 186 187 D( 188 q{ 189 Struct s; 190 static assert(is(typeof(s.protocols) == const(char*)*), 191 "Expected const(char*)*, not " ~ 192 typeof(s.protocols).stringof); 193 } 194 ), 195 ); 196 } 197 198 @("forward declaration") 199 @safe unittest { 200 shouldCompile( 201 C( 202 q{ 203 struct Struct; 204 void fun(struct Struct* s); 205 struct Struct* make_struct(void); 206 } 207 ), 208 209 D( 210 q{ 211 Struct* s = make_struct(); 212 fun(s); 213 } 214 ), 215 ); 216 } 217 218 219 @("restrict") 220 @safe unittest { 221 shouldCompile( 222 C( 223 q{ 224 struct FILE { int dummy; }; 225 extern struct FILE *fopen(const char *restrict filename, 226 const char *restrict modes); 227 } 228 ), 229 230 D( 231 q{ 232 import std.string; 233 fopen("foo.txt".toStringz, "w".toStringz); 234 } 235 ), 236 ); 237 } 238 239 240 @("return type typedefd enum") 241 @safe unittest { 242 shouldCompile( 243 C( 244 q{ 245 typedef struct { int dummy; } CURL; 246 247 typedef enum { 248 CURLIOE_OK, /* I/O operation successful */ 249 } curlioerr; 250 251 typedef curlioerr (*curl_ioctl_callback)(CURL *handle, 252 int cmd, 253 void *clientp); 254 } 255 ), 256 D( 257 q{ 258 CURL handle; 259 auto func = curl_ioctl_callback.init; 260 curlioerr err = func(&handle, 42, null); 261 } 262 ), 263 ); 264 } 265 266 267 @("curl_slist") 268 @safe unittest { 269 shouldCompile( 270 C( 271 q{ 272 struct curl_httppost { 273 struct curl_slist *contentheader; 274 }; 275 struct curl_slist { 276 char *data; 277 struct curl_slist *next; 278 }; 279 } 280 ), 281 D( 282 q{ 283 curl_httppost p; 284 p.contentheader.data = null; 285 p.contentheader.next = null; 286 curl_slist l; 287 l.data = null; 288 l.next = null; 289 } 290 ), 291 ); 292 } 293 294 @("struct var collision with var before") 295 @safe unittest { 296 shouldCompile( 297 C( 298 q{ 299 extern int foo; 300 struct foo { int dummy; }; 301 } 302 ), 303 D( 304 q{ 305 auto u = foo(44); 306 foo_ = 42; 307 } 308 ), 309 ); 310 } 311 312 @("struct function collision with function before") 313 @safe unittest { 314 shouldCompile( 315 C( 316 q{ 317 void foo(void); 318 struct foo { int dummy; }; 319 } 320 ), 321 D( 322 q{ 323 auto u = foo(44); 324 foo_(); 325 } 326 ), 327 ); 328 } 329 330 331 @("union var collision") 332 @safe unittest { 333 shouldCompile( 334 C( 335 q{ 336 union foo { int dummy; }; 337 extern int foo; 338 } 339 ), 340 D( 341 q{ 342 auto u = foo(44); 343 foo_ = 42; 344 } 345 ), 346 ); 347 } 348 349 @("enum var collision") 350 @safe unittest { 351 shouldCompile( 352 C( 353 q{ 354 enum foo { one, two, three }; 355 extern int foo; 356 } 357 ), 358 D( 359 q{ 360 auto e = foo.three; 361 foo_ = 42; 362 } 363 ), 364 ); 365 } 366 367 @("use int for enum parameter") 368 @safe unittest { 369 shouldCompile( 370 C( 371 q{ 372 typedef enum { 373 foo, 374 bar, 375 } Enum; 376 void func(Enum e); 377 } 378 ), 379 D( 380 q{ 381 func(Enum.bar); 382 } 383 ), 384 ); 385 } 386 387 @("pthread struct") 388 @safe unittest { 389 with(immutable IncludeSandbox()) { 390 writeFile("hdr.h", 391 q{ 392 typedef struct { 393 void (*routine)(void*); 394 } Struct; 395 } 396 ); 397 writeFile("app.dpp", 398 ` 399 #include "hdr.h" 400 extern(C) void foo(void*) {} 401 402 void main() { 403 Struct s; 404 s.routine = &foo; 405 } 406 ` 407 ); 408 409 runPreprocessOnly("app.dpp"); 410 shouldCompile("app.d"); 411 } 412 } 413 414 415 @("multiple headers with the same typedef") 416 @safe unittest { 417 with(const IncludeSandbox()) { 418 writeFile("hdr1.h", 419 q{ 420 typedef long time_t; 421 typedef long time_t; 422 } 423 ), 424 425 writeFile("hdr2.h", 426 q{ 427 typedef long time_t; 428 typedef long time_t; 429 } 430 ), 431 432 writeFile("app.dpp", 433 ` 434 #include "hdr1.h" 435 #include "hdr2.h" 436 void main() { 437 time_t var = 42; 438 } 439 `); 440 441 runPreprocessOnly("app.dpp"); 442 shouldCompile("app.d"); 443 } 444 } 445 446 @("jmp_buf") 447 @safe unittest { 448 shouldCompile( 449 C( 450 q{ 451 typedef long int __jmp_buf[8]; 452 } 453 ), 454 455 D( 456 q{ 457 __jmp_buf buf; 458 static assert(buf.length == 8); 459 } 460 ), 461 ); 462 } 463 464 @("__pthread_unwind_buf_t") 465 @safe unittest { 466 shouldCompile( 467 C( 468 q{ 469 typedef long int __jmp_buf[8]; 470 typedef struct { 471 struct { 472 __jmp_buf __cancel_jmp_buf; 473 int __mask_was_saved; 474 } __cancel_jmp_buf[1]; 475 void *__pad[4]; 476 } __pthread_unwind_buf_t __attribute__ ((__aligned__)); 477 } 478 ), 479 480 D( 481 q{ 482 __pthread_unwind_buf_t buf; 483 } 484 ), 485 ); 486 } 487 488 489 @("struct pointer to unknown struct that is defined by a later header") 490 @safe unittest { 491 with(immutable IncludeSandbox()) { 492 writeFile("hdr1.h", 493 q{ 494 typedef struct Foo { 495 struct Bar* bar; 496 } Foo; 497 }); 498 writeFile("hdr2.h", 499 q{ 500 struct Bar; 501 }); 502 writeFile("app.dpp", 503 ` 504 #include "hdr1.h" 505 #include "hdr2.h" 506 void main() { 507 Foo f; 508 f.bar = null; 509 } 510 `); 511 runPreprocessOnly("app.dpp"); 512 shouldCompile("app.d"); 513 } 514 } 515 516 @("typedef struct pointer with no declaration") 517 @safe unittest { 518 shouldCompile( 519 C( 520 q{ 521 typedef struct _Foo Foo; 522 typedef Foo *FooPtr; 523 } 524 ), 525 D( 526 q{ 527 void fun(FooPtr ptr) { } 528 FooPtr ptr; 529 fun(ptr); 530 } 531 ), 532 ); 533 } 534 535 @("extern global variable with undefined macro") 536 @safe unittest { 537 with(immutable IncludeSandbox()) { 538 writeFile("hdr.h", 539 q{ 540 // EXPORT_VAR not defined anywhere 541 typedef struct _Foo Foo; 542 typedef Foo *FooPtr; 543 EXPORT_VAR FooPtr theFoo; 544 }); 545 writeFile("app.dpp", 546 ` 547 #include "hdr.h" 548 `); 549 try { 550 runPreprocessOnly("app.dpp"); 551 assert(0, "Should not get here"); 552 } catch(Exception e) { 553 "unknown type name 'EXPORT_VAR'".shouldBeIn(e.msg); 554 } 555 } 556 } 557 558 @("angle brackets headers with more angle brackets") 559 @safe unittest { 560 561 with(immutable IncludeSandbox()) { 562 563 writeFile("includes/libfoo/libfoo.h", 564 ` 565 #include <libfoo/libfoo-common.h> 566 #include <libfoo/libfoo-host.h> 567 `); 568 569 writeFile("includes/libfoo/libfoo-common.h", 570 ` 571 #define EXPORT_VAR extern 572 `); 573 574 writeFile("includes/libfoo/libfoo-host.h", 575 q{ 576 typedef struct _Foo Foo; 577 typedef Foo *FooPtr; 578 }); 579 580 writeFile("app.dpp", 581 ` 582 #include <libfoo/libfoo.h> 583 void func(FooPtr foo) { 584 assert(foo is null); 585 } 586 `); 587 588 runPreprocessOnly( 589 "--include-path", 590 inSandboxPath("includes"), 591 "app.dpp"); 592 593 shouldCompile("app.d"); 594 } 595 } 596 597 598 @("double enum typedef") 599 @safe unittest { 600 601 with(immutable IncludeSandbox()) { 602 603 writeFile("enum.h", 604 q{ 605 typedef enum { 606 only_value, 607 } Enum; 608 }); 609 610 writeFile("hdr1.h", 611 ` 612 #include "enum.h" 613 `); 614 615 writeFile("hdr2.h", 616 ` 617 #include "enum.h" 618 `); 619 620 writeFile("app.dpp", 621 ` 622 #include "hdr1.h" 623 #include "hdr2.h" 624 `); 625 626 runPreprocessOnly("app.dpp"); 627 shouldCompile("app.d"); 628 } 629 630 } 631 632 @("gregset_t") 633 @safe unittest { 634 shouldCompile( 635 C( 636 ` 637 typedef long long int greg_t; 638 #define __NGREG 23 639 typedef greg_t gregset_t[__NGREG]; 640 ` 641 ), 642 D( 643 q{ 644 static assert(greg_t.sizeof == 8); 645 static assert(gregset_t.sizeof == 23 * 8); 646 } 647 ), 648 ); 649 } 650 651 652 @("nv_alloc_ops") 653 @safe unittest { 654 shouldCompile( 655 C( 656 q{ 657 typedef struct Inner_ Inner; 658 659 typedef struct Outer { 660 const Inner *nva_ops; 661 } Outer; 662 663 struct Inner_ { 664 int dummy; 665 }; 666 } 667 ), 668 D( 669 q{ 670 } 671 ), 672 ); 673 } 674 675 @("va_list") 676 @safe unittest { 677 shouldCompile( 678 C( 679 ` 680 #include <stdarg.h> 681 typedef struct Struct { 682 int (*func)(int, va_list); 683 }; 684 ` 685 ), 686 D( 687 q{ 688 } 689 ), 690 ); 691 } 692 693 694 @("ASN1_ITEM") 695 @safe unittest { 696 shouldCompile( 697 C( 698 q{ 699 struct Foo_st; 700 typedef struct Foo_st Foo; 701 extern const Foo gVar; 702 } 703 ), 704 D( 705 q{ 706 707 } 708 ), 709 ); 710 } 711 712 713 @("X509_get0_extensions") 714 @safe unittest { 715 shouldCompile( 716 C( 717 q{ 718 typedef struct { int dummy; } Param; 719 struct Ret; 720 const struct Ret *func(const Param *x); 721 } 722 ), 723 D( 724 q{ 725 726 } 727 ), 728 ); 729 } 730 731 732 @("double semicolon after function declaration") 733 @safe unittest { 734 shouldCompile( 735 C( 736 q{ 737 void foo(void);; 738 } 739 ), 740 D( 741 q{ 742 743 } 744 ), 745 ); 746 } 747 748 749 @("_Bool") 750 @safe unittest { 751 shouldCompile( 752 C( 753 ` 754 #include <stdbool.h> 755 typedef bool handler_t(int, double); 756 ` 757 ), 758 D( 759 q{ 760 handler_t handler; 761 bool b = handler(42, 33.3); 762 } 763 ), 764 ); 765 }