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();
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++)
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);
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");
/*
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
*/
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);
* 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);
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,
{
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)
{
&&CASE_EEOP_LAST
};
- StaticAssertStmt(lengthof(dispatch_table) == EEOP_LAST + 1,
+ StaticAssertDecl(lengthof(dispatch_table) == EEOP_LAST + 1,
"dispatch_table out of whack with ExprEvalOp");
if (unlikely(state == NULL))
* 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);
"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,
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];
}
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
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");
/*
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");
/*
/* 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":
*
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();
#include "storage/itemptr.h"
+/*
+ * We really want ItemPointerData to be exactly 6 bytes.
+ */
+StaticAssertDecl(sizeof(ItemPointerData) == 3 * sizeof(uint16),
+ "ItemPointerData struct is improperly padded");
+
/*
* ItemPointerEquals
* Returns true if both item pointers point to the same item,
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) ==
{
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)))
{
/*
* 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]);
#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.
*
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));
}
};
+StaticAssertDecl(lengthof(cacheinfo) == SysCacheSize,
+ "SysCacheSize does not match syscache.c's array");
+
static CatCache *SysCache[SysCacheSize];
static bool CacheInitialized = false;
{
int cacheId;
- StaticAssertStmt(lengthof(cacheinfo) == SysCacheSize,
- "SysCacheSize does not match syscache.c's array");
-
Assert(!CacheInitialized);
SysCacheRelationOidSize = SysCacheSupportingRelOidSize = 0;
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;
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");
/*
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");
/*
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);
{
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)
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);
"KOI8-U", /* PG_KOI8U */
};
+StaticAssertDecl(lengthof(pg_enc2icu_tbl) == PG_ENCODING_BE_LAST + 1,
+ "pg_enc2icu_tbl incomplete");
+
/*
* Is this encoding supported by ICU?
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];
*/
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
(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) \
#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
* 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++ */
*/
#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 */
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");
/*----------
*/
#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
{