I'm proposing two changes:

First, rename AssertVariableIsOfType to StaticAssertVariableIsOfType. The current name suggests that it is a run-time assertion (like "Assert"), but it's not. The name change makes that clearer.

I doubt that the current name is used in many extensions, but if necessary, extension code could adapt to this quite easily with something like

#if PG_VERSION_NUM < ...
#define StaticAssertVariableIsOfType(x, y) AssertVariableIsOfType(x, y)
#endif

Second, change the underlying implementation of StaticAssertVariableIsOfType to use StaticAssertDecl instead of StaticAssertStmt. This makes StaticAssertVariableIsOfType behave more like a normal static assertion, and in many cases we can move the current instances to a more natural position at file scope. This is similar to previous commits like 493eb0da31b.
From fbc4eb08e808938ef0c8067886e96afbb356773b Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Tue, 18 Nov 2025 08:43:13 +0100
Subject: [PATCH 1/2] Rename AssertVariableIsOfType to
 StaticAssertVariableIsOfType

This keeps run-time assertions and static assertions clearly separate.
---
 contrib/hstore_plperl/hstore_plperl.c     | 12 +++----
 contrib/hstore_plpython/hstore_plpython.c | 16 +++++-----
 contrib/jsonb_plpython/jsonb_plpython.c   |  8 ++---
 contrib/ltree_plpython/ltree_plpython.c   |  4 +--
 src/backend/executor/execParallel.c       |  2 +-
 src/backend/jit/llvm/llvmjit_types.c      | 10 +++---
 src/include/access/xlogdefs.h             |  2 +-
 src/include/c.h                           | 14 ++++-----
 src/include/lib/ilist.h                   | 38 +++++++++++------------
 src/include/lib/pairingheap.h             |  8 ++---
 src/include/postgres.h                    |  4 +--
 src/include/storage/proclist.h            |  4 +--
 src/include/utils/freepage.h              |  2 +-
 src/include/utils/relptr.h                | 10 +++---
 14 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/contrib/hstore_plperl/hstore_plperl.c 
