Skip to content

Commit e1d25de

Browse files
committed
Move Assert() definitions to c.h
This way, they can be used by frontend and backend code. We already supported that, but doing it this way allows us to mix true frontend files with backend files compiled in frontend environment. Author: Andres Freund
1 parent dd1569d commit e1d25de

File tree

3 files changed

+136
-125
lines changed

3 files changed

+136
-125
lines changed

src/include/c.h

Lines changed: 134 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@
3131
* 3) standard system types
3232
* 4) IsValid macros for system types
3333
* 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
3738
*
3839
* NOTE: since this file is included by both frontend and backend modules, it's
3940
* almost certainly wrong to put an "extern" declaration here. typedefs and
@@ -550,7 +551,134 @@ typedef NameData *Name;
550551
#define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN))
551552

552553
/* ----------------------------------------------------------------
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
554682
* ----------------------------------------------------------------
555683
*/
556684
/*
@@ -693,61 +821,6 @@ typedef NameData *Name;
693821
} while (0)
694822

695823

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-
751824
/*
752825
* Mark a point as unreachable in a portable fashion. This should preferably
753826
* be something that the compiler understands, to aid code generation.
@@ -781,7 +854,7 @@ typedef NameData *Name;
781854
#endif /* PG_USE_INLINE */
782855

783856
/* ----------------------------------------------------------------
784-
* Section 7: random stuff
857+
* Section 8: random stuff
785858
* ----------------------------------------------------------------
786859
*/
787860

@@ -835,7 +908,7 @@ typedef NameData *Name;
835908

836909

837910
/* ----------------------------------------------------------------
838-
* Section 8: system-specific hacks
911+
* Section 9: system-specific hacks
839912
*
840913
* This should be limited to things that absolutely have to be
841914
* included in every source file. The port-specific header file

src/include/postgres.h

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* ------- ------------------------------------------------
2626
* 1) variable-length datatypes (TOAST support)
2727
* 2) datum type + support macros
28-
* 3) exception handling definitions
28+
* 3) exception handling backend support
2929
*
3030
* NOTES
3131
*
@@ -634,62 +634,12 @@ extern Datum Float8GetDatum(float8 X);
634634

635635

636636
/* ----------------------------------------------------------------
637-
* Section 3: exception handling definitions
638-
* Assert, Trap, etc macros
637+
* Section 3: exception handling backend support
639638
* ----------------------------------------------------------------
640639
*/
641640

642641
extern PGDLLIMPORT bool assert_enabled;
643642

644-
/*
645-
* USE_ASSERT_CHECKING, if defined, turns on all the assertions.
646-
* - plai 9/5/90
647-
*
648-
* It should _NOT_ be defined in releases or in benchmark copies
649-
*/
650-
651-
/*
652-
* Trap
653-
* Generates an exception if the given condition is true.
654-
*/
655-
#define Trap(condition, errorType) \
656-
do { \
657-
if ((assert_enabled) && (condition)) \
658-
ExceptionalCondition(CppAsString(condition), (errorType), \
659-
__FILE__, __LINE__); \
660-
} while (0)
661-
662-
/*
663-
* TrapMacro is the same as Trap but it's intended for use in macros:
664-
*
665-
* #define foo(x) (AssertMacro(x != 0), bar(x))
666-
*
667-
* Isn't CPP fun?
668-
*/
669-
#define TrapMacro(condition, errorType) \
670-
((bool) ((! assert_enabled) || ! (condition) || \
671-
(ExceptionalCondition(CppAsString(condition), (errorType), \
672-
__FILE__, __LINE__), 0)))
673-
674-
#ifndef USE_ASSERT_CHECKING
675-
#define Assert(condition)
676-
#define AssertMacro(condition) ((void)true)
677-
#define AssertArg(condition)
678-
#define AssertState(condition)
679-
#else
680-
#define Assert(condition) \
681-
Trap(!(condition), "FailedAssertion")
682-
683-
#define AssertMacro(condition) \
684-
((void) TrapMacro(!(condition), "FailedAssertion"))
685-
686-
#define AssertArg(condition) \
687-
Trap(!(condition), "BadArgument")
688-
689-
#define AssertState(condition) \
690-
Trap(!(condition), "BadState")
691-
#endif /* USE_ASSERT_CHECKING */
692-
693643
extern void ExceptionalCondition(const char *conditionName,
694644
const char *errorType,
695645
const char *fileName, int lineNumber) __attribute__((noreturn));

src/include/postgres_fe.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,4 @@
2424

2525
#include "c.h"
2626

27-
/*
28-
* Assert() can be used in both frontend and backend code. In frontend code it
29-
* just calls the standard assert, if it's available. If use of assertions is
30-
* not configured, it does nothing.
31-
*/
32-
#ifdef USE_ASSERT_CHECKING
33-
#include <assert.h>
34-
#define Assert(p) assert(p)
35-
#else
36-
#define Assert(p)
37-
#endif
38-
3927
#endif /* POSTGRES_FE_H */

0 commit comments

Comments
 (0)