Simplify our Assert infrastructure a little.

Remove the Trap and TrapMacro macros, which were nearly unused
and confusingly had the opposite condition polarity from the
otherwise-functionally-equivalent Assert macros.

Having done that, it's very hard to justify carrying the errorType
argument of ExceptionalCondition, so drop that too, and just
let it assume everything's an Assert.  This saves about 64K
of code space as of current HEAD.

Discussion: https://postgr.es/m/3928703.1665345117@sss.pgh.pa.us
This commit is contained in:
Tom Lane 2022-10-10 15:16:56 -04:00
parent 6291b2546c
commit 235eb4db98
5 changed files with 24 additions and 53 deletions

View File

@ -1319,7 +1319,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
*/ */
/* /*
* Check that VARTAG_SIZE won't hit a TrapMacro on a corrupt va_tag before * Check that VARTAG_SIZE won't hit an Assert on a corrupt va_tag before
* risking a call into att_addlength_pointer * risking a call into att_addlength_pointer
*/ */
if (VARATT_IS_EXTERNAL(tp + ctx->offset)) if (VARATT_IS_EXTERNAL(tp + ctx->offset))

View File

@ -28,20 +28,17 @@
*/ */
void void
ExceptionalCondition(const char *conditionName, ExceptionalCondition(const char *conditionName,
const char *errorType,
const char *fileName, const char *fileName,
int lineNumber) int lineNumber)
{ {
/* Report the failure on stderr (or local equivalent) */ /* Report the failure on stderr (or local equivalent) */
if (!PointerIsValid(conditionName) if (!PointerIsValid(conditionName)
|| !PointerIsValid(fileName) || !PointerIsValid(fileName))
|| !PointerIsValid(errorType))
write_stderr("TRAP: ExceptionalCondition: bad arguments in PID %d\n", write_stderr("TRAP: ExceptionalCondition: bad arguments in PID %d\n",
(int) getpid()); (int) getpid());
else else
write_stderr("TRAP: %s(\"%s\", File: \"%s\", Line: %d, PID: %d)\n", write_stderr("TRAP: failed Assert(\"%s\"), File: \"%s\", Line: %d, PID: %d\n",
errorType, conditionName, conditionName, fileName, lineNumber, (int) getpid());
fileName, lineNumber, (int) getpid());
/* Usually this shouldn't be needed, but make sure the msg went out */ /* Usually this shouldn't be needed, but make sure the msg went out */
fflush(stderr); fflush(stderr);

View File

@ -1832,8 +1832,7 @@ pg_re_throw(void)
} }
/* Doesn't return ... */ /* Doesn't return ... */
ExceptionalCondition("pg_re_throw tried to return", "FailedAssertion", ExceptionalCondition("pg_re_throw tried to return", __FILE__, __LINE__);
__FILE__, __LINE__);
} }

View File

@ -796,8 +796,6 @@ typedef NameData *Name;
#define AssertArg(condition) ((void)true) #define AssertArg(condition) ((void)true)
#define AssertState(condition) ((void)true) #define AssertState(condition) ((void)true)
#define AssertPointerAlignment(ptr, bndr) ((void)true) #define AssertPointerAlignment(ptr, bndr) ((void)true)
#define Trap(condition, errorType) ((void)true)
#define TrapMacro(condition, errorType) (true)
#elif defined(FRONTEND) #elif defined(FRONTEND)
@ -811,60 +809,38 @@ typedef NameData *Name;
#else /* USE_ASSERT_CHECKING && !FRONTEND */ #else /* USE_ASSERT_CHECKING && !FRONTEND */
/* /*
* Trap * Assert
* Generates an exception if the given condition is true. * Generates a fatal exception if the given condition is false.
*/ */
#define Trap(condition, errorType) \
do { \
if (condition) \
ExceptionalCondition(#condition, (errorType), \
__FILE__, __LINE__); \
} while (0)
/*
* TrapMacro is the same as Trap but it's intended for use in macros:
*
* #define foo(x) (AssertMacro(x != 0), bar(x))
*
* Isn't CPP fun?
*/
#define TrapMacro(condition, errorType) \
((bool) (! (condition) || \
(ExceptionalCondition(#condition, (errorType), \
__FILE__, __LINE__), 0)))
#define Assert(condition) \ #define Assert(condition) \
do { \ do { \
if (!(condition)) \ if (!(condition)) \
ExceptionalCondition(#condition, "FailedAssertion", \ ExceptionalCondition(#condition, __FILE__, __LINE__); \
__FILE__, __LINE__); \
} while (0) } while (0)
/*
* AssertMacro is the same as Assert but it's suitable for use in
* expression-like macros, for example:
*
* #define foo(x) (AssertMacro(x != 0), bar(x))
*/
#define AssertMacro(condition) \ #define AssertMacro(condition) \
((void) ((condition) || \ ((void) ((condition) || \
(ExceptionalCondition(#condition, "FailedAssertion", \ (ExceptionalCondition(#condition, __FILE__, __LINE__), 0)))
__FILE__, __LINE__), 0)))
#define AssertArg(condition) \ /*
do { \ * AssertArg and AssertState are identical to Assert. Some places use them
if (!(condition)) \ * to indicate that the complaint is specifically about a bad argument or
ExceptionalCondition(#condition, "BadArgument", \ * unexpected state, but this usage is largely obsolescent.
__FILE__, __LINE__); \ */
} while (0) #define AssertArg(condition) Assert(condition)
#define AssertState(condition) Assert(condition)
#define AssertState(condition) \
do { \
if (!(condition)) \
ExceptionalCondition(#condition, "BadState", \
__FILE__, __LINE__); \
} while (0)
/* /*
* Check that `ptr' is `bndr' aligned. * Check that `ptr' is `bndr' aligned.
*/ */
#define AssertPointerAlignment(ptr, bndr) \ #define AssertPointerAlignment(ptr, bndr) \
Trap(TYPEALIGN(bndr, (uintptr_t)(ptr)) != (uintptr_t)(ptr), \ Assert(TYPEALIGN(bndr, (uintptr_t)(ptr)) == (uintptr_t)(ptr))
"UnalignedPointer")
#endif /* USE_ASSERT_CHECKING && !FRONTEND */ #endif /* USE_ASSERT_CHECKING && !FRONTEND */
@ -876,7 +852,6 @@ typedef NameData *Name;
*/ */
#ifndef FRONTEND #ifndef FRONTEND
extern void ExceptionalCondition(const char *conditionName, extern void ExceptionalCondition(const char *conditionName,
const char *errorType,
const char *fileName, int lineNumber) pg_attribute_noreturn(); const char *fileName, int lineNumber) pg_attribute_noreturn();
#endif #endif

View File

@ -135,7 +135,7 @@ typedef enum vartag_external
((tag) == VARTAG_INDIRECT ? sizeof(varatt_indirect) : \ ((tag) == VARTAG_INDIRECT ? sizeof(varatt_indirect) : \
VARTAG_IS_EXPANDED(tag) ? sizeof(varatt_expanded) : \ VARTAG_IS_EXPANDED(tag) ? sizeof(varatt_expanded) : \
(tag) == VARTAG_ONDISK ? sizeof(varatt_external) : \ (tag) == VARTAG_ONDISK ? sizeof(varatt_external) : \
TrapMacro(true, "unrecognized TOAST vartag")) (AssertMacro(false), 0))
/* /*
* These structs describe the header of a varlena object that may have been * These structs describe the header of a varlena object that may have been