diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c index bc62c6e..b2909b1 100644 --- a/src/backend/utils/adt/lockfuncs.c +++ b/src/backend/utils/adt/lockfuncs.c @@ -35,6 +35,8 @@ const char *const LockTagTypeNames[] = { "userlock", "advisory" }; +StaticAssertDecl(lengthof(LockTagTypeNames) == LOCKTAG_ADVISORY+1, + "LockTagTypeNames array inconsistency"); /* This must match enum PredicateLockTargetType (predicate_internals.h) */ static const char *const PredicateLockTagTypeNames[] = { @@ -42,6 +44,8 @@ static const char *const PredicateLockTagTypeNames[] = { "page", "tuple" }; +StaticAssertDecl(lengthof(PredicateLockTagTypeNames) == PREDLOCKTAG_TUPLE+1, + "PredicateLockTagTypeNames array inconsistency"); /* Working status for pg_lock_status */ typedef struct diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 31a5ef0..a3c19a1 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -232,6 +232,8 @@ static const struct config_enum_entry bytea_output_options[] = { {"hex", BYTEA_OUTPUT_HEX, false}, {NULL, 0, false} }; +StaticAssertDecl(lengthof(bytea_output_options) == BYTEA_OUTPUT_HEX+1+1, + "bytea_output_options array inconsistency"); /* * We have different sets for client and server message level options because @@ -277,6 +279,8 @@ static const struct config_enum_entry intervalstyle_options[] = { {"iso_8601", INTSTYLE_ISO_8601, false}, {NULL, 0, false} }; +StaticAssertDecl(lengthof(intervalstyle_options) == INTSTYLE_ISO_8601+1+1, + "intervalstyle_options array inconsistency"); static const struct config_enum_entry log_error_verbosity_options[] = { {"terse", PGERROR_TERSE, false}, @@ -284,6 +288,8 @@ static const struct config_enum_entry log_error_verbosity_options[] = { {"verbose", PGERROR_VERBOSE, false}, {NULL, 0, false} }; +StaticAssertDecl(lengthof(log_error_verbosity_options) == PGERROR_VERBOSE+1+1, + "log_error_verbosity_options array inconsistency"); static const struct config_enum_entry log_statement_options[] = { {"none", LOGSTMT_NONE, false}, @@ -292,6 +298,8 @@ static const struct config_enum_entry log_statement_options[] = { {"all", LOGSTMT_ALL, false}, {NULL, 0, false} }; +StaticAssertDecl(lengthof(log_statement_options) == LOGSTMT_ALL+1+1, + "log_statement_options array inconsistency"); static const struct config_enum_entry isolation_level_options[] = { {"serializable", XACT_SERIALIZABLE, false}, @@ -307,6 +315,8 @@ static const struct config_enum_entry session_replication_role_options[] = { {"local", SESSION_REPLICATION_ROLE_LOCAL, false}, {NULL, 0, false} }; +StaticAssertDecl(lengthof(session_replication_role_options) == SESSION_REPLICATION_ROLE_LOCAL+1+1, + "session_replication_role_options array inconsistency"); static const struct config_enum_entry syslog_facility_options[] = { #ifdef HAVE_SYSLOG @@ -330,18 +340,24 @@ static const struct config_enum_entry track_function_options[] = { {"all", TRACK_FUNC_ALL, false}, {NULL, 0, false} }; +StaticAssertDecl(lengthof(track_function_options) == TRACK_FUNC_ALL+1+1, + "track_function_options array inconsistency"); static const struct config_enum_entry xmlbinary_options[] = { {"base64", XMLBINARY_BASE64, false}, {"hex", XMLBINARY_HEX, false}, {NULL, 0, false} }; +StaticAssertDecl(lengthof(xmlbinary_options) == XMLBINARY_HEX+1+1, + "xmlbinary_options array inconsistency"); static const struct config_enum_entry xmloption_options[] = { {"content", XMLOPTION_CONTENT, false}, {"document", XMLOPTION_DOCUMENT, false}, {NULL, 0, false} }; +StaticAssertDecl(lengthof(xmloption_options) == XMLOPTION_CONTENT+1+1, + "xmloption_options array inconsistency"); /* * Although only "on", "off", and "safe_encoding" are documented, we @@ -456,6 +472,8 @@ const struct config_enum_entry ssl_protocol_versions_info[] = { {"TLSv1.3", PG_TLS1_3_VERSION, false}, {NULL, 0, false} }; +StaticAssertDecl(lengthof(ssl_protocol_versions_info) == PG_TLS1_3_VERSION+1+1, + "ssl_protocol_versions_info array inconsistency"); static struct config_enum_entry shared_memory_options[] = { #ifndef WIN32 @@ -601,6 +619,8 @@ const char *const GucContext_Names[] = /* PGC_SUSET */ "superuser", /* PGC_USERSET */ "user" }; +StaticAssertDecl(lengthof(GucContext_Names) == PGC_USERSET+1, + "GucContext_Names array inconsistency"); /* * Displayable names for source types (enum GucSource) @@ -624,6 +644,8 @@ const char *const GucSource_Names[] = /* PGC_S_TEST */ "test", /* PGC_S_SESSION */ "session" }; +StaticAssertDecl(lengthof(GucSource_Names) == PGC_S_SESSION+1, + "GucSource_Names array inconsistency"); /* * Displayable names for the groupings defined in enum config_group @@ -735,6 +757,8 @@ const char *const config_group_names[] = /* help_config wants this array to be null-terminated */ NULL }; +StaticAssertDecl(lengthof(config_group_names) == DEVELOPER_OPTIONS+1+1, + "config_group_names array inconsistency"); /* * Displayable names for GUC variable types (enum config_type) @@ -749,6 +773,8 @@ const char *const config_type_names[] = /* PGC_STRING */ "string", /* PGC_ENUM */ "enum" }; +StaticAssertDecl(lengthof(config_type_names) == PGC_ENUM+1, + "config_type_names array inconsistency"); /* * Unit conversion tables. diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c index ad01316..b2643bf 100644 --- a/src/bin/pg_dump/pg_dump_sort.c +++ b/src/bin/pg_dump/pg_dump_sort.c @@ -79,6 +79,8 @@ static const int dbObjectTypePriority[] = 37, /* DO_PUBLICATION_REL */ 38 /* DO_SUBSCRIPTION */ }; +StaticAssertDecl(lengthof(dbObjectTypePriority) == DO_SUBSCRIPTION+1, + "dbObjectTypePriority array inconsistency"); static DumpId preDataBoundId; static DumpId postDataBoundId; diff --git a/src/common/relpath.c b/src/common/relpath.c index 62b9553..5cffc38 100644 --- a/src/common/relpath.c +++ b/src/common/relpath.c @@ -36,6 +36,8 @@ const char *const forkNames[] = { "vm", /* VISIBILITYMAP_FORKNUM */ "init" /* INIT_FORKNUM */ }; +StaticAssertDecl(lengthof(forkNames) == (MAX_FORKNUM+1), + "forkNames array inconsistency"); /* * forkname_to_number - look up fork number by name diff --git a/src/include/c.h b/src/include/c.h index d752cc0..3e24ff4 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -838,11 +838,16 @@ extern void ExceptionalCondition(const char *conditionName, do { _Static_assert(condition, errmessage); } while(0) #define StaticAssertExpr(condition, errmessage) \ ((void) ({ StaticAssertStmt(condition, errmessage); true; })) +/* StaticAssertDecl is suitable for use at file scope. */ +#define StaticAssertDecl(condition, errmessage) \ + _Static_assert(condition, errmessage) #else /* !HAVE__STATIC_ASSERT */ #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 @@ -858,7 +863,6 @@ extern void ExceptionalCondition(const char *conditionName, #endif #endif /* C++ */ - /* * Compile-time checks that a variable (or expression) has the specified type. *