diff options
Diffstat (limited to 'src')
29 files changed, 99 insertions, 104 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 747db503761..42756a9e6df 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(); @@ -7921,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/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index ff260c393ab..10f13e6d415 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/clog.c b/src/backend/access/transam/clog.c index 77d9894dab3..8832efc7c11 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/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a31fbbff78d..91473b00d90 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -3884,15 +3884,6 @@ WriteControlFile(void) 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 */ ControlFile->pg_control_version = PG_CONTROL_VERSION; diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c index 7aa5f6e44d1..c00ac14c0be 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); @@ -1745,7 +1745,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/catalog/dependency.c b/src/backend/catalog/dependency.c index 7f3e64b5ae6..30394dccf56 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/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index be48886511e..957406ae697 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(lengthof(dispatch_table) == EEOP_LAST + 1, + StaticAssertDecl(lengthof(dispatch_table) == EEOP_LAST + 1, "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 ee7f52218ab..c9bab85e82f 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/libpq/hba.c b/src/backend/libpq/hba.c index 46e91441ac5..870b9076970 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/port/atomics.c b/src/backend/port/atomics.c index ba274bed931..ff4771ae370 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/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index a5ad36ca780..528b2e96438 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 9011337aa81..5c98a5ec2b8 100644 --- a/src/backend/storage/page/itemptr.c +++ b/src/backend/storage/page/itemptr.c @@ -18,6 +18,12 @@ /* + * 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, * otherwise returns false. @@ -28,13 +34,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/numeric.c b/src/backend/utils/adt/numeric.c index c024928bc8d..152e1b7e0c4 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -4187,7 +4187,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/adt/tsginidx.c b/src/backend/utils/adt/tsginidx.c index e272fca0756..cf23aeb5ead 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 2093776809f..3baf5f7d903 100644 --- a/src/backend/utils/adt/xid8funcs.c +++ b/src/backend/utils/adt/xid8funcs.c @@ -75,6 +75,14 @@ typedef struct ((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. * * It is an ERROR if the xid is in the future. Otherwise, returns true if @@ -402,13 +410,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/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 8b359683539..5f17047047b 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(lengthof(cacheinfo) == SysCacheSize, + "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(lengthof(cacheinfo) == SysCacheSize, - "SysCacheSize does not match syscache.c's array"); - Assert(!CacheInitialized); SysCacheRelationOidSize = SysCacheSupportingRelOidSize = 0; diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c index b6a8bbcd596..b45a34abcee 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 b432a92be31..1f17905b5a3 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 6df0839b6ac..c2f9bb6ad34 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 74d0cf0a2e2..8948df4da1a 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/common/controldata_utils.c b/src/common/controldata_utils.c index 2d1f35bbd18..5c654746fae 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/common/encnames.c b/src/common/encnames.c index 596a23b64da..2329db572bc 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]; diff --git a/src/include/access/gin.h b/src/include/access/gin.h index fff861e2192..119ed685bb4 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 9561c835f21..c1af814e8d0 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 8e4f6864e59..7d5a6fa558e 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -467,6 +467,13 @@ typedef struct BTVacState #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/c.h b/src/include/c.h index 98cdd285dd9..bd6d8e5bf53 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++ */ diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 06368e23667..1b648b7196e 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/common/int128.h b/src/include/common/int128.h index 8f035cf4cb2..4b17aa9689e 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"); /*---------- diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index a494cb598ff..dd818e16abc 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 { |