b/contrib/hstore_plperl/hstore_plperl.c
index 31393b4fa50..1380a1b4367 100644
--- a/contrib/hstore_plperl/hstore_plperl.c
+++ b/contrib/hstore_plperl/hstore_plperl.c
@@ -28,24 +28,24 @@ static hstoreCheckValLen_t hstoreCheckValLen_p;
 void
 _PG_init(void)
 {
-       /* Asserts verify that typedefs above match original declarations */
-       AssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
+       /* Static asserts verify that typedefs above match original 
declarations */
+       StaticAssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
        hstoreUpgrade_p = (hstoreUpgrade_t)
                load_external_function("$libdir/hstore", "hstoreUpgrade",
                                                           true, NULL);
-       AssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
+       StaticAssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
        hstoreUniquePairs_p = (hstoreUniquePairs_t)
                load_external_function("$libdir/hstore", "hstoreUniquePairs",
                                                           true, NULL);
-       AssertVariableIsOfType(&hstorePairs, hstorePairs_t);
+       StaticAssertVariableIsOfType(&hstorePairs, hstorePairs_t);
        hstorePairs_p = (hstorePairs_t)
                load_external_function("$libdir/hstore", "hstorePairs",
                                                           true, NULL);
-       AssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
+       StaticAssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
        hstoreCheckKeyLen_p = (hstoreCheckKeyLen_t)
                load_external_function("$libdir/hstore", "hstoreCheckKeyLen",
                                                           true, NULL);
-       AssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
+       StaticAssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
        hstoreCheckValLen_p = (hstoreCheckValLen_t)
                load_external_function("$libdir/hstore", "hstoreCheckValLen",
                                                           true, NULL);
diff --git a/contrib/hstore_plpython/hstore_plpython.c 
b/contrib/hstore_plpython/hstore_plpython.c
index e2bfc6da38e..3c8ada2a0dc 100644
--- a/contrib/hstore_plpython/hstore_plpython.c
+++ b/contrib/hstore_plpython/hstore_plpython.c
@@ -35,32 +35,32 @@ static hstoreCheckValLen_t hstoreCheckValLen_p;
 void
 _PG_init(void)
 {
-       /* Asserts verify that typedefs above match original declarations */
-       AssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
+       /* Static asserts verify that typedefs above match original 
declarations */
+       StaticAssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
        PLyObject_AsString_p = (PLyObject_AsString_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyObject_AsString",
                                                           true, NULL);
-       AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
+       StaticAssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
        PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyUnicode_FromStringAndSize",
                                                           true, NULL);
-       AssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
+       StaticAssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
        hstoreUpgrade_p = (hstoreUpgrade_t)
                load_external_function("$libdir/hstore", "hstoreUpgrade",
                                                           true, NULL);
-       AssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
+       StaticAssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
        hstoreUniquePairs_p = (hstoreUniquePairs_t)
                load_external_function("$libdir/hstore", "hstoreUniquePairs",
                                                           true, NULL);
-       AssertVariableIsOfType(&hstorePairs, hstorePairs_t);
+       StaticAssertVariableIsOfType(&hstorePairs, hstorePairs_t);
        hstorePairs_p = (hstorePairs_t)
                load_external_function("$libdir/hstore", "hstorePairs",
                                                           true, NULL);
-       AssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
+       StaticAssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
        hstoreCheckKeyLen_p = (hstoreCheckKeyLen_t)
                load_external_function("$libdir/hstore", "hstoreCheckKeyLen",
                                                           true, NULL);
-       AssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
+       StaticAssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
        hstoreCheckValLen_p = (hstoreCheckValLen_t)
                load_external_function("$libdir/hstore", "hstoreCheckValLen",
                                                           true, NULL);
diff --git a/contrib/jsonb_plpython/jsonb_plpython.c 
b/contrib/jsonb_plpython/jsonb_plpython.c
index 7e8e1d6674f..1983bf8c30a 100644
--- a/contrib/jsonb_plpython/jsonb_plpython.c
+++ b/contrib/jsonb_plpython/jsonb_plpython.c
@@ -39,16 +39,16 @@ static PLyUnicode_FromStringAndSize_t 
PLyUnicode_FromStringAndSize_p;
 void
 _PG_init(void)
 {
-       /* Asserts verify that typedefs above match original declarations */
-       AssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
+       /* Static asserts verify that typedefs above match original 
declarations */
+       StaticAssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
        PLyObject_AsString_p = (PLyObject_AsString_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyObject_AsString",
                                                           true, NULL);
-       AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
+       StaticAssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
        PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyUnicode_FromStringAndSize",
                                                           true, NULL);
-       AssertVariableIsOfType(&PLy_elog_impl, PLy_elog_impl_t);
+       StaticAssertVariableIsOfType(&PLy_elog_impl, PLy_elog_impl_t);
        PLy_elog_impl_p = (PLy_elog_impl_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLy_elog_impl",
                                                           true, NULL);
diff --git a/contrib/ltree_plpython/ltree_plpython.c 
b/contrib/ltree_plpython/ltree_plpython.c
index 0493aeb2423..a25fb5c5fa5 100644
--- a/contrib/ltree_plpython/ltree_plpython.c
+++ b/contrib/ltree_plpython/ltree_plpython.c
@@ -20,8 +20,8 @@ static PLyUnicode_FromStringAndSize_t 
PLyUnicode_FromStringAndSize_p;
 void
 _PG_init(void)
 {
-       /* Asserts verify that typedefs above match original declarations */
-       AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
+       /* Static asserts verify that typedefs above match original 
declarations */
+       StaticAssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
        PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyUnicode_FromStringAndSize",
                                                           true, NULL);
diff --git a/src/backend/executor/execParallel.c 
b/src/backend/executor/execParallel.c
index 772e81f3154..f87978c137e 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -106,7 +106,7 @@ struct SharedExecutorInstrumentation
        /* array of num_plan_nodes * num_workers Instrumentation objects 
follows */
 };
 #define GetInstrumentationArray(sei) \
