A number of static assertions could be moved to better places.

We first added StaticAssertStmt() in 2012, which required all static assertions to be inside function bodies. We then added StaticAssertDecl() in 2020, which enabled static assertions on file level. We have a number of calls that were stuck in not-really-related functions for this historical reason. This patch set cleans that up.

0001-Update-static-assert-usage-comment.patch

This updates the usage information in c.h to be more current and precise.

0002-Move-array-size-related-static-assertions.patch

This moves some obviously poorly placed ones.

0003-Move-some-static-assertions-to-better-places.patch

This moves some that I thought were suboptimally placed but it could be debated or refined.

0004-Use-StaticAssertDecl-where-possible.patch

This just changes some StaticAssertStmt() to StaticAssertDecl() where appropriate. It's optional.
From ca1cb9e59e2216f1bfed234792379a46e425e105 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Thu, 8 Dec 2022 14:30:01 +0100
Subject: [PATCH 1/4] Update static assert usage comment

Since we added StaticAssertStmt() first before StaticAssertDecl(), the
instructions in c.h are a bit backwards from the "native" way static
assertions are meant to be used in C.  Update this to make it more
precise.
---
 src/include/c.h | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/src/include/c.h b/src/include/c.h
index 98cdd285dd..bd6d8e5bf5 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -847,47 +847,50 @@ extern void ExceptionalCondition(const char 
*conditionName,
  * If the "condition" (a compile-time-constant expression) evaluates to false,
  * throw a compile error using the "errmessage" (a string literal).
  *
- * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic
- * placement restrictions.  Macros StaticAssertStmt() and StaticAssertExpr()
+ * C11 has _Static_assert(), and most C99 compilers already support that.  For
+ * portability, we wrap it into StaticAssertDecl().  _Static_assert() is a
+ * "declaration", and so it must be placed where for example a variable
+ * declaration would be valid.  As long as we compile with
+ * -Wno-declaration-after-statement, that also means it cannot be placed after
+ * statements in a function.  Macros StaticAssertStmt() and StaticAssertExpr()
  * make it safe to use as a statement or in an expression, respectively.
- * The macro StaticAssertDecl() is suitable for use at file scope (outside of
- * any function).
  *
- * Otherwise we fall back on a kluge that assumes the compiler will complain
- * about a negative width for a struct bit-field.  This will not include a
- * helpful error message, but it beats not getting an error at all.
+ * For compilers without _Static_assert(), we fall back on a kluge that
+ * assumes the compiler will complain about a negative width for a struct
+ * bit-field.  This will not include a helpful error message, but it beats not
+ * getting an error at all.
  */
 #ifndef __cplusplus
 #ifdef HAVE__STATIC_ASSERT
+#define StaticAssertDecl(condition, errmessage) \
+       _Static_assert(condition, errmessage)
 #define StaticAssertStmt(condition, errmessage) \
        do { _Static_assert(condition, errmessage); } while(0)
 #define StaticAssertExpr(condition, errmessage) \
        ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
-#define StaticAssertDecl(condition, errmessage) \
-       _Static_assert(condition, errmessage)
 #else                                                  /* !HAVE__STATIC_ASSERT 
*/
+#define StaticAssertDecl(condition, errmessage) \
+       extern void static_assert_func(int static_assert_failure[(condition) ? 
1 : -1])
 #define StaticAssertStmt(condition, errmessage) \
        ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : 
-1; }))
 #define StaticAssertExpr(condition, errmessage) \
        StaticAssertStmt(condition, errmessage)
-#define StaticAssertDecl(condition, errmessage) \
-       extern void static_assert_func(int static_assert_failure[(condition) ? 
1 : -1])
 #endif                                                 /* HAVE__STATIC_ASSERT 
*/
 #else                                                  /* C++ */
 #if defined(__cpp_static_assert) && __cpp_static_assert >= 200410
+#define StaticAssertDecl(condition, errmessage) \
+       static_assert(condition, errmessage)
 #define StaticAssertStmt(condition, errmessage) \
        static_assert(condition, errmessage)
 #define StaticAssertExpr(condition, errmessage) \
        ({ static_assert(condition, errmessage); })
-#define StaticAssertDecl(condition, errmessage) \
-       static_assert(condition, errmessage)
 #else                                                  /* !__cpp_static_assert 
*/
+#define StaticAssertDecl(condition, errmessage) \
+       extern void static_assert_func(int static_assert_failure[(condition) ? 
1 : -1])
 #define StaticAssertStmt(condition, errmessage) \
        do { struct static_assert_struct { int static_assert_failure : 
(condition) ? 1 : -1; }; } while(0)
 #define StaticAssertExpr(condition, errmessage) \
        ((void) ({ StaticAssertStmt(condition, errmessage); }))
-#define StaticAssertDecl(condition, errmessage) \
-       extern void static_assert_func(int static_assert_failure[(condition) ? 
1 : -1])
 #endif                                                 /* __cpp_static_assert 
*/
 #endif                                                 /* C++ */
 

base-commit: 07c29ca7fe30839a75d15b43c13b290a59a60ddf
-- 
2.38.1

From 2998b8d24aed74221fede4954155b31fc7601b62 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Thu, 8 Dec 2022 14:32:43 +0100
Subject: [PATCH 2/4] Move array-size-related static assertions

Since the addition of StaticAssertDecl(), we can put static assertions
at the file level.  Some static assertions that check the size of an
array against some constant can now be moved closer to where those
things are defined, instead of being stuck in some unrelated function
body.
---
 src/backend/catalog/dependency.c   | 12 ++++++------
 src/backend/libpq/hba.c            | 12 ++++++------
 src/backend/utils/cache/syscache.c |  6 +++---
 src/common/encnames.c              |  6 +++---
 4 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 7f3e64b5ae..30394dccf5 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -191,6 +191,12 @@ static const Oid object_classes[] = {
        TransformRelationId                     /* OCLASS_TRANSFORM */
 };
 
