Simplify our Assert infrastructure a little.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 10 Oct 2022 19:16:56 +0000 (15:16 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 10 Oct 2022 19:16:56 +0000 (15:16 -0400)
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

contrib/amcheck/verify_heapam.c
src/backend/utils/error/assert.c
src/backend/utils/error/elog.c
src/include/c.h
src/include/postgres.h

index d33f33f1703a633b210557bcac7b51321bb58665..83dc728011552f6d27a988afc078b2f37aaa3ed8 100644 (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
         */
        if (VARATT_IS_EXTERNAL(tp + ctx->offset))
index 2da512a2f1e160b9725b83a4976a78fc1081f48c..ac6173e660b8d1a52f478a849c6b055bb3843346 100644 (file)
  */
 void
 ExceptionalCondition(const char *conditionName,
-                                        const char *errorType,
                                         const char *fileName,
                                         int lineNumber)
 {
        /* Report the failure on stderr (or local equivalent) */
        if (!PointerIsValid(conditionName)
-               || !PointerIsValid(fileName)
-               || !PointerIsValid(errorType))
+               || !PointerIsValid(fileName))
                write_stderr("TRAP: ExceptionalCondition: bad arguments in PID %d\n",
                                         (int) getpid());
        else
-               write_stderr("TRAP: %s(\"%s\", File: \"%s\", Line: %d, PID: %d)\n",
-                                        errorType, conditionName,
-                                        fileName, lineNumber, (int) getpid());
+               write_stderr("TRAP: failed Assert(\"%s\"), File: \"%s\", Line: %d, PID: %d\n",
+                                        conditionName, fileName, lineNumber, (int) getpid());
 
        /* Usually this shouldn't be needed, but make sure the msg went out */
        fflush(stderr);
index eb724a9d7f27813f06e4145967c45348fe08066c..6e0a66c29ee98032ff61e304921ca220526060b6 100644 (file)
@@ -1832,8 +1832,7 @@ pg_re_throw(void)
        }
 
        /* Doesn't return ... */
-       ExceptionalCondition("pg_re_throw tried to return", "FailedAssertion",
-                                                __FILE__, __LINE__);
+       ExceptionalCondition("pg_re_throw tried to return", __FILE__, __LINE__);
 }
 
 
index 405d53cb56b9c78e327dcd297676813af1eaa579..bebbfd83d16a5620bc30a629fbf95abe763ea6f3 100644 (file)
@@ -796,8 +796,6 @@ typedef NameData *Name;
 #define AssertArg(condition)   ((void)true)
 #define AssertState(condition) ((void)true)
 #define AssertPointerAlignment(ptr, bndr)      ((void)true)
-#define Trap(condition, errorType)     ((void)true)
-#define TrapMacro(condition, errorType) (true)
 
 #elif defined(FRONTEND)
 
@@ -811,60 +809,38 @@ typedef NameData *Name;
 #else                                                  /* USE_ASSERT_CHECKING && !FRONTEND */
 
 /*
- * Trap
- *             Generates an exception if the given condition is true.
+ * Assert
+ *             Generates a fatal exception if the given condition is false.
  */
-#define Trap(condition, errorType) \
+#define Assert(condition) \
        do { \
-               if (condition) \
-                       ExceptionalCondition(#condition, (errorType), \
-                                                                __FILE__, __LINE__); \
+               if (!(condition)) \
+                       ExceptionalCondition(#condition, __FILE__, __LINE__); \
        } while (0)
 
 /*
- *     TrapMacro is the same as Trap but it's intended for use in macros:
+ * 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))
- *
- *     Isn't CPP fun?
  */
-#define TrapMacro(condition, errorType) \
-       ((bool) (! (condition) || \
-                        (ExceptionalCondition(#condition, (errorType), \
-                                                                  __FILE__, __LINE__), 0)))
-
-#define Assert(condition) \
-       do { \
-               if (!(condition)) \
-                       ExceptionalCondition(#condition, "FailedAssertion", \
-                                                                __FILE__, __LINE__); \
-       } while (0)
-
 #define AssertMacro(condition) \
        ((void) ((condition) || \
-                        (ExceptionalCondition(#condition, "FailedAssertion", \
-                                                                  __FILE__, __LINE__), 0)))
+                        (ExceptionalCondition(#condition, __FILE__, __LINE__), 0)))
 
-#define AssertArg(condition) \
-       do { \
-               if (!(condition)) \
-                       ExceptionalCondition(#condition, "BadArgument", \
-                                                                __FILE__, __LINE__); \
-       } while (0)
-
-#define AssertState(condition) \
-       do { \
-               if (!(condition)) \
-                       ExceptionalCondition(#condition, "BadState", \
-                                                                __FILE__, __LINE__); \
-       } while (0)
+/*
+ * AssertArg and AssertState are identical to Assert.  Some places use them
+ * to indicate that the complaint is specifically about a bad argument or
+ * unexpected state, but this usage is largely obsolescent.
+ */
+#define AssertArg(condition) Assert(condition)
+#define AssertState(condition) Assert(condition)
 
 /*
  * Check that `ptr' is `bndr' aligned.
  */
 #define AssertPointerAlignment(ptr, bndr) \
-       Trap(TYPEALIGN(bndr, (uintptr_t)(ptr)) != (uintptr_t)(ptr), \
-                "UnalignedPointer")
+       Assert(TYPEALIGN(bndr, (uintptr_t)(ptr)) == (uintptr_t)(ptr))
 
 #endif                                                 /* USE_ASSERT_CHECKING && !FRONTEND */
 
@@ -876,7 +852,6 @@ typedef NameData *Name;
  */
 #ifndef FRONTEND
 extern void ExceptionalCondition(const char *conditionName,
-                                                                const char *errorType,
                                                                 const char *fileName, int lineNumber) pg_attribute_noreturn();
 #endif
 
index 5f6a1e3d5a23452386cb43efc4aa1ba88c9b0f04..54730dfb381ed86d1f88af90fb463aa4dcae8678 100644 (file)
@@ -135,7 +135,7 @@ typedef enum vartag_external
        ((tag) == VARTAG_INDIRECT ? sizeof(varatt_indirect) : \
         VARTAG_IS_EXPANDED(tag) ? sizeof(varatt_expanded) : \
         (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