-       (AssertVariableIsOfTypeMacro(sei, SharedExecutorInstrumentation *), \
+       (StaticAssertVariableIsOfTypeMacro(sei, SharedExecutorInstrumentation 
*), \
         (Instrumentation *) (((char *) sei) + sei->instrument_offset))
 
 /* Context object for ExecParallelEstimate. */
diff --git a/src/backend/jit/llvm/llvmjit_types.c 
b/src/backend/jit/llvm/llvmjit_types.c
index 4636b90cd0f..c8a1f841293 100644
--- a/src/backend/jit/llvm/llvmjit_types.c
+++ b/src/backend/jit/llvm/llvmjit_types.c
@@ -81,7 +81,7 @@ extern Datum AttributeTemplate(PG_FUNCTION_ARGS);
 Datum
 AttributeTemplate(PG_FUNCTION_ARGS)
 {
-       AssertVariableIsOfType(&AttributeTemplate, PGFunction);
+       StaticAssertVariableIsOfType(&AttributeTemplate, PGFunction);
 
        PG_RETURN_NULL();
 }
@@ -99,8 +99,8 @@ ExecEvalSubroutineTemplate(ExprState *state,
                                                   struct ExprEvalStep *op,
                                                   ExprContext *econtext)
 {
-       AssertVariableIsOfType(&ExecEvalSubroutineTemplate,
-                                                  ExecEvalSubroutine);
+       StaticAssertVariableIsOfType(&ExecEvalSubroutineTemplate,
+                                                                
ExecEvalSubroutine);
 }
 
 extern bool ExecEvalBoolSubroutineTemplate(ExprState *state,
@@ -111,8 +111,8 @@ ExecEvalBoolSubroutineTemplate(ExprState *state,
                                                           struct ExprEvalStep 
*op,
                                                           ExprContext 
*econtext)
 {
-       AssertVariableIsOfType(&ExecEvalBoolSubroutineTemplate,
-                                                  ExecEvalBoolSubroutine);
+       StaticAssertVariableIsOfType(&ExecEvalBoolSubroutineTemplate,
+                                                                
ExecEvalBoolSubroutine);
 
        return false;
 }
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index 1dfed85c0a3..f461bac3468 100644
--- a/src/include/access/xlogdefs.h
+++ b/src/include/access/xlogdefs.h
@@ -44,7 +44,7 @@ typedef uint64 XLogRecPtr;
  * To avoid breaking translatable messages, we're directly applying the
  * LSN format instead of using a macro.
  */
-#define LSN_FORMAT_ARGS(lsn) (AssertVariableIsOfTypeMacro((lsn), XLogRecPtr), 
(uint32) ((lsn) >> 32)), ((uint32) (lsn))
+#define LSN_FORMAT_ARGS(lsn) (StaticAssertVariableIsOfTypeMacro((lsn), 
XLogRecPtr), (uint32) ((lsn) >> 32)), ((uint32) (lsn))
 
 /*
  * XLogSegNo - physical log file sequence number.
diff --git a/src/include/c.h b/src/include/c.h
index 48e4087c09c..070d24bc358 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -955,26 +955,26 @@ pg_noreturn extern void ExceptionalCondition(const char 
*conditionName,
 /*
  * Compile-time checks that a variable (or expression) has the specified type.
  *
- * AssertVariableIsOfType() can be used as a statement.
- * AssertVariableIsOfTypeMacro() is intended for use in macros, eg
- *             #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x))
+ * StaticAssertVariableIsOfType() can be used as a statement.
+ * StaticAssertVariableIsOfTypeMacro() is intended for use in macros, eg
+ *             #define foo(x) (StaticAssertVariableIsOfTypeMacro(x, int), 
bar(x))
  *
  * If we don't have __builtin_types_compatible_p, we can still assert that
  * the types have the same size.  This is far from ideal (especially on 32-bit
  * platforms) but it provides at least some coverage.
  */
 #ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P
-#define AssertVariableIsOfType(varname, typename) \
+#define StaticAssertVariableIsOfType(varname, typename) \
        StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), 
typename), \
        CppAsString(varname) " does not have type " CppAsString(typename))
-#define AssertVariableIsOfTypeMacro(varname, typename) \
+#define StaticAssertVariableIsOfTypeMacro(varname, typename) \
        (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), 
typename), \
         CppAsString(varname) " does not have type " CppAsString(typename)))
 #else                                                  /* 
!HAVE__BUILTIN_TYPES_COMPATIBLE_P */
-#define AssertVariableIsOfType(varname, typename) \
+#define StaticAssertVariableIsOfType(varname, typename) \
        StaticAssertStmt(sizeof(varname) == sizeof(typename), \
        CppAsString(varname) " does not have type " CppAsString(typename))
-#define AssertVariableIsOfTypeMacro(varname, typename) \
+#define StaticAssertVariableIsOfTypeMacro(varname, typename) \
        (StaticAssertExpr(sizeof(varname) == sizeof(typename), \
         CppAsString(varname) " does not have type " CppAsString(typename)))
 #endif                                                 /* 