+/*
+ * Make sure object_classes is kept up to date with the ObjectClass enum.
+ */
+StaticAssertDecl(lengthof(object_classes) == LAST_OCLASS + 1,
+                                "object_classes[] must cover all 
ObjectClasses");
+
 
 static void findDependentObjects(const ObjectAddress *object,
                                                                 int objflags,
@@ -2550,12 +2556,6 @@ add_object_address(ObjectClass oclass, Oid objectId, 
int32 subId,
 {
        ObjectAddress *item;
 
-       /*
-        * Make sure object_classes is kept up to date with the ObjectClass 
enum.
-        */
-       StaticAssertStmt(lengthof(object_classes) == LAST_OCLASS + 1,
-                                        "object_classes[] must cover all 
ObjectClasses");
-
        /* enlarge array if needed */
        if (addrs->numrefs >= addrs->maxrefs)
        {
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 46e91441ac..870b907697 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -127,6 +127,12 @@ static const char *const UserAuthName[] =
        "peer"
 };
 
+/*
+ * Make sure UserAuthName[] tracks additions to the UserAuth enum
+ */
+StaticAssertDecl(lengthof(UserAuthName) == USER_AUTH_LAST + 1,
+                                "UserAuthName[] must match the UserAuth enum");
+
 
 static List *tokenize_expand_file(List *tokens, const char *outer_filename,
                                                                  const char 
*inc_filename, int elevel,
@@ -3117,11 +3123,5 @@ hba_getauthmethod(hbaPort *port)
 const char *
 hba_authname(UserAuth auth_method)
 {
-       /*
-        * Make sure UserAuthName[] tracks additions to the UserAuth enum
-        */
-       StaticAssertStmt(lengthof(UserAuthName) == USER_AUTH_LAST + 1,
-                                        "UserAuthName[] must match the 
UserAuth enum");
-
        return UserAuthName[auth_method];
 }
diff --git a/src/backend/utils/cache/syscache.c 
b/src/backend/utils/cache/syscache.c
index eec644ec84..bb3dd6f4d2 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -1040,6 +1040,9 @@ static const struct cachedesc cacheinfo[] = {
        }
 };
 
+StaticAssertDecl(SysCacheSize == (int) lengthof(cacheinfo),
+                                "SysCacheSize does not match syscache.c's 
array");
+
 static CatCache *SysCache[SysCacheSize];
 
 static bool CacheInitialized = false;
@@ -1068,9 +1071,6 @@ InitCatalogCache(void)
 {
        int                     cacheId;
 
-       StaticAssertStmt(SysCacheSize == (int) lengthof(cacheinfo),
-                                        "SysCacheSize does not match 
syscache.c's array");
-
        Assert(!CacheInitialized);
 
        SysCacheRelationOidSize = SysCacheSupportingRelOidSize = 0;
diff --git a/src/common/encnames.c b/src/common/encnames.c
index 596a23b64d..2329db572b 100644
--- a/src/common/encnames.c
+++ b/src/common/encnames.c
@@ -451,6 +451,9 @@ static const char *const pg_enc2icu_tbl[] =
        "KOI8-U",                                       /* PG_KOI8U */
 };
 
+StaticAssertDecl(lengthof(pg_enc2icu_tbl) == PG_ENCODING_BE_LAST + 1,
+                                "pg_enc2icu_tbl incomplete");
+
 
 /*
  * Is this encoding supported by ICU?
@@ -469,9 +472,6 @@ is_encoding_supported_by_icu(int encoding)
 const char *
 get_encoding_name_for_icu(int encoding)
 {
-       StaticAssertStmt(lengthof(pg_enc2icu_tbl) == PG_ENCODING_BE_LAST + 1,
-                                        "pg_enc2icu_tbl incomplete");
-
        if (!PG_VALID_BE_ENCODING(encoding))
                return NULL;
        return pg_enc2icu_tbl[encoding];
-- 
2.38.1

From dd74c128e4d98167e921adaee09f21c2cff7a155 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Thu, 8 Dec 2022 14:34:47 +0100
Subject: [PATCH 3/4] Move some static assertions to better places

Since the addition of StaticAssertDecl(), we can put static assertions
at the file level.  This moves some static assertions out of function
bodies, where they might have been stuck out of necessity, to perhaps
better places at the file level or in header files.
---
 src/backend/access/heap/heapam.c     |  4 ----
 src/backend/access/nbtree/nbtutils.c |  7 -------
 src/backend/access/transam/xlog.c    |  9 ---------
 src/backend/storage/lmgr/lwlock.c    |  9 +++------
 src/backend/storage/page/itemptr.c   | 14 +++++++-------
 src/backend/utils/adt/tsginidx.c     |  2 --
 src/backend/utils/adt/xid8funcs.c    | 15 ++++++++-------
 src/common/controldata_utils.c       |  8 --------
 src/include/access/gin.h             |  3 +++
 src/include/access/htup_details.h    |  3 +++
 src/include/access/nbtree.h          |  7 +++++++
 src/include/catalog/pg_control.h     |  8 ++++++++
 src/include/storage/lwlock.h         |  3 +++
 13 files changed, 42 insertions(+), 50 deletions(-)

diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 747db50376..383e1ddde4 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -5783,10 +5783,6 @@ heap_finish_speculative(Relation relation, ItemPointer 
tid)
 
        htup = (HeapTupleHeader) PageGetItem(page, lp);
 
-       /* SpecTokenOffsetNumber should be distinguishable from any real offset 
*/
-       StaticAssertStmt(MaxOffsetNumber < SpecTokenOffsetNumber,
-                                        "invalid speculative token constant");
-
        /* NO EREPORT(ERROR) from here till changes are logged */
        START_CRIT_SECTION();
 
diff --git a/src/backend/access/nbtree/nbtutils.c 
b/src/backend/access/nbtree/nbtutils.c
index ff260c393a..10f13e6d41 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -2486,13 +2486,6 @@ _bt_check_natts(Relation rel, bool heapkeyspace, Page 
page, OffsetNumber offnum)
        Assert(offnum >= FirstOffsetNumber &&
                   offnum <= PageGetMaxOffsetNumber(page));
 
-       /*
-        * Mask allocated for number of keys in index tuple must be able to fit
-        * maximum possible number of index attributes
-        */
-       StaticAssertStmt(BT_OFFSET_MASK >= INDEX_MAX_KEYS,
-                                        "BT_OFFSET_MASK can't fit 
INDEX_MAX_KEYS");
-
        itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
        tupnatts = BTreeTupleGetNAtts(itup, rel);
 
diff --git a/src/backend/access/transam/xlog.c 
b/src/backend/access/transam/xlog.c
index a31fbbff78..91473b00d9 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -3883,15 +3883,6 @@ WriteControlFile(void)
        int                     fd;
        char            buffer[PG_CONTROL_FILE_SIZE];   /* need not be aligned 
*/
 
-       /*
-        * Ensure that the size of the pg_control data structure is sane.  See 
the
-        * comments for these symbols in pg_control.h.
-        */
-       StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_MAX_SAFE_SIZE,
-                                        "pg_control is too large for atomic 
disk writes");
-       StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_FILE_SIZE,
-                                        "sizeof(ControlFileData) exceeds 
PG_CONTROL_FILE_SIZE");
-
        /*
         * Initialize version and compatibility-check fields
         */
diff --git a/src/backend/storage/lmgr/lwlock.c 
b/src/backend/storage/lmgr/lwlock.c
index a5ad36ca78..528b2e9643 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -108,6 +108,9 @@ extern slock_t *ShmemLock;
 /* Must be greater than MAX_BACKENDS - which is 2^23-1, so we're fine. */
 #define LW_SHARED_MASK                         ((uint32) ((1 << 24)-1))
 
+StaticAssertDecl(LW_VAL_EXCLUSIVE > (uint32) MAX_BACKENDS,
+                                "MAX_BACKENDS too big for lwlock.c");
+
 /*
  * There are three sorts of LWLock "tranches":
  *
@@ -466,12 +469,6 @@ LWLockShmemSize(void)
 void
 CreateLWLocks(void)
 {
-       StaticAssertStmt(LW_VAL_EXCLUSIVE > (uint32) MAX_BACKENDS,
-                                        "MAX_BACKENDS too big for lwlock.c");
-
-       StaticAssertStmt(sizeof(LWLock) <= LWLOCK_PADDED_SIZE,
-                                        "Miscalculated LWLock padding");
-
        if (!IsUnderPostmaster)
        {
                Size            spaceLocks = LWLockShmemSize();
diff --git a/src/backend/storage/page/itemptr.c 
b/src/backend/storage/page/itemptr.c
index 9011337aa8..c1a84acdb6 100644
--- a/src/backend/storage/page/itemptr.c
+++ b/src/backend/storage/page/itemptr.c
@@ -17,6 +17,13 @@
 #include "storage/itemptr.h"
 
 
+/*
+ * We really want ItemPointerData to be exactly 6 bytes.  This is rather a
+ * random place to check, but there is no better place.
+ */
+StaticAssertDecl(sizeof(ItemPointerData) == 3 * sizeof(uint16),
+                                "ItemPointerData struct is improperly padded");
+
 /*
  * ItemPointerEquals
  *     Returns true if both item pointers point to the same item,
@@ -28,13 +35,6 @@
 bool
 ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
 {
-       /*
-        * We really want ItemPointerData to be exactly 6 bytes.  This is 
rather a
-        * random place to check, but there is no better place.
-        */
-       StaticAssertStmt(sizeof(ItemPointerData) == 3 * sizeof(uint16),
-                                        "ItemPointerData struct is improperly 
padded");
-
        if (ItemPointerGetBlockNumber(pointer1) ==
                ItemPointerGetBlockNumber(pointer2) &&
                ItemPointerGetOffsetNumber(pointer1) ==
diff --git a/src/backend/utils/adt/tsginidx.c b/src/backend/utils/adt/tsginidx.c
index e272fca075..cf23aeb5ea 100644
--- a/src/backend/utils/adt/tsginidx.c
+++ b/src/backend/utils/adt/tsginidx.c
@@ -236,8 +236,6 @@ gin_tsquery_consistent(PG_FUNCTION_ARGS)
                 * query.
                 */
                gcv.first_item = GETQUERY(query);
-               StaticAssertStmt(sizeof(GinTernaryValue) == sizeof(bool),
-                                                "sizes of GinTernaryValue and 
bool are not equal");
                gcv.check = (GinTernaryValue *) check;
                gcv.map_item_operand = (int *) (extra_data[0]);
 
diff --git a/src/backend/utils/adt/xid8funcs.c 
b/src/backend/utils/adt/xid8funcs.c
index d8e40b3b96..afc3dc8a47 100644
--- a/src/backend/utils/adt/xid8funcs.c
+++ b/src/backend/utils/adt/xid8funcs.c
@@ -74,6 +74,14 @@ typedef struct
 #define PG_SNAPSHOT_MAX_NXIP \
        ((MaxAllocSize - offsetof(pg_snapshot, xip)) / 
sizeof(FullTransactionId))
 
+/*
+ * Compile-time limits on the procarray (MAX_BACKENDS processes plus
+ * MAX_BACKENDS prepared transactions) guarantee nxip won't be too large.
+ */
+StaticAssertDecl(MAX_BACKENDS * 2 <= PG_SNAPSHOT_MAX_NXIP,
+                                "possible overflow in pg_current_snapshot()");
+
+
 /*
  * Helper to get a TransactionId from a 64-bit xid with wraparound detection.
  *
@@ -403,13 +411,6 @@ pg_current_snapshot(PG_FUNCTION_ARGS)
        if (cur == NULL)
                elog(ERROR, "no active snapshot set");
 
-       /*
-        * Compile-time limits on the procarray (MAX_BACKENDS processes plus
-        * MAX_BACKENDS prepared transactions) guarantee nxip won't be too 
large.
-        */
-       StaticAssertStmt(MAX_BACKENDS * 2 <= PG_SNAPSHOT_MAX_NXIP,
-                                        "possible overflow in 
pg_current_snapshot()");
-
        /* allocate */
        nxip = cur->xcnt;
        snap = palloc(PG_SNAPSHOT_SIZE(nxip));
diff --git a/src/common/controldata_utils.c b/src/common/controldata_utils.c
index 2d1f35bbd1..5c654746fa 100644
--- a/src/common/controldata_utils.c
+++ b/src/common/controldata_utils.c
@@ -149,14 +149,6 @@ update_controlfile(const char *DataDir,
        char            buffer[PG_CONTROL_FILE_SIZE];
        char            ControlFilePath[MAXPGPATH];
 
-       /*
-        * Apply the same static assertions as in backend's WriteControlFile().
-        */
-       StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_MAX_SAFE_SIZE,
-                                        "pg_control is too large for atomic 
disk writes");
-       StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_FILE_SIZE,
-                                        "sizeof(ControlFileData) exceeds 
PG_CONTROL_FILE_SIZE");
-
        /* Update timestamp  */
        ControlFile->time = (pg_time_t) time(NULL);
 
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index fff861e219..119ed685bb 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -57,6 +57,9 @@ typedef struct GinStatsData
  */
 typedef char GinTernaryValue;
 
+StaticAssertDecl(sizeof(GinTernaryValue) == sizeof(bool),
+                                "sizes of GinTernaryValue and bool are not 
equal");
+
 #define GIN_FALSE              0               /* item is not present / does 
not match */
 #define GIN_TRUE               1               /* item is present / matches */
 #define GIN_MAYBE              2               /* don't know if item is 
present / don't know
diff --git a/src/include/access/htup_details.h 
b/src/include/access/htup_details.h
index 9561c835f2..c1af814e8d 100644
--- a/src/include/access/htup_details.h
+++ b/src/include/access/htup_details.h
@@ -426,6 +426,9 @@ do { \
        (tup)->t_choice.t_heap.t_field3.t_xvac = (xid); \
 } while (0)
 
+StaticAssertDecl(MaxOffsetNumber < SpecTokenOffsetNumber,
+                                "invalid speculative token constant");
+
 #define HeapTupleHeaderIsSpeculative(tup) \
 ( \
        (ItemPointerGetOffsetNumberNoCheck(&(tup)->t_ctid) == 
SpecTokenOffsetNumber) \
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 8e4f6864e5..7d5a6fa558 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -466,6 +466,13 @@ typedef struct BTVacState
 #define BT_PIVOT_HEAP_TID_ATTR         0x1000
 #define BT_IS_POSTING                          0x2000
 
+/*
+ * Mask allocated for number of keys in index tuple must be able to fit
+ * maximum possible number of index attributes
+ */
+StaticAssertDecl(BT_OFFSET_MASK >= INDEX_MAX_KEYS,
+                                "BT_OFFSET_MASK can't fit INDEX_MAX_KEYS");
+
 /*
  * Note: BTreeTupleIsPivot() can have false negatives (but not false
  * positives) when used with !heapkeyspace indexes
diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h
index 06368e2366..1b648b7196 100644
--- a/src/include/catalog/pg_control.h
+++ b/src/include/catalog/pg_control.h
@@ -247,4 +247,12 @@ typedef struct ControlFileData
  */
 #define PG_CONTROL_FILE_SIZE           8192
 
+/*
+ * Ensure that the size of the pg_control data structure is sane.
+ */
+StaticAssertDecl(sizeof(ControlFileData) <= PG_CONTROL_MAX_SAFE_SIZE,
+                                "pg_control is too large for atomic disk 
writes");
+StaticAssertDecl(sizeof(ControlFileData) <= PG_CONTROL_FILE_SIZE,
+                                "sizeof(ControlFileData) exceeds 
PG_CONTROL_FILE_SIZE");
+
 #endif                                                 /* PG_CONTROL_H */
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index a494cb598f..dd818e16ab 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -59,6 +59,9 @@ typedef struct LWLock
  */
 #define LWLOCK_PADDED_SIZE     PG_CACHE_LINE_SIZE
 
+StaticAssertDecl(sizeof(LWLock) <= LWLOCK_PADDED_SIZE,
+                                "Miscalculated LWLock padding");
+
 /* LWLock, padded to a full cache line size */
 typedef union LWLockPadded
 {
-- 
2.38.1

From c7c7e648466e1c70dd303570031e8b23bfbb38dc Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Thu, 8 Dec 2022 14:34:07 +0100
Subject: [PATCH 4/4] Use StaticAssertDecl where possible

When the static assertion appears in a position where a declaration is
allowed, then using StaticAssertDecl() is more native than
StaticAssertStmt().
---
 src/backend/access/heap/heapam.c      |  2 +-
 src/backend/access/transam/clog.c     |  2 +-
 src/backend/backup/basebackup.c       |  4 ++--
 src/backend/executor/execExprInterp.c |  2 +-
 src/backend/libpq/auth-scram.c        |  2 +-
 src/backend/port/atomics.c            |  6 +++---
 src/backend/utils/adt/numeric.c       |  3 ++-
 src/backend/utils/mmgr/aset.c         |  6 +++---
 src/backend/utils/mmgr/generation.c   |  2 +-
 src/backend/utils/mmgr/slab.c         |  2 +-
 src/common/checksum_helper.c          | 10 +++++-----
 src/include/common/int128.h           |  2 +-
 12 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 383e1ddde4..42756a9e6d 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -7917,7 +7917,7 @@ index_delete_sort(TM_IndexDeleteOp *delstate)
        const int       gaps[9] = {1968, 861, 336, 112, 48, 21, 7, 3, 1};
 
        /* Think carefully before changing anything here -- keep swaps cheap */
-       StaticAssertStmt(sizeof(TM_IndexDelete) <= 8,
+       StaticAssertDecl(sizeof(TM_IndexDelete) <= 8,
                                         "element size exceeds 8 bytes");
 
        for (int g = 0; g < lengthof(gaps); g++)
diff --git a/src/backend/access/transam/clog.c 
b/src/backend/access/transam/clog.c
index 77d9894dab..8832efc7c1 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -275,7 +275,7 @@ TransactionIdSetPageStatus(TransactionId xid, int nsubxids,
                                                   bool all_xact_same_page)
 {
        /* Can't use group update when PGPROC overflows. */
-       StaticAssertStmt(THRESHOLD_SUBTRANS_CLOG_OPT <= 
PGPROC_MAX_CACHED_SUBXIDS,
+       StaticAssertDecl(THRESHOLD_SUBTRANS_CLOG_OPT <= 
PGPROC_MAX_CACHED_SUBXIDS,
                                         "group clog threshold less than PGPROC 
cached subxids");
 
        /*
diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c
index 74fb529380..f28bf10df3 100644
--- a/src/backend/backup/basebackup.c
+++ b/src/backend/backup/basebackup.c
@@ -370,7 +370,7 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
                        else
                        {
                                /* Properly terminate the tarfile. */
-                               StaticAssertStmt(2 * TAR_BLOCK_SIZE <= BLCKSZ,
+                               StaticAssertDecl(2 * TAR_BLOCK_SIZE <= BLCKSZ,
                                                                 "BLCKSZ too 
small for 2 tar blocks");
                                memset(sink->bbs_buffer, 0, 2 * TAR_BLOCK_SIZE);
                                bbsink_archive_contents(sink, 2 * 
TAR_BLOCK_SIZE);
@@ -1744,7 +1744,7 @@ _tarWriteHeader(bbsink *sink, const char *filename, const 
char *linktarget,
                 * large enough to fit an entire tar block. We double-check by 
means
                 * of these assertions.
                 */
-               StaticAssertStmt(TAR_BLOCK_SIZE <= BLCKSZ,
+               StaticAssertDecl(TAR_BLOCK_SIZE <= BLCKSZ,
                                                 "BLCKSZ too small for tar 
block");
                Assert(sink->bbs_buffer_length >= TAR_BLOCK_SIZE);
 
diff --git a/src/backend/executor/execExprInterp.c 
b/src/backend/executor/execExprInterp.c
index 1dab2787b7..ec26ae506f 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -496,7 +496,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, 
bool *isnull)
                &&CASE_EEOP_LAST
        };
 
-       StaticAssertStmt(EEOP_LAST + 1 == lengthof(dispatch_table),
+       StaticAssertDecl(EEOP_LAST + 1 == lengthof(dispatch_table),
                                         "dispatch_table out of whack with 
ExprEvalOp");
 
        if (unlikely(state == NULL))
diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c
index ee7f52218a..c9bab85e82 100644
--- a/src/backend/libpq/auth-scram.c
+++ b/src/backend/libpq/auth-scram.c
@@ -1443,7 +1443,7 @@ scram_mock_salt(const char *username)
         * not larger than the SHA256 digest length.  If the salt is smaller, 
the
         * caller will just ignore the extra data.)
         */
-       StaticAssertStmt(PG_SHA256_DIGEST_LENGTH >= SCRAM_DEFAULT_SALT_LEN,
+       StaticAssertDecl(PG_SHA256_DIGEST_LENGTH >= SCRAM_DEFAULT_SALT_LEN,
                                         "salt length greater than SHA256 
digest length");
 
        ctx = pg_cryptohash_create(PG_SHA256);
diff --git a/src/backend/port/atomics.c b/src/backend/port/atomics.c
index ba274bed93..ff4771ae37 100644
--- a/src/backend/port/atomics.c
+++ b/src/backend/port/atomics.c
@@ -54,7 +54,7 @@ pg_extern_compiler_barrier(void)
 void
 pg_atomic_init_flag_impl(volatile pg_atomic_flag *ptr)
 {
-       StaticAssertStmt(sizeof(ptr->sema) >= sizeof(slock_t),
+       StaticAssertDecl(sizeof(ptr->sema) >= sizeof(slock_t),
                                         "size mismatch of atomic_flag vs 
slock_t");
 
 #ifndef HAVE_SPINLOCKS
@@ -105,7 +105,7 @@ pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag 
*ptr)
 void
 pg_atomic_init_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 val_)
 {
-       StaticAssertStmt(sizeof(ptr->sema) >= sizeof(slock_t),
+       StaticAssertDecl(sizeof(ptr->sema) >= sizeof(slock_t),
                                         "size mismatch of atomic_uint32 vs 
slock_t");
 
        /*
@@ -181,7 +181,7 @@ pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 
*ptr, int32 add_)
 void
 pg_atomic_init_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 val_)
 {
-       StaticAssertStmt(sizeof(ptr->sema) >= sizeof(slock_t),
+       StaticAssertDecl(sizeof(ptr->sema) >= sizeof(slock_t),
                                         "size mismatch of atomic_uint64 vs 
slock_t");
 
        /*
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 7f0e93aa80..813e9d777d 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -4176,7 +4176,8 @@ int64_div_fast_to_numeric(int64 val1, int log10val2)
        {
                static int      pow10[] = {1, 10, 100, 1000};
 
-               StaticAssertStmt(lengthof(pow10) == DEC_DIGITS, "mismatch with 
DEC_DIGITS");
+               StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with 
DEC_DIGITS");
+
                if (unlikely(pg_mul_s64_overflow(val1, pow10[DEC_DIGITS - m], 
&val1)))
                {
                        /*
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index b6a8bbcd59..b45a34abce 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -306,7 +306,7 @@ AllocSetFreeIndex(Size size)
                                        tsize;
 
                /* Statically assert that we only have a 16-bit input value. */
-               StaticAssertStmt(ALLOC_CHUNK_LIMIT < (1 << 16),
+               StaticAssertDecl(ALLOC_CHUNK_LIMIT < (1 << 16),
                                                 "ALLOC_CHUNK_LIMIT must be 
less than 64kB");
 
                tsize = size - 1;
@@ -358,10 +358,10 @@ AllocSetContextCreateInternal(MemoryContext parent,
        AllocBlock      block;
 
        /* ensure MemoryChunk's size is properly maxaligned */
-       StaticAssertStmt(ALLOC_CHUNKHDRSZ == MAXALIGN(ALLOC_CHUNKHDRSZ),
+       StaticAssertDecl(ALLOC_CHUNKHDRSZ == MAXALIGN(ALLOC_CHUNKHDRSZ),
                                         "sizeof(MemoryChunk) is not 
maxaligned");
        /* check we have enough space to store the freelist link */
-       StaticAssertStmt(sizeof(AllocFreeListLink) <= (1 << ALLOC_MINBITS),
+       StaticAssertDecl(sizeof(AllocFreeListLink) <= (1 << ALLOC_MINBITS),
                                         "sizeof(AllocFreeListLink) larger than 
minimum allocation size");
 
        /*
diff --git a/src/backend/utils/mmgr/generation.c 
b/src/backend/utils/mmgr/generation.c
index b432a92be3..1f17905b5a 100644
--- a/src/backend/utils/mmgr/generation.c
+++ b/src/backend/utils/mmgr/generation.c
@@ -167,7 +167,7 @@ GenerationContextCreate(MemoryContext parent,
        GenerationBlock *block;
 
        /* ensure MemoryChunk's size is properly maxaligned */
-       StaticAssertStmt(Generation_CHUNKHDRSZ == 
MAXALIGN(Generation_CHUNKHDRSZ),
+       StaticAssertDecl(Generation_CHUNKHDRSZ == 
MAXALIGN(Generation_CHUNKHDRSZ),
                                         "sizeof(MemoryChunk) is not 
maxaligned");
 
        /*
diff --git a/src/backend/utils/mmgr/slab.c b/src/backend/utils/mmgr/slab.c
index 6df0839b6a..c2f9bb6ad3 100644
--- a/src/backend/utils/mmgr/slab.c
+++ b/src/backend/utils/mmgr/slab.c
@@ -151,7 +151,7 @@ SlabContextCreate(MemoryContext parent,
        int                     i;
 
        /* ensure MemoryChunk's size is properly maxaligned */
-       StaticAssertStmt(Slab_CHUNKHDRSZ == MAXALIGN(Slab_CHUNKHDRSZ),
+       StaticAssertDecl(Slab_CHUNKHDRSZ == MAXALIGN(Slab_CHUNKHDRSZ),
                                         "sizeof(MemoryChunk) is not 
maxaligned");
        Assert(MAXALIGN(chunkSize) <= MEMORYCHUNK_MAX_VALUE);
 
diff --git a/src/common/checksum_helper.c b/src/common/checksum_helper.c
index 74d0cf0a2e..8948df4da1 100644
--- a/src/common/checksum_helper.c
+++ b/src/common/checksum_helper.c
@@ -177,15 +177,15 @@ pg_checksum_final(pg_checksum_context *context, uint8 
*output)
 {
        int                     retval = 0;
 
-       StaticAssertStmt(sizeof(pg_crc32c) <= PG_CHECKSUM_MAX_LENGTH,
+       StaticAssertDecl(sizeof(pg_crc32c) <= PG_CHECKSUM_MAX_LENGTH,
                                         "CRC-32C digest too big for 
PG_CHECKSUM_MAX_LENGTH");
-       StaticAssertStmt(PG_SHA224_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
+       StaticAssertDecl(PG_SHA224_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
                                         "SHA224 digest too big for 
PG_CHECKSUM_MAX_LENGTH");
-       StaticAssertStmt(PG_SHA256_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
+       StaticAssertDecl(PG_SHA256_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
                                         "SHA256 digest too big for 
PG_CHECKSUM_MAX_LENGTH");
-       StaticAssertStmt(PG_SHA384_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
+       StaticAssertDecl(PG_SHA384_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
                                         "SHA384 digest too big for 
PG_CHECKSUM_MAX_LENGTH");
-       StaticAssertStmt(PG_SHA512_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
+       StaticAssertDecl(PG_SHA512_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH,
                                         "SHA512 digest too big for 
PG_CHECKSUM_MAX_LENGTH");
 
        switch (context->type)
diff --git a/src/include/common/int128.h b/src/include/common/int128.h
index 8f035cf4cb..4b17aa9689 100644
--- a/src/include/common/int128.h
+++ b/src/include/common/int128.h
@@ -177,7 +177,7 @@ static inline void
 int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
 {
        /* INT64_AU32 must use arithmetic right shift */
-       StaticAssertStmt(((int64) -1 >> 1) == (int64) -1,
+       StaticAssertDecl(((int64) -1 >> 1) == (int64) -1,
                                         "arithmetic right shift is needed");
 
        /*----------
-- 
2.38.1

Reply via email to