Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf1f10a1

Browse files
committed
Add declaration-level assertions for compile-time checks
Those new assertions can be used at file scope, outside of any functionfor compilation checks. This commit provides implementations for C andC++, and fallback implementations.Author: Peter SmithReviewed-by: Andres Freund, Kyotaro Horiguchi, Dagfinn Ilmari Mannsåker,Michael PaquierDiscussion:https://postgr.es/m/201DD0641B056142AC8C6645EC1B5F62014B8E8030@SYD1217
1 parent6148e2b commitf1f10a1

File tree

7 files changed

+76
-12
lines changed

7 files changed

+76
-12
lines changed

‎src/backend/storage/page/bufpage.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,7 @@ PageIsVerified(Page page, BlockNumber blkno)
119119
return true;
120120
}
121121

122-
/*
123-
* Check all-zeroes case. Luckily BLCKSZ is guaranteed to always be a
124-
* multiple of size_t - and it's much faster to compare memory using the
125-
* native word size.
126-
*/
127-
StaticAssertStmt(BLCKSZ== (BLCKSZ /sizeof(size_t))*sizeof(size_t),
128-
"BLCKSZ has to be a multiple of sizeof(size_t)");
129-
122+
/* Check all-zeroes case */
130123
all_zeroes= true;
131124
pagebytes= (size_t*)page;
132125
for (i=0;i< (BLCKSZ /sizeof(size_t));i++)

‎src/backend/utils/adt/lockfuncs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,19 @@ const char *const LockTagTypeNames[] = {
3636
"advisory"
3737
};
3838

39+
StaticAssertDecl(lengthof(LockTagTypeNames)== (LOCKTAG_ADVISORY+1),
40+
"array length mismatch");
41+
3942
/* This must match enum PredicateLockTargetType (predicate_internals.h) */
4043
staticconstchar*constPredicateLockTagTypeNames[]= {
4144
"relation",
4245
"page",
4346
"tuple"
4447
};
4548

