|
31 | 31 | * 3) standard system types
|
32 | 32 | * 4) IsValid macros for system types
|
33 | 33 | * 5) offsetof, lengthof, endof, alignment
|
34 |
| - * 6) widely useful macros |
35 |
| - * 7) random stuff |
36 |
| - * 8) system-specific hacks |
| 34 | + * 6) assertions |
| 35 | + * 7) widely useful macros |
| 36 | + * 8) random stuff |
| 37 | + * 9) system-specific hacks |
37 | 38 | *
|
38 | 39 | * NOTE: since this file is included by both frontend and backend modules, it's
|
39 | 40 | * almost certainly wrong to put an "extern" declaration here. typedefs and
|
@@ -550,7 +551,134 @@ typedef NameData *Name;
|
550 | 551 | #define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN))
|
551 | 552 |
|
552 | 553 | /* ----------------------------------------------------------------
|
553 |
| - * Section 6: widely useful macros |
| 554 | + * Section 6: assertions |
| 555 | + * ---------------------------------------------------------------- |
| 556 | + */ |
| 557 | + |
| 558 | +/* |
| 559 | + * USE_ASSERT_CHECKING, if defined, turns on all the assertions. |
| 560 | + * - plai 9/5/90 |
| 561 | + * |
| 562 | + * It should _NOT_ be defined in releases or in benchmark copies |
| 563 | + */ |
| 564 | + |
| 565 | +/* |
| 566 | + * Assert() can be used in both frontend and backend code. In frontend code it |
| 567 | + * just calls the standard assert, if it's available. If use of assertions is |
| 568 | + * not configured, it does nothing. |
| 569 | + */ |
| 570 | +#ifndef USE_ASSERT_CHECKING |
| 571 | + |
| 572 | +#define Assert(condition) |
| 573 | +#define AssertMacro(condition) ((void)true) |
| 574 | +#define AssertArg(condition) |
| 575 | +#define AssertState(condition) |
| 576 | + |
| 577 | +#elif defined(FRONTEND) |
| 578 | + |
| 579 | +#include <assert.h> |
| 580 | +#define Assert(p) assert(p) |
| 581 | +#define AssertMacro(p) ((void) assert(p)) |
| 582 | +#define AssertArg(condition) assert(condition) |
| 583 | +#define AssertState(condition) assert(condition) |
| 584 | + |
| 585 | +#else /* USE_ASSERT_CHECKING && FRONTEND */ |
| 586 | + |
| 587 | +/* |
| 588 | + * Trap |
| 589 | + * Generates an exception if the given condition is true. |
| 590 | + */ |
| 591 | +#define Trap(condition, errorType) \ |
| 592 | + do { \ |
| 593 | + if ((assert_enabled) && (condition)) \ |
| 594 | + ExceptionalCondition(CppAsString(condition), (errorType), \ |
| 595 | + __FILE__, __LINE__); \ |
| 596 | + } while (0) |
| 597 | + |
| 598 | +/* |
| 599 | + * TrapMacro is the same as Trap but it's intended for use in macros: |
| 600 | + * |
| 601 | + * #define foo(x) (AssertMacro(x != 0), bar(x)) |
| 602 | + * |
| 603 | + * Isn't CPP fun? |
| 604 | + */ |
| 605 | +#define TrapMacro(condition, errorType) \ |
| 606 | + ((bool) ((! assert_enabled) || ! (condition) || \ |
| 607 | + (ExceptionalCondition(CppAsString(condition), (errorType), \ |
| 608 | + __FILE__, __LINE__), 0))) |
| 609 | + |
| 610 | +#define Assert(condition) \ |
| 611 | + Trap(!(condition), "FailedAssertion") |
| 612 | + |
| 613 | +#define AssertMacro(condition) \ |
| 614 | + ((void) TrapMacro(!(condition), "FailedAssertion")) |
| 615 | + |
| 616 | +#define AssertArg(condition) \ |
| 617 | + Trap(!(condition), "BadArgument") |
| 618 | + |
| 619 | +#define AssertState(condition) \ |
| 620 | + Trap(!(condition), "BadState") |
| 621 | + |
| 622 | +#endif /* USE_ASSERT_CHECKING && !FRONTEND */ |
| 623 | + |
| 624 | + |
| 625 | +/* |
| 626 | + * Macros to support compile-time assertion checks. |
| 627 | + * |
| 628 | + * If the "condition" (a compile-time-constant expression) evaluates to false, |
| 629 | + * throw a compile error using the "errmessage" (a string literal). |
| 630 | + * |
| 631 | + * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic |
| 632 | + * placement restrictions. These macros make it safe to use as a statement |
| 633 | + * or in an expression, respectively. |
| 634 | + * |
| 635 | + * Otherwise we fall back on a kluge that assumes the compiler will complain |
| 636 | + * about a negative width for a struct bit-field. This will not include a |
| 637 | + * helpful error message, but it beats not getting an error at all. |
| 638 | + */ |
| 639 | +#ifdef HAVE__STATIC_ASSERT |
| 640 | +#define StaticAssertStmt(condition, errmessage) \ |
| 641 | + do { _Static_assert(condition, errmessage); } while(0) |
| 642 | +#define StaticAssertExpr(condition, errmessage) \ |
| 643 | + ({ StaticAssertStmt(condition, errmessage); true; }) |
| 644 | +#else /* !HAVE__STATIC_ASSERT */ |
| 645 | +#define StaticAssertStmt(condition, errmessage) \ |
| 646 | + ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) |
| 647 | +#define StaticAssertExpr(condition, errmessage) \ |
| 648 | + StaticAssertStmt(condition, errmessage) |
| 649 | +#endif /* HAVE__STATIC_ASSERT */ |
| 650 | + |
| 651 | + |
| 652 | +/* |
| 653 | + * Compile-time checks that a variable (or expression) has the specified type. |
| 654 | + * |
| 655 | + * AssertVariableIsOfType() can be used as a statement. |
| 656 | + * AssertVariableIsOfTypeMacro() is intended for use in macros, eg |
| 657 | + * #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x)) |
| 658 | + * |
| 659 | + * If we don't have __builtin_types_compatible_p, we can still assert that |
| 660 | + * the types have the same size. This is far from ideal (especially on 32-bit |
| 661 | + * platforms) but it provides at least some coverage. |
| 662 | + */ |
| 663 | +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P |
| 664 | +#define AssertVariableIsOfType(varname, typename) \ |
| 665 | + StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \ |
| 666 | + CppAsString(varname) " does not have type " CppAsString(typename)) |
| 667 | +#define AssertVariableIsOfTypeMacro(varname, typename) \ |
| 668 | + ((void) StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \ |
| 669 | + CppAsString(varname) " does not have type " CppAsString(typename))) |
| 670 | +#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */ |
| 671 | +#define AssertVariableIsOfType(varname, typename) \ |
| 672 | + StaticAssertStmt(sizeof(varname) == sizeof(typename), \ |
| 673 | + CppAsString(varname) " does not have type " CppAsString(typename)) |
| 674 | +#define AssertVariableIsOfTypeMacro(varname, typename) \ |
| 675 | + ((void) StaticAssertExpr(sizeof(varname) == sizeof(typename), \ |
| 676 | + CppAsString(varname) " does not have type " CppAsString(typename))) |
| 677 | +#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ |
| 678 | + |
| 679 | + |
| 680 | +/* ---------------------------------------------------------------- |
| 681 | + * Section 7: widely useful macros |
554 | 682 | * ----------------------------------------------------------------
|
555 | 683 | */
|
556 | 684 | /*
|
@@ -693,61 +821,6 @@ typedef NameData *Name;
|
693 | 821 | } while (0)
|
694 | 822 |
|
695 | 823 |
|
696 |
| -/* |
697 |
| - * Macros to support compile-time assertion checks. |
698 |
| - * |
699 |
| - * If the "condition" (a compile-time-constant expression) evaluates to false, |
700 |
| - * throw a compile error using the "errmessage" (a string literal). |
701 |
| - * |
702 |
| - * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic |
703 |
| - * placement restrictions. These macros make it safe to use as a statement |
704 |
| - * or in an expression, respectively. |
705 |
| - * |
706 |
| - * Otherwise we fall back on a kluge that assumes the compiler will complain |
707 |
| - * about a negative width for a struct bit-field. This will not include a |
708 |
| - * helpful error message, but it beats not getting an error at all. |
709 |
| - */ |
710 |
| -#ifdef HAVE__STATIC_ASSERT |
711 |
| -#define StaticAssertStmt(condition, errmessage) \ |
712 |
| - do { _Static_assert(condition, errmessage); } while(0) |
713 |
| -#define StaticAssertExpr(condition, errmessage) \ |
714 |
| - ({ StaticAssertStmt(condition, errmessage); true; }) |
715 |
| -#else /* !HAVE__STATIC_ASSERT */ |
716 |
| -#define StaticAssertStmt(condition, errmessage) \ |
717 |
| - ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) |
718 |
| -#define StaticAssertExpr(condition, errmessage) \ |
719 |
| - StaticAssertStmt(condition, errmessage) |
720 |
| -#endif /* HAVE__STATIC_ASSERT */ |
721 |
| - |
722 |
| - |
723 |
| -/* |
724 |
| - * Compile-time checks that a variable (or expression) has the specified type. |
725 |
| - * |
726 |
| - * AssertVariableIsOfType() can be used as a statement. |
727 |
| - * AssertVariableIsOfTypeMacro() is intended for use in macros, eg |
728 |
| - * #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x)) |
729 |
| - * |
730 |
| - * If we don't have __builtin_types_compatible_p, we can still assert that |
731 |
| - * the types have the same size. This is far from ideal (especially on 32-bit |
732 |
| - * platforms) but it provides at least some coverage. |
733 |
| - */ |
734 |
| -#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P |
735 |
| -#define AssertVariableIsOfType(varname, typename) \ |
736 |
| - StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \ |
737 |
| - CppAsString(varname) " does not have type " CppAsString(typename)) |
738 |
| -#define AssertVariableIsOfTypeMacro(varname, typename) \ |
739 |
| - ((void) StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \ |
740 |
| - CppAsString(varname) " does not have type " CppAsString(typename))) |
741 |
| -#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */ |
742 |
| -#define AssertVariableIsOfType(varname, typename) \ |
743 |
| - StaticAssertStmt(sizeof(varname) == sizeof(typename), \ |
744 |
| - CppAsString(varname) " does not have type " CppAsString(typename)) |
745 |
| -#define AssertVariableIsOfTypeMacro(varname, typename) \ |
746 |
| - ((void) StaticAssertExpr(sizeof(varname) == sizeof(typename), \ |
747 |
| - CppAsString(varname) " does not have type " CppAsString(typename))) |
748 |
| -#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ |
749 |
| - |
750 |
| - |
751 | 824 | /*
|
752 | 825 | * Mark a point as unreachable in a portable fashion. This should preferably
|
753 | 826 | * be something that the compiler understands, to aid code generation.
|
@@ -781,7 +854,7 @@ typedef NameData *Name;
|
781 | 854 | #endif /* PG_USE_INLINE */
|
782 | 855 |
|
783 | 856 | /* ----------------------------------------------------------------
|
784 |
| - * Section 7: random stuff |
| 857 | + * Section 8: random stuff |
785 | 858 | * ----------------------------------------------------------------
|
786 | 859 | */
|
787 | 860 |
|
@@ -835,7 +908,7 @@ typedef NameData *Name;
|
835 | 908 |
|
836 | 909 |
|
837 | 910 | /* ----------------------------------------------------------------
|
838 |
| - * Section 8: system-specific hacks |
| 911 | + * Section 9: system-specific hacks |
839 | 912 | *
|
840 | 913 | * This should be limited to things that absolutely have to be
|
841 | 914 | * included in every source file. The port-specific header file
|
|
0 commit comments