HAVE__BUILTIN_TYPES_COMPATIBLE_P */
diff --git a/src/include/lib/ilist.h b/src/include/lib/ilist.h
index d49ec0ffbc5..fc298a6c1d7 100644
--- a/src/include/lib/ilist.h
+++ b/src/include/lib/ilist.h
@@ -591,8 +591,8 @@ dlist_tail_node(dlist_head *head)
  * This is used to convert a dlist_node * back to its containing struct.
  */
 #define dlist_container(type, membername, ptr)                                 
                        \
-       (AssertVariableIsOfTypeMacro(ptr, dlist_node *),                        
                        \
-        AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node),  
\
+       (StaticAssertVariableIsOfTypeMacro(ptr, dlist_node *),                  
                        \
+        StaticAssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
dlist_node),    \
         ((type *) ((char *) (ptr) - offsetof(type, membername))))
 
 /*
@@ -601,7 +601,7 @@ dlist_tail_node(dlist_head *head)
  * The list must not be empty.
  */
 #define dlist_head_element(type, membername, lhead)                            
                        \
-       (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node),  
\
+       (StaticAssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
dlist_node),    \
         (type *) dlist_head_element_off(lhead, offsetof(type, membername)))
 
 /*
@@ -610,7 +610,7 @@ dlist_tail_node(dlist_head *head)
  * The list must not be empty.
  */
 #define dlist_tail_element(type, membername, lhead)                            
                        \
-       (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node),  
\
+       (StaticAssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
dlist_node),    \
         ((type *) dlist_tail_element_off(lhead, offsetof(type, membername))))
 
 /*
@@ -621,8 +621,8 @@ dlist_tail_node(dlist_head *head)
  * It is *not* allowed to manipulate the list during iteration.
  */
 #define dlist_foreach(iter, lhead)                                             
                                        \
-       for (AssertVariableIsOfTypeMacro(iter, dlist_iter),                     
                        \
-                AssertVariableIsOfTypeMacro(lhead, dlist_head *),              
                        \
+       for (StaticAssertVariableIsOfTypeMacro(iter, dlist_iter),               
                                \
+                StaticAssertVariableIsOfTypeMacro(lhead, dlist_head *),        
                                \
                 (iter).end = &(lhead)->head,                                   
                                        \
                 (iter).cur = (iter).end->next ? (iter).end->next : (iter).end; 
        \
                 (iter).cur != (iter).end;                                      
                                                \
@@ -638,8 +638,8 @@ dlist_tail_node(dlist_head *head)
  * fine to insert or delete adjacent nodes.
  */
 #define dlist_foreach_modify(iter, lhead)                                      
                                \
-       for (AssertVariableIsOfTypeMacro(iter, dlist_mutable_iter),             
                \
-                AssertVariableIsOfTypeMacro(lhead, dlist_head *),              
                        \
+       for (StaticAssertVariableIsOfTypeMacro(iter, dlist_mutable_iter),       
                        \
+                StaticAssertVariableIsOfTypeMacro(lhead, dlist_head *),        
                                \
                 (iter).end = &(lhead)->head,                                   
                                        \
                 (iter).cur = (iter).end->next ? (iter).end->next : (iter).end, 
        \
                 (iter).next = (iter).cur->next;                                
                                        \
@@ -652,8 +652,8 @@ dlist_tail_node(dlist_head *head)
  * It is *not* allowed to manipulate the list during iteration.
  */
 #define dlist_reverse_foreach(iter, lhead)                                     
                                \
-       for (AssertVariableIsOfTypeMacro(iter, dlist_iter),                     
                        \
-                AssertVariableIsOfTypeMacro(lhead, dlist_head *),              
                        \
+       for (StaticAssertVariableIsOfTypeMacro(iter, dlist_iter),               
                                \
+                StaticAssertVariableIsOfTypeMacro(lhead, dlist_head *),        
                                \
                 (iter).end = &(lhead)->head,                                   
                                        \
                 (iter).cur = (iter).end->prev ? (iter).end->prev : (iter).end; 
        \
                 (iter).cur != (iter).end;                                      
                                                \
@@ -953,7 +953,7 @@ dclist_count(const dclist_head *head)
   * The list must not be empty.
   */
 #define dclist_head_element(type, membername, lhead)                           
                        \
-       (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node),  
\
+       (StaticAssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
dlist_node),    \
         (type *) dclist_head_element_off(lhead, offsetof(type, membername)))
 
  /*
@@ -962,7 +962,7 @@ dclist_count(const dclist_head *head)
   * The list must not be empty.
   */
 #define dclist_tail_element(type, membername, lhead)                           
                        \
-       (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node),  
\
+       (StaticAssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
dlist_node),    \
         ((type *) dclist_tail_element_off(lhead, offsetof(type, membername))))
 
 
@@ -1104,8 +1104,8 @@ slist_delete_current(slist_mutable_iter *iter)
  * This is used to convert a slist_node * back to its containing struct.
  */
 #define slist_container(type, membername, ptr)                                 
                        \
-       (AssertVariableIsOfTypeMacro(ptr, slist_node *),                        
                        \
-        AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node),  
\
+       (StaticAssertVariableIsOfTypeMacro(ptr, slist_node *),                  
                        \
+        StaticAssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
slist_node),    \
         ((type *) ((char *) (ptr) - offsetof(type, membername))))
 
 /*
@@ -1114,7 +1114,7 @@ slist_delete_current(slist_mutable_iter *iter)
  * The list must not be empty.
  */
 #define slist_head_element(type, membername, lhead)                            
                        \
-       (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node),  
\
+       (StaticAssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
slist_node),    \
         (type *) slist_head_element_off(lhead, offsetof(type, membername)))
 
 /*
@@ -1130,8 +1130,8 @@ slist_delete_current(slist_mutable_iter *iter)
  * not safe.)
  */
 #define slist_foreach(iter, lhead)                                             
                                        \
-       for (AssertVariableIsOfTypeMacro(iter, slist_iter),                     
                        \
-                AssertVariableIsOfTypeMacro(lhead, slist_head *),              
                        \
+       for (StaticAssertVariableIsOfTypeMacro(iter, slist_iter),               
                                \
+                StaticAssertVariableIsOfTypeMacro(lhead, slist_head *),        
                                \
                 (iter).cur = (lhead)->head.next;                               
                                        \
                 (iter).cur != NULL;                                            
                                                \
                 (iter).cur = (iter).cur->next)
@@ -1146,8 +1146,8 @@ slist_delete_current(slist_mutable_iter *iter)
  * deletion of nodes adjacent to the current node would misbehave.
  */
 #define slist_foreach_modify(iter, lhead)                                      
                                \
-       for (AssertVariableIsOfTypeMacro(iter, slist_mutable_iter),             
                \
-                AssertVariableIsOfTypeMacro(lhead, slist_head *),              
                        \
+       for (StaticAssertVariableIsOfTypeMacro(iter, slist_mutable_iter),       
                        \
+                StaticAssertVariableIsOfTypeMacro(lhead, slist_head *),        
                                \
                 (iter).prev = &(lhead)->head,                                  
                                        \
                 (iter).cur = (iter).prev->next,                                
                                        \
                 (iter).next = (iter).cur ? (iter).cur->next : NULL;            
                \
diff --git a/src/include/lib/pairingheap.h b/src/include/lib/pairingheap.h
index b93ea5b638d..f1582c98626 100644
--- a/src/include/lib/pairingheap.h
+++ b/src/include/lib/pairingheap.h
@@ -41,16 +41,16 @@ typedef struct pairingheap_node
  * This is used to convert a pairingheap_node * back to its containing struct.
  */
 #define pairingheap_container(type, membername, ptr) \
-       (AssertVariableIsOfTypeMacro(ptr, pairingheap_node *), \
-        AssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
pairingheap_node),  \
+       (StaticAssertVariableIsOfTypeMacro(ptr, pairingheap_node *), \
+        StaticAssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
pairingheap_node),  \
         ((type *) ((char *) (ptr) - offsetof(type, membername))))
 
 /*
  * Like pairingheap_container, but used when the pointer is 'const ptr'
  */
 #define pairingheap_const_container(type, membername, ptr) \
-       (AssertVariableIsOfTypeMacro(ptr, const pairingheap_node *), \
-        AssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
pairingheap_node),  \
+       (StaticAssertVariableIsOfTypeMacro(ptr, const pairingheap_node *), \
+        StaticAssertVariableIsOfTypeMacro(((type *) NULL)->membername, 
pairingheap_node),  \
         ((const type *) ((const char *) (ptr) - offsetof(type, membername))))
 
 /*
diff --git a/src/include/postgres.h b/src/include/postgres.h
index 8b92f453e7a..a7a6584e762 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -533,9 +533,9 @@ Float8GetDatum(float8 X)
  */
 
 #define Int64GetDatumFast(X) \
-       (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
+       (StaticAssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
 #define Float8GetDatumFast(X) \
-       (AssertVariableIsOfTypeMacro(X, double), Float8GetDatum(X))
+       (StaticAssertVariableIsOfTypeMacro(X, double), Float8GetDatum(X))
 
 
 /* ----------------------------------------------------------------
diff --git a/src/include/storage/proclist.h b/src/include/storage/proclist.h
index 965609145e4..9caf109a845 100644
--- a/src/include/storage/proclist.h
+++ b/src/include/storage/proclist.h
@@ -204,8 +204,8 @@ proclist_pop_head_node_offset(proclist_head *list, size_t 
node_offset)
  * node with proclist_delete(list, iter.cur, node_offset).
  */
 #define proclist_foreach_modify(iter, lhead, link_member)                      
                \
-       for (AssertVariableIsOfTypeMacro(iter, proclist_mutable_iter),          
        \
-                AssertVariableIsOfTypeMacro(lhead, proclist_head *),           
                \
+       for (StaticAssertVariableIsOfTypeMacro(iter, proclist_mutable_iter),    
                \
+                StaticAssertVariableIsOfTypeMacro(lhead, proclist_head *),     
                        \
                 (iter).cur = (lhead)->head,                                    
                                        \
                 (iter).next = (iter).cur == INVALID_PROC_NUMBER ? 
INVALID_PROC_NUMBER :        \
                         proclist_node_get((iter).cur,                          
                                        \
diff --git a/src/include/utils/freepage.h b/src/include/utils/freepage.h
index 8c0e0edd791..2681fd6d5ea 100644
--- a/src/include/utils/freepage.h
+++ b/src/include/utils/freepage.h
@@ -65,7 +65,7 @@ struct FreePageManager
 
 /* Macros to convert between page numbers (expressed as Size) and pointers. */
 #define fpm_page_to_pointer(base, page) \
-       (AssertVariableIsOfTypeMacro(page, Size), \
+       (StaticAssertVariableIsOfTypeMacro(page, Size), \
         (base) + FPM_PAGE_SIZE * (page))
 #define fpm_pointer_to_page(base, ptr)         \
        (((Size) (((char *) (ptr)) - (base))) / FPM_PAGE_SIZE)
diff --git a/src/include/utils/relptr.h b/src/include/utils/relptr.h
index aeb17fa24a5..94975f2f237 100644
--- a/src/include/utils/relptr.h
+++ b/src/include/utils/relptr.h
@@ -40,12 +40,12 @@
 
 #ifdef HAVE_TYPEOF
 #define relptr_access(base, rp) \
-       (AssertVariableIsOfTypeMacro(base, char *), \
+       (StaticAssertVariableIsOfTypeMacro(base, char *), \
         (typeof((rp).relptr_type)) ((rp).relptr_off == 0 ? NULL : \
                (base) + (rp).relptr_off - 1))
 #else
 #define relptr_access(base, rp) \
-       (AssertVariableIsOfTypeMacro(base, char *), \
+       (StaticAssertVariableIsOfTypeMacro(base, char *), \
         (void *) ((rp).relptr_off == 0 ? NULL : (base) + (rp).relptr_off - 1))
 #endif
 
@@ -70,12 +70,12 @@ relptr_store_eval(char *base, char *val)
 
 #ifdef HAVE_TYPEOF
 #define relptr_store(base, rp, val) \
-       (AssertVariableIsOfTypeMacro(base, char *), \
-        AssertVariableIsOfTypeMacro(val, typeof((rp).relptr_type)), \
+       (StaticAssertVariableIsOfTypeMacro(base, char *), \
+        StaticAssertVariableIsOfTypeMacro(val, typeof((rp).relptr_type)), \
         (rp).relptr_off = relptr_store_eval((base), (char *) (val)))
 #else
 #define relptr_store(base, rp, val) \
-       (AssertVariableIsOfTypeMacro(base, char *), \
+       (StaticAssertVariableIsOfTypeMacro(base, char *), \
         (rp).relptr_off = relptr_store_eval((base), (char *) (val)))
 #endif
 
-- 
2.52.0

From 01458455ff94bb20cd414a6f3c91107d56fbd7aa Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Tue, 18 Nov 2025 08:43:13 +0100
Subject: [PATCH 2/2] Change StaticAssertVariableIsOfType to be a declaration

This allows moving the uses to more natural and useful positions.
Also, a declaration is the more native use of static assertions in C.
---
 contrib/hstore_plperl/hstore_plperl.c     | 13 +++++++------
 contrib/hstore_plpython/hstore_plpython.c | 17 +++++++++--------
 contrib/jsonb_plpython/jsonb_plpython.c   | 10 ++++++----
 contrib/ltree_plpython/ltree_plpython.c   |  5 +++--
 src/include/c.h                           |  6 +++---
 5 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/contrib/hstore_plperl/hstore_plperl.c 
b/contrib/hstore_plperl/hstore_plperl.c
index 1380a1b4367..69001191cc0 100644
--- a/contrib/hstore_plperl/hstore_plperl.c
+++ b/contrib/hstore_plperl/hstore_plperl.c
@@ -21,6 +21,13 @@ static hstoreCheckKeyLen_t hstoreCheckKeyLen_p;
 typedef size_t (*hstoreCheckValLen_t) (size_t len);
 static hstoreCheckValLen_t hstoreCheckValLen_p;
 
+/* Static asserts verify that typedefs above match original declarations */
+StaticAssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
+StaticAssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
+StaticAssertVariableIsOfType(&hstorePairs, hstorePairs_t);
+StaticAssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
+StaticAssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
+
 
 /*
  * Module initialize function: fetch function pointers for cross-module calls.
@@ -28,24 +35,18 @@ static hstoreCheckValLen_t hstoreCheckValLen_p;
 void
 _PG_init(void)
 {
-       /* Static asserts verify that typedefs above match original 
declarations */
-       StaticAssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
        hstoreUpgrade_p = (hstoreUpgrade_t)
                load_external_function("$libdir/hstore", "hstoreUpgrade",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
        hstoreUniquePairs_p = (hstoreUniquePairs_t)
                load_external_function("$libdir/hstore", "hstoreUniquePairs",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&hstorePairs, hstorePairs_t);
        hstorePairs_p = (hstorePairs_t)
                load_external_function("$libdir/hstore", "hstorePairs",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
        hstoreCheckKeyLen_p = (hstoreCheckKeyLen_t)
                load_external_function("$libdir/hstore", "hstoreCheckKeyLen",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
        hstoreCheckValLen_p = (hstoreCheckValLen_t)
                load_external_function("$libdir/hstore", "hstoreCheckValLen",
                                                           true, NULL);
diff --git a/contrib/hstore_plpython/hstore_plpython.c 
b/contrib/hstore_plpython/hstore_plpython.c
index 3c8ada2a0dc..d2be030e07c 100644
--- a/contrib/hstore_plpython/hstore_plpython.c
+++ b/contrib/hstore_plpython/hstore_plpython.c
@@ -28,6 +28,15 @@ static hstoreCheckKeyLen_t hstoreCheckKeyLen_p;
 typedef size_t (*hstoreCheckValLen_t) (size_t len);
 static hstoreCheckValLen_t hstoreCheckValLen_p;
 
+/* Static asserts verify that typedefs above match original declarations */
+StaticAssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
+StaticAssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
+StaticAssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
+StaticAssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
+StaticAssertVariableIsOfType(&hstorePairs, hstorePairs_t);
+StaticAssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
+StaticAssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
+
 
 /*
  * Module initialize function: fetch function pointers for cross-module calls.
@@ -35,32 +44,24 @@ static hstoreCheckValLen_t hstoreCheckValLen_p;
 void
 _PG_init(void)
 {
-       /* Static asserts verify that typedefs above match original 
declarations */
-       StaticAssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
        PLyObject_AsString_p = (PLyObject_AsString_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyObject_AsString",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
        PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyUnicode_FromStringAndSize",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
        hstoreUpgrade_p = (hstoreUpgrade_t)
                load_external_function("$libdir/hstore", "hstoreUpgrade",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
        hstoreUniquePairs_p = (hstoreUniquePairs_t)
                load_external_function("$libdir/hstore", "hstoreUniquePairs",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&hstorePairs, hstorePairs_t);
        hstorePairs_p = (hstorePairs_t)
                load_external_function("$libdir/hstore", "hstorePairs",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
        hstoreCheckKeyLen_p = (hstoreCheckKeyLen_t)
                load_external_function("$libdir/hstore", "hstoreCheckKeyLen",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
        hstoreCheckValLen_p = (hstoreCheckValLen_t)
                load_external_function("$libdir/hstore", "hstoreCheckValLen",
                                                           true, NULL);
diff --git a/contrib/jsonb_plpython/jsonb_plpython.c 
b/contrib/jsonb_plpython/jsonb_plpython.c
index 1983bf8c30a..c2c4ce37c08 100644
--- a/contrib/jsonb_plpython/jsonb_plpython.c
+++ b/contrib/jsonb_plpython/jsonb_plpython.c
@@ -33,22 +33,24 @@ typedef PyObject *(*PLyUnicode_FromStringAndSize_t)
                        (const char *s, Py_ssize_t size);
 static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p;
 
+/* Static asserts verify that typedefs above match original declarations */
+StaticAssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
+StaticAssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
+StaticAssertVariableIsOfType(&PLy_elog_impl, PLy_elog_impl_t);
+
+
 /*
  * Module initialize function: fetch function pointers for cross-module calls.
  */
 void
 _PG_init(void)
 {
-       /* Static asserts verify that typedefs above match original 
declarations */
-       StaticAssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
        PLyObject_AsString_p = (PLyObject_AsString_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyObject_AsString",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
        PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyUnicode_FromStringAndSize",
                                                           true, NULL);
-       StaticAssertVariableIsOfType(&PLy_elog_impl, PLy_elog_impl_t);
        PLy_elog_impl_p = (PLy_elog_impl_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLy_elog_impl",
                                                           true, NULL);
diff --git a/contrib/ltree_plpython/ltree_plpython.c 
b/contrib/ltree_plpython/ltree_plpython.c
index a25fb5c5fa5..d4e7b613fa1 100644
--- a/contrib/ltree_plpython/ltree_plpython.c
+++ b/contrib/ltree_plpython/ltree_plpython.c
@@ -13,6 +13,9 @@ PG_MODULE_MAGIC_EXT(
 typedef PyObject *(*PLyUnicode_FromStringAndSize_t) (const char *s, Py_ssize_t 
size);
 static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p;
 
+/* Static asserts verify that typedefs above match original declarations */
+StaticAssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
+
 
 /*
  * Module initialize function: fetch function pointers for cross-module calls.
@@ -20,8 +23,6 @@ static PLyUnicode_FromStringAndSize_t 
PLyUnicode_FromStringAndSize_p;
 void
 _PG_init(void)
 {
-       /* Static asserts verify that typedefs above match original 
declarations */
-       StaticAssertVariableIsOfType(&PLyUnicode_FromStringAndSize, 
PLyUnicode_FromStringAndSize_t);
        PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t)
                load_external_function("$libdir/" PLPYTHON_LIBNAME, 
"PLyUnicode_FromStringAndSize",
                                                           true, NULL);
diff --git a/src/include/c.h b/src/include/c.h
index 070d24bc358..0f9f328147f 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -955,7 +955,7 @@ pg_noreturn extern void ExceptionalCondition(const char 
*conditionName,
 /*
  * Compile-time checks that a variable (or expression) has the specified type.
  *
- * StaticAssertVariableIsOfType() can be used as a statement.
+ * StaticAssertVariableIsOfType() can be used as a declaration.
  * StaticAssertVariableIsOfTypeMacro() is intended for use in macros, eg
  *             #define foo(x) (StaticAssertVariableIsOfTypeMacro(x, int), 
bar(x))
  *
@@ -965,14 +965,14 @@ pg_noreturn extern void ExceptionalCondition(const char 
*conditionName,
  */
 #ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P
 #define StaticAssertVariableIsOfType(varname, typename) \
-       StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), 
typename), \
+       StaticAssertDecl(__builtin_types_compatible_p(__typeof__(varname), 
typename), \
        CppAsString(varname) " does not have type " CppAsString(typename))
 #define StaticAssertVariableIsOfTypeMacro(varname, typename) \
        (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), 
typename), \
         CppAsString(varname) " does not have type " CppAsString(typename)))
 #else                                                  /* 
!HAVE__BUILTIN_TYPES_COMPATIBLE_P */
 #define StaticAssertVariableIsOfType(varname, typename) \
-       StaticAssertStmt(sizeof(varname) == sizeof(typename), \
+       StaticAssertDecl(sizeof(varname) == sizeof(typename), \
        CppAsString(varname) " does not have type " CppAsString(typename))
 #define StaticAssertVariableIsOfTypeMacro(varname, typename) \
        (StaticAssertExpr(sizeof(varname) == sizeof(typename), \
-- 
2.52.0

Reply via email to