49+
StaticAssertDecl(lengthof(PredicateLockTagTypeNames)== (PREDLOCKTAG_TUPLE+1),
50+
"array length mismatch");
51+
4652
/* Working status for pg_lock_status */
4753
typedefstruct
4854
{

‎src/backend/utils/misc/guc.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ static const struct config_enum_entry bytea_output_options[] = {
241241
{NULL,0, false}
242242
};
243243

244+
StaticAssertDecl(lengthof(bytea_output_options)== (BYTEA_OUTPUT_HEX+2),
245+
"array length mismatch");
246+
244247
/*
245248
* We have different sets for client and server message level options because
246249
* they sort slightly different (see "log" level), and because "fatal"/"panic"
@@ -286,13 +289,19 @@ static const struct config_enum_entry intervalstyle_options[] = {
286289
{NULL,0, false}
287290
};
288291

292+
StaticAssertDecl(lengthof(intervalstyle_options)== (INTSTYLE_ISO_8601+2),
293+
"array length mismatch");
294+
289295
staticconststructconfig_enum_entrylog_error_verbosity_options[]= {
290296
{"terse",PGERROR_TERSE, false},
291297
{"default",PGERROR_DEFAULT, false},
292298
{"verbose",PGERROR_VERBOSE, false},
293299
{NULL,0, false}
294300
};
295301

302+
StaticAssertDecl(lengthof(log_error_verbosity_options)== (PGERROR_VERBOSE+2),
303+
"array length mismatch");
304+
296305
staticconststructconfig_enum_entrylog_statement_options[]= {
297306
{"none",LOGSTMT_NONE, false},
298307
{"ddl",LOGSTMT_DDL, false},
@@ -301,6 +310,9 @@ static const struct config_enum_entry log_statement_options[] = {
301310
{NULL,0, false}
302311
};
303312

313+
StaticAssertDecl(lengthof(log_statement_options)== (LOGSTMT_ALL+2),
314+
"array length mismatch");
315+
304316
staticconststructconfig_enum_entryisolation_level_options[]= {
305317
{"serializable",XACT_SERIALIZABLE, false},
306318
{"repeatable read",XACT_REPEATABLE_READ, false},
@@ -316,6 +328,9 @@ static const struct config_enum_entry session_replication_role_options[] = {
316328
{NULL,0, false}
317329
};
318330

331+
StaticAssertDecl(lengthof(session_replication_role_options)== (SESSION_REPLICATION_ROLE_LOCAL+2),
332+
"array length mismatch");
333+
319334
staticconststructconfig_enum_entrysyslog_facility_options[]= {
320335
#ifdefHAVE_SYSLOG
321336
{"local0",LOG_LOCAL0, false},
@@ -339,18 +354,27 @@ static const struct config_enum_entry track_function_options[] = {
339354
{NULL,0, false}
340355
};
341356

357+
StaticAssertDecl(lengthof(track_function_options)== (TRACK_FUNC_ALL+2),
358+
"array length mismatch");
359+
342360
staticconststructconfig_enum_entryxmlbinary_options[]= {
343361
{"base64",XMLBINARY_BASE64, false},
344362
{"hex",XMLBINARY_HEX, false},
345363
{NULL,0, false}
346364
};
347365

366+
StaticAssertDecl(lengthof(xmlbinary_options)== (XMLBINARY_HEX+2),
367+
"array length mismatch");
368+
348369
staticconststructconfig_enum_entryxmloption_options[]= {
349370
{"content",XMLOPTION_CONTENT, false},
350371
{"document",XMLOPTION_DOCUMENT, false},
351372
{NULL,0, false}
352373
};
353374

375+
StaticAssertDecl(lengthof(xmloption_options)== (XMLOPTION_CONTENT+2),
376+
"array length mismatch");
377+
354378
/*
355379
* Although only "on", "off", and "safe_encoding" are documented, we
356380
* accept all the likely variants of "on" and "off".
@@ -465,6 +489,9 @@ const struct config_enum_entry ssl_protocol_versions_info[] = {
465489
{NULL,0, false}
466490
};
467491

492+
StaticAssertDecl(lengthof(ssl_protocol_versions_info)== (PG_TLS1_3_VERSION+2),
493+
"array length mismatch");
494+
468495
staticstructconfig_enum_entryshared_memory_options[]= {
469496
#ifndefWIN32
470497
{"sysv",SHMEM_TYPE_SYSV, false},
@@ -615,6 +642,9 @@ const char *const GucContext_Names[] =
615642
/* PGC_USERSET */"user"
616643
};
617644

645+
StaticAssertDecl(lengthof(GucContext_Names)== (PGC_USERSET+1),
646+
"array length mismatch");
647+
618648
/*
619649
* Displayable names for source types (enum GucSource)
620650
*
@@ -638,6 +668,9 @@ const char *const GucSource_Names[] =
638668
/* PGC_S_SESSION */"session"
639669
};
640670

671+
StaticAssertDecl(lengthof(GucSource_Names)== (PGC_S_SESSION+1),
672+
"array length mismatch");
673+
641674
/*
642675
* Displayable names for the groupings defined in enum config_group
643676
*/
@@ -749,6 +782,9 @@ const char *const config_group_names[] =
749782
NULL
750783
};
751784

785+
StaticAssertDecl(lengthof(config_group_names)== (DEVELOPER_OPTIONS+2),
786+
"array length mismatch");
787+
752788
/*
753789
* Displayable names for GUC variable types (enum config_type)
754790
*
@@ -763,6 +799,9 @@ const char *const config_type_names[] =
763799
/* PGC_ENUM */"enum"
764800
};
765801

802+
StaticAssertDecl(lengthof(config_type_names)== (PGC_ENUM+1),
803+
"array length mismatch");
804+
766805
/*
767806
* Unit conversion tables.
768807
*

‎src/bin/pg_dump/pg_dump_sort.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ static const int dbObjectTypePriority[] =
8080
38/* DO_SUBSCRIPTION */
8181
};
8282

83+
StaticAssertDecl(lengthof(dbObjectTypePriority)== (DO_SUBSCRIPTION+1),
84+
"array length mismatch");
85+
8386
staticDumpIdpreDataBoundId;
8487
staticDumpIdpostDataBoundId;
8588

‎src/common/relpath.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ const char *const forkNames[] = {
3737
"init"/* INIT_FORKNUM */
3838
};
3939

40+
StaticAssertDecl(lengthof(forkNames)== (MAX_FORKNUM+1),
41+
"array length mismatch");
42+
4043
/*
4144
* forkname_to_number - look up fork number by name
4245
*

‎src/include/c.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -832,8 +832,10 @@ extern void ExceptionalCondition(const char *conditionName,
832832
* throw a compile error using the "errmessage" (a string literal).
833833
*
834834
* gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic
835-
* placement restrictions. These macros make it safe to use as a statement
836-
* or in an expression, respectively.
835+
* placement restrictions. Macros StaticAssertStmt() and StaticAssertExpr()
836+
* make it safe to use as a statement or in an expression, respectively.
837+
* The macro StaticAssertDecl() is suitable for use at file scope (outside of
838+
* any function).
837839
*
838840
* Otherwise we fall back on a kluge that assumes the compiler will complain
839841
* about a negative width for a struct bit-field. This will not include a
@@ -845,24 +847,32 @@ extern void ExceptionalCondition(const char *conditionName,
845847
do { _Static_assert(condition, errmessage); } while(0)
846848
#defineStaticAssertExpr(condition,errmessage) \
847849
((void) ({ StaticAssertStmt(condition, errmessage); true; }))
850+
#defineStaticAssertDecl(condition,errmessage) \
851+
_Static_assert(condition, errmessage)
848852
#else/* !HAVE__STATIC_ASSERT */
849853
#defineStaticAssertStmt(condition,errmessage) \
850854
((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
851855
#defineStaticAssertExpr(condition,errmessage) \
852856
StaticAssertStmt(condition, errmessage)
857+
#defineStaticAssertDecl(condition,errmessage) \
858+
extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1])
853859
#endif/* HAVE__STATIC_ASSERT */
854860
#else/* C++ */
855861
#if defined(__cpp_static_assert)&&__cpp_static_assert >=200410
856862
#defineStaticAssertStmt(condition,errmessage) \
857863
static_assert(condition, errmessage)
858864
#defineStaticAssertExpr(condition,errmessage) \
859865
({ static_assert(condition, errmessage); })
860-
#else
866+
#defineStaticAssertDecl(condition,errmessage) \
867+
static_assert(condition, errmessage)
868+
#else/* !__cpp_static_assert */
861869
#defineStaticAssertStmt(condition,errmessage) \
862870
do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0)
863871
#defineStaticAssertExpr(condition,errmessage) \
864872
((void) ({ StaticAssertStmt(condition, errmessage); }))
865-
#endif
873+
#defineStaticAssertDecl(condition,errmessage) \
874+
extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1])
875+
#endif/* __cpp_static_assert */
866876
#endif/* C++ */
867877

868878

‎src/include/storage/bufpage.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,16 @@ do { \
418418
((overwrite) ? PAI_OVERWRITE : 0) | \
419419
((is_heap) ? PAI_IS_HEAP : 0))
420420

421+
/*
422+
* Check that BLCKSZ is a multiple of sizeof(size_t). In PageIsVerified(),
423+
* it is much faster to check if a page is full of zeroes using the native
424+
* word size. Note that this assertion is kept within a header to make
425+
* sure that StaticAssertDecl() works across various combinations of
426+
* platforms and compilers.
427+
*/
428+
StaticAssertDecl(BLCKSZ== ((BLCKSZ /sizeof(size_t))*sizeof(size_t)),
429+
"BLCKSZ has to be a multiple of sizeof(size_t)");
430+
421431
externvoidPageInit(Pagepage,SizepageSize,SizespecialSize);
422432
externboolPageIsVerified(Pagepage,BlockNumberblkno);
423433
externOffsetNumberPageAddItemExtended(Pagepage,Itemitem,Sizesize,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp