On 22.01.25 19:16, Peter Eisentraut wrote:
On 06.01.25 15:52, Peter Eisentraut wrote:
On 03.01.25 21:51, Dagfinn Ilmari Mannsåker wrote:
Peter Eisentraut <pe...@eisentraut.org> writes:
I suggest we define pg_noreturn as
1. If C11 is supported, then _Noreturn, else
2. If GCC-compatible, then __attribute__((noreturn)), else
Would it be worth also checking __has_attribute(noreturn)? Or do all
compilers that have __attribute__((noreturn)) claim to be GCC?
I don't think that would expand the set of supported compilers in a
significant way. We can always add it if we find one, of course.
In fact, as another thought, we could even drop #2. Among the GCC-
compatible compilers, both GCC and Clang have supported #1 for ages, and
the only other candidate I could find on the build farm is the Solaris
compiler, which also supports C11 by default, per its documentation.
3. If MSVC, then __declspec((noreturn))
Here is an updated patch set that contains the above small change and
fixes some conflicts that have arisen in the meantime.
From 8464526cede39d032f52239c5dcdfdbada189691 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Thu, 13 Feb 2025 16:01:06 +0100
Subject: [PATCH v2 1/4] pg_noreturn to replace pg_attribute_noreturn()
We want to support a "noreturn" decoration on more compilers besides
just GCC-compatible ones, but for that we need to move the decoration
in front of the function declaration instead of either behind it or
wherever, which is the current style afforded by GCC-style attributes.
Also rename the macro to "pg_noreturn" to be similar to the C11
standard "noreturn".
pg_noreturn is now supported on all compilers that support C11 (using
_Noreturn), as well as MSVC (using __declspec). (When PostgreSQL
requires C11, the latter variant can be dropped.) (We don't need the
previously used variant for GCC-compatible compilers using
__attribute__, because all reasonable candidates already support C11,
so that variant would be dead code in practice.)
Now, all supported compilers effectively support pg_noreturn, so the
extra code for !HAVE_PG_ATTRIBUTE_NORETURN can be dropped.
This also fixes a possible problem if third-party code includes
stdnoreturn.h, because then the current definition of
#define pg_attribute_noreturn() __attribute__((noreturn))
would cause an error.
Note that the C standard does not support a noreturn attribute on
function pointer types. So we have to drop these here. There are
only two instances at this time, so it's not a big loss.
Discussion:
https://www.postgresql.org/message-id/flat/pxr5b3z7jmkpenssra5zroxi7qzzp6eswuggokw64axmdixpnk@zbwxuq7gbbcw
---
contrib/dblink/dblink.c | 6 ++--
contrib/pgcrypto/px.h | 2 +-
src/backend/access/transam/xlogrecovery.c | 3 +-
src/backend/backup/basebackup_incremental.c | 6 ++--
src/backend/postmaster/autovacuum.c | 2 +-
src/backend/postmaster/launch_backend.c | 2 +-
src/backend/postmaster/postmaster.c | 2 +-
src/backend/replication/logical/tablesync.c | 3 +-
src/backend/replication/walsender.c | 2 +-
src/backend/utils/adt/ri_triggers.c | 8 +++---
src/backend/utils/fmgr/dfmgr.c | 4 +--
src/backend/utils/hash/dynahash.c | 2 +-
src/backend/utils/mmgr/slab.c | 2 +-
src/bin/pg_combinebackup/load_manifest.c | 6 ++--
src/bin/pg_dump/pg_backup_utils.h | 2 +-
src/bin/pg_upgrade/pg_upgrade.h | 2 +-
src/bin/pg_verifybackup/pg_verifybackup.c | 6 ++--
src/bin/pg_verifybackup/pg_verifybackup.h | 4 +--
src/bin/pgbench/pgbench.h | 12 ++++----
src/include/bootstrap/bootstrap.h | 4 +--
src/include/c.h | 28 ++++++++++++-------
src/include/commands/defrem.h | 2 +-
src/include/common/parse_manifest.h | 3 +-
src/include/mb/pg_wchar.h | 6 ++--
src/include/parser/parse_relation.h | 6 ++--
src/include/parser/scanner.h | 2 +-
src/include/postmaster/autovacuum.h | 4 +--
src/include/postmaster/bgworker_internals.h | 2 +-
src/include/postmaster/bgwriter.h | 4 +--
src/include/postmaster/pgarch.h | 2 +-
src/include/postmaster/postmaster.h | 4 +--
src/include/postmaster/startup.h | 2 +-
src/include/postmaster/syslogger.h | 2 +-
src/include/postmaster/walsummarizer.h | 2 +-
src/include/postmaster/walwriter.h | 2 +-
src/include/replication/slotsync.h | 2 +-
src/include/replication/walreceiver.h | 2 +-
src/include/replication/walsender_private.h | 2 +-
src/include/storage/ipc.h | 2 +-
src/include/storage/lock.h | 2 +-
src/include/tcop/backend_startup.h | 2 +-
src/include/tcop/tcopprot.h | 12 ++++----
src/include/utils/elog.h | 13 ++-------
src/include/utils/float.h | 6 ++--
src/include/utils/help_config.h | 2 +-
src/include/utils/memutils_internal.h | 4 +--
src/interfaces/ecpg/preproc/preproc_extern.h | 2 +-
src/pl/plpgsql/src/plpgsql.h | 2 +-
.../modules/libpq_pipeline/libpq_pipeline.c | 5 ++--
src/test/modules/test_shm_mq/test_shm_mq.h | 2 +-
src/test/modules/worker_spi/worker_spi.c | 2 +-
src/timezone/zic.c | 4 +--
src/tools/pg_bsd_indent/err.h | 8 +++---
53 files changed, 109 insertions(+), 116 deletions(-)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index bed2dee3d72..58c1a6221c8 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -160,8 +160,7 @@ xpstrdup(const char *in)
return pstrdup(in);
}
-static void
-pg_attribute_noreturn()
+pg_noreturn static void
dblink_res_internalerror(PGconn *conn, PGresult *res, const char *p2)
{
char *msg = pchomp(PQerrorMessage(conn));
@@ -170,8 +169,7 @@ dblink_res_internalerror(PGconn *conn, PGresult *res, const
char *p2)
elog(ERROR, "%s: %s", p2, msg);
}
-static void
-pg_attribute_noreturn()
+pg_noreturn static void
dblink_conn_not_avail(const char *conname)
{
if (conname)
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index 37013cd9f82..4b81fceab8e 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -181,7 +181,7 @@ int px_find_hmac(const char *name, PX_HMAC
**res);
int px_find_cipher(const char *name, PX_Cipher **res);
int px_find_combo(const char *name, PX_Combo **res);
-void px_THROW_ERROR(int err) pg_attribute_noreturn();
+pg_noreturn void px_THROW_ERROR(int err);
const char *px_strerror(int err);
const char *px_resolve_alias(const PX_Alias *list, const char *name);
diff --git a/src/backend/access/transam/xlogrecovery.c
b/src/backend/access/transam/xlogrecovery.c
index 473de6710d7..efc628fb43c 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -4776,8 +4776,7 @@ check_primary_slot_name(char **newval, void **extra,
GucSource source)
* that we have odd behaviors such as unexpected GUC ordering dependencies.
*/
-static void
-pg_attribute_noreturn()
+pg_noreturn static void
error_multiple_recovery_targets(void)
{
ereport(ERROR,
diff --git a/src/backend/backup/basebackup_incremental.c
b/src/backend/backup/basebackup_incremental.c
index 360711fadb8..1172c1ea528 100644
--- a/src/backend/backup/basebackup_incremental.c
+++ b/src/backend/backup/basebackup_incremental.c
@@ -139,9 +139,9 @@ static void
manifest_process_wal_range(JsonManifestParseContext *context,
TimeLineID tli,
XLogRecPtr start_lsn,
XLogRecPtr end_lsn);
-static void manifest_report_error(JsonManifestParseContext *context,
- const char
*fmt,...)
- pg_attribute_printf(2, 3) pg_attribute_noreturn();
+pg_noreturn static void manifest_report_error(JsonManifestParseContext
*context,
+
const char *fmt,...)
+ pg_attribute_printf(2, 3);
static int compare_block_numbers(const void *a, const void *b);
/*
diff --git a/src/backend/postmaster/autovacuum.c
b/src/backend/postmaster/autovacuum.c
index ade2708b59e..fcc6756b2b8 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -317,7 +317,7 @@ int AutovacuumLauncherPid = 0;
static Oid do_start_worker(void);
static void HandleAutoVacLauncherInterrupts(void);
-static void AutoVacLauncherShutdown(void) pg_attribute_noreturn();
+pg_noreturn static void AutoVacLauncherShutdown(void);
static void launcher_determine_sleep(bool canlaunch, bool recursing,
struct
timeval *nap);
static void launch_worker(TimestampTz now);
diff --git a/src/backend/postmaster/launch_backend.c
b/src/backend/postmaster/launch_backend.c
index a97a1eda6da..3d583211c8a 100644
--- a/src/backend/postmaster/launch_backend.c
+++ b/src/backend/postmaster/launch_backend.c
@@ -171,7 +171,7 @@ static pid_t internal_forkexec(const char *child_kind, int
child_slot,
typedef struct
{
const char *name;
- void (*main_fn) (char *startup_data, size_t
startup_data_len) pg_attribute_noreturn();
+ void (*main_fn) (char *startup_data, size_t
startup_data_len);
bool shmem_attach;
} child_process_kind;
diff --git a/src/backend/postmaster/postmaster.c
b/src/backend/postmaster/postmaster.c
index bb22b13adef..9429da0b77b 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -426,7 +426,7 @@ static void LogChildExit(int lev, const char *procname,
static void PostmasterStateMachine(void);
static void UpdatePMState(PMState newState);
-static void ExitPostmaster(int status) pg_attribute_noreturn();
+pg_noreturn static void ExitPostmaster(int status);
static int ServerLoop(void);
static int BackendStartup(ClientSocket *client_sock);
static void report_fork_failure_to_client(ClientSocket *client_sock, int
errnum);
diff --git a/src/backend/replication/logical/tablesync.c
b/src/backend/replication/logical/tablesync.c
index 6af5c9fe16c..65b98aa905f 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -139,8 +139,7 @@ static StringInfo copybuf = NULL;
/*
* Exit routine for synchronization worker.
*/
-static void
-pg_attribute_noreturn()
+pg_noreturn static void
finish_sync_worker(void)
{
/*
diff --git a/src/backend/replication/walsender.c
b/src/backend/replication/walsender.c
index 446d10c1a7d..d96121b3aad 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -237,7 +237,7 @@ typedef void (*WalSndSendDataCallback) (void);
static void WalSndLoop(WalSndSendDataCallback send_data);
static void InitWalSenderSlot(void);
static void WalSndKill(int code, Datum arg);
-static void WalSndShutdown(void) pg_attribute_noreturn();
+pg_noreturn static void WalSndShutdown(void);
static void XLogSendPhysical(void);
static void XLogSendLogical(void);
static void WalSndDone(WalSndSendDataCallback send_data);
diff --git a/src/backend/utils/adt/ri_triggers.c
b/src/backend/utils/adt/ri_triggers.c
index 8473448849c..c4ff18ce65e 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -235,10 +235,10 @@ static bool ri_PerformCheck(const RI_ConstraintInfo
*riinfo,
static void ri_ExtractValues(Relation rel, TupleTableSlot *slot,
const
RI_ConstraintInfo *riinfo, bool rel_is_pk,
Datum *vals, char
*nulls);
-static void ri_ReportViolation(const RI_ConstraintInfo *riinfo,
- Relation pk_rel,
Relation fk_rel,
- TupleTableSlot
*violatorslot, TupleDesc tupdesc,
- int queryno, bool
is_restrict, bool partgone) pg_attribute_noreturn();
+pg_noreturn static void ri_ReportViolation(const RI_ConstraintInfo *riinfo,
+
Relation pk_rel, Relation fk_rel,
+
TupleTableSlot *violatorslot, TupleDesc tupdesc,
+
int queryno, bool is_restrict, bool partgone);
/*
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 87b233cb887..4409e3e6fa8 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -67,8 +67,8 @@ static DynamicFileList *file_tail = NULL;
char *Dynamic_library_path;
static void *internal_load_library(const char *libname);
-static void incompatible_module_error(const char *libname,
- const
Pg_magic_struct *module_magic_data) pg_attribute_noreturn();
+pg_noreturn static void incompatible_module_error(const char *libname,
+
const Pg_magic_struct *module_magic_data);
static char *expand_dynamic_library_name(const char *name);
static void check_restricted_library_name(const char *name);
static char *substitute_libpath_macro(const char *name);
diff --git a/src/backend/utils/hash/dynahash.c
b/src/backend/utils/hash/dynahash.c
index cd5a00132fc..3f25929f2d8 100644
--- a/src/backend/utils/hash/dynahash.c
+++ b/src/backend/utils/hash/dynahash.c
@@ -272,7 +272,7 @@ static HASHBUCKET get_hash_entry(HTAB *hashp, int
freelist_idx);
static void hdefault(HTAB *hashp);
static int choose_nelem_alloc(Size entrysize);
static bool init_htab(HTAB *hashp, long nelem);
-static void hash_corrupted(HTAB *hashp) pg_attribute_noreturn();
+pg_noreturn static void hash_corrupted(HTAB *hashp);
static uint32 hash_initial_lookup(HTAB *hashp, uint32 hashvalue,
HASHBUCKET
**bucketptr);
static long next_pow2_long(long num);
diff --git a/src/backend/utils/mmgr/slab.c b/src/backend/utils/mmgr/slab.c
index ec8eddad863..d32c0d318fb 100644
--- a/src/backend/utils/mmgr/slab.c
+++ b/src/backend/utils/mmgr/slab.c
@@ -601,8 +601,8 @@ SlabAllocFromNewBlock(MemoryContext context, Size size, int
flags)
* want to avoid that.
*/
pg_noinline
+pg_noreturn
static void
-pg_attribute_noreturn()
SlabAllocInvalidSize(MemoryContext context, Size size)
{
SlabContext *slab = (SlabContext *) context;
diff --git a/src/bin/pg_combinebackup/load_manifest.c
b/src/bin/pg_combinebackup/load_manifest.c
index 485fe518e41..8e0d04a26a6 100644
--- a/src/bin/pg_combinebackup/load_manifest.c
+++ b/src/bin/pg_combinebackup/load_manifest.c
@@ -68,9 +68,9 @@ static void
combinebackup_per_wal_range_cb(JsonManifestParseContext *context,
TimeLineID tli,
XLogRecPtr start_lsn,
XLogRecPtr end_lsn);
-static void report_manifest_error(JsonManifestParseContext *context,
- const char
*fmt,...)
- pg_attribute_printf(2, 3) pg_attribute_noreturn();
+pg_noreturn static void report_manifest_error(JsonManifestParseContext
*context,
+
const char *fmt,...)
+ pg_attribute_printf(2, 3);
/*
* Load backup_manifest files from an array of backups and produces an array
diff --git a/src/bin/pg_dump/pg_backup_utils.h
b/src/bin/pg_dump/pg_backup_utils.h
index 38551944513..ba042016879 100644
--- a/src/bin/pg_dump/pg_backup_utils.h
+++ b/src/bin/pg_dump/pg_backup_utils.h
@@ -29,7 +29,7 @@ extern const char *progname;
extern void set_dump_section(const char *arg, int *dumpSections);
extern void on_exit_nicely(on_exit_nicely_callback function, void *arg);
-extern void exit_nicely(int code) pg_attribute_noreturn();
+pg_noreturn extern void exit_nicely(int code);
/* In pg_dump, we modify pg_fatal to call exit_nicely instead of exit */
#undef pg_fatal
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index 0cdd675e4f1..0f5dbe57097 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -471,7 +471,7 @@ int get_user_info(char **user_name_p);
void check_ok(void);
void report_status(eLogType type, const char *fmt,...)
pg_attribute_printf(2, 3);
void pg_log(eLogType type, const char *fmt,...)
pg_attribute_printf(2, 3);
-void pg_fatal(const char *fmt,...) pg_attribute_printf(1, 2)
pg_attribute_noreturn();
+pg_noreturn void pg_fatal(const char *fmt,...) pg_attribute_printf(1, 2);
void end_progress_output(void);
void cleanup_output_dirs(void);
void prep_status(const char *fmt,...) pg_attribute_printf(1, 2);
diff --git a/src/bin/pg_verifybackup/pg_verifybackup.c
b/src/bin/pg_verifybackup/pg_verifybackup.c
index 7c720ab98bd..84edd2cdca5 100644
--- a/src/bin/pg_verifybackup/pg_verifybackup.c
+++ b/src/bin/pg_verifybackup/pg_verifybackup.c
@@ -69,9 +69,9 @@ static void
verifybackup_per_wal_range_cb(JsonManifestParseContext *context,
TimeLineID tli,
XLogRecPtr start_lsn,
XLogRecPtr end_lsn);
-static void report_manifest_error(JsonManifestParseContext *context,
- const char
*fmt,...)
- pg_attribute_printf(2, 3) pg_attribute_noreturn();
+pg_noreturn static void report_manifest_error(JsonManifestParseContext
*context,
+
const char *fmt,...)
+ pg_attribute_printf(2, 3);
static void verify_tar_backup(verifier_context *context, DIR *dir);
static void verify_plain_backup_directory(verifier_context *context,
diff --git a/src/bin/pg_verifybackup/pg_verifybackup.h
b/src/bin/pg_verifybackup/pg_verifybackup.h
index 622c9d82a81..8cb6f9c53ad 100644
--- a/src/bin/pg_verifybackup/pg_verifybackup.h
+++ b/src/bin/pg_verifybackup/pg_verifybackup.h
@@ -98,8 +98,8 @@ typedef struct verifier_context
extern void report_backup_error(verifier_context *context,
const char
*pg_restrict fmt,...)
pg_attribute_printf(2, 3);
-extern void report_fatal_error(const char *pg_restrict fmt,...)
- pg_attribute_printf(1, 2) pg_attribute_noreturn();
+pg_noreturn extern void report_fatal_error(const char *pg_restrict fmt,...)
+ pg_attribute_printf(1, 2);
extern bool should_ignore_relpath(verifier_context *context,
const char
*relpath);
diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h
index f6a883611c5..566db4c7bf9 100644
--- a/src/bin/pgbench/pgbench.h
+++ b/src/bin/pgbench/pgbench.h
@@ -140,9 +140,9 @@ struct PgBenchExprList
extern int expr_yyparse(PgBenchExpr **expr_parse_result_p, yyscan_t
yyscanner);
extern int expr_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
-extern void expr_yyerror(PgBenchExpr **expr_parse_result_p, yyscan_t
yyscanner, const char *message) pg_attribute_noreturn();
-extern void expr_yyerror_more(yyscan_t yyscanner, const char *message,
- const char *more)
pg_attribute_noreturn();
+pg_noreturn extern void expr_yyerror(PgBenchExpr **expr_parse_result_p,
yyscan_t yyscanner, const char *message);
+pg_noreturn extern void expr_yyerror_more(yyscan_t yyscanner, const char
*message,
+
const char *more);
extern bool expr_lex_one_word(PsqlScanState state, PQExpBuffer word_buf,
int *offset);
extern yyscan_t expr_scanner_init(PsqlScanState state,
@@ -155,9 +155,9 @@ extern char *expr_scanner_get_substring(PsqlScanState state,
bool chomp);
extern int expr_scanner_get_lineno(PsqlScanState state, int offset);
-extern void syntax_error(const char *source, int lineno, const char *line,
- const char *command, const
char *msg,
- const char *more, int column)
pg_attribute_noreturn();
+pg_noreturn extern void syntax_error(const char *source, int lineno, const
char *line,
+ const
char *command, const char *msg,
+ const
char *more, int column);
extern bool strtoint64(const char *str, bool errorOK, int64 *result);
extern bool strtodouble(const char *str, bool errorOK, double *dv);
diff --git a/src/include/bootstrap/bootstrap.h
b/src/include/bootstrap/bootstrap.h
index 69f3d31a4ef..befc4fa1b3d 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -33,7 +33,7 @@ extern PGDLLIMPORT Form_pg_attribute attrtypes[MAXATTR];
extern PGDLLIMPORT int numattr;
-extern void BootstrapModeMain(int argc, char *argv[], bool check_only)
pg_attribute_noreturn();
+pg_noreturn extern void BootstrapModeMain(int argc, char *argv[], bool
check_only);
extern void closerel(char *relname);
extern void boot_openrel(char *relname);
@@ -64,6 +64,6 @@ typedef void *yyscan_t;
extern int boot_yyparse(yyscan_t yyscanner);
extern int boot_yylex_init(yyscan_t *yyscannerp);
extern int boot_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
-extern void boot_yyerror(yyscan_t yyscanner, const char *message)
pg_attribute_noreturn();
+pg_noreturn extern void boot_yyerror(yyscan_t yyscanner, const char *message);
#endif /* BOOTSTRAP_H */
diff --git a/src/include/c.h b/src/include/c.h
index a14c6315162..d42548cb1c1 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -145,6 +145,20 @@
#define pg_nodiscard
#endif
+/*
+ * pg_noreturn corresponds to the C11 noreturn/_Noreturn function specifier.
+ * We can't use the standard name "noreturn" because some third-party code
+ * uses __attribute__((noreturn)) in headers, which would get confused if
+ * "noreturn" is defined to "_Noreturn", as is done by <stdnoreturn.h>.
+ */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#define pg_noreturn _Noreturn
+#elif defined(_MSC_VER)
+#define pg_noreturn __declspec(noreturn)
+#else
+#define pg_noreturn
+#endif
+
/*
* This macro will disable address safety instrumentation for a function
* when running with "-fsanitize=address". Think twice before using this!
@@ -213,30 +227,24 @@
#define pg_attribute_printf(f,a)
#endif
-/* GCC and Sunpro support aligned, packed and noreturn */
+/* GCC and Sunpro support aligned and packed */
#if defined(__GNUC__) || defined(__SUNPRO_C)
#define pg_attribute_aligned(a) __attribute__((aligned(a)))
-#define pg_attribute_noreturn() __attribute__((noreturn))
#define pg_attribute_packed() __attribute__((packed))
-#define HAVE_PG_ATTRIBUTE_NORETURN 1
#elif defined(_MSC_VER)
/*
- * MSVC supports aligned. noreturn is also possible but in MSVC it is
- * declared before the definition while pg_attribute_noreturn() macro
- * is currently used after the definition.
+ * MSVC supports aligned.
*
* Packing is also possible but only by wrapping the entire struct definition
* which doesn't fit into our current macro declarations.
*/
#define pg_attribute_aligned(a) __declspec(align(a))
-#define pg_attribute_noreturn()
#else
/*
* NB: aligned and packed are not given default definitions because they
* affect code functionality; they *must* be implemented by the compiler
* if they are to be used.
*/
-#define pg_attribute_noreturn()
#endif
/*
@@ -858,8 +866,8 @@ typedef NameData *Name;
* we should declare it as long as !FRONTEND.
*/
#ifndef FRONTEND
-extern void ExceptionalCondition(const char *conditionName,
- const char
*fileName, int lineNumber) pg_attribute_noreturn();
+pg_noreturn extern void ExceptionalCondition(const char *conditionName,
+
const char *fileName, int lineNumber);
#endif
/*
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 6d9348bac80..dd22b5efdfd 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -160,6 +160,6 @@ extern List *defGetQualifiedName(DefElem *def);
extern TypeName *defGetTypeName(DefElem *def);
extern int defGetTypeLength(DefElem *def);
extern List *defGetStringList(DefElem *def);
-extern void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
pg_attribute_noreturn();
+pg_noreturn extern void errorConflictingDefElem(DefElem *defel, ParseState
*pstate);
#endif /* DEFREM_H */
diff --git a/src/include/common/parse_manifest.h
b/src/include/common/parse_manifest.h
index 255cab5c2a9..6172d1d5224 100644
--- a/src/include/common/parse_manifest.h
+++ b/src/include/common/parse_manifest.h
@@ -34,8 +34,7 @@ typedef void (*json_manifest_per_wal_range_callback)
(JsonManifestParseContext *
TimeLineID tli,
XLogRecPtr start_lsn, XLogRecPtr end_lsn);
typedef void (*json_manifest_error_callback) (JsonManifestParseContext *,
-
const char *fmt,...) pg_attribute_printf(2, 3)
- pg_attribute_noreturn();
+
const char *fmt,...) pg_attribute_printf(2, 3);
struct JsonManifestParseContext
{
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index ff7983ee90a..bfef95baea2 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -768,9 +768,9 @@ extern void check_encoding_conversion_args(int src_encoding,
int expected_src_encoding,
int expected_dest_encoding);
-extern void report_invalid_encoding(int encoding, const char *mbstr, int len)
pg_attribute_noreturn();
-extern void report_untranslatable_char(int src_encoding, int dest_encoding,
-
const char *mbstr, int len) pg_attribute_noreturn();
+pg_noreturn extern void report_invalid_encoding(int encoding, const char
*mbstr, int len);
+pg_noreturn extern void report_untranslatable_char(int src_encoding, int
dest_encoding,
+
const char *mbstr, int len);
extern int local2local(const unsigned char *l, unsigned char *p, int len,
int src_encoding, int
dest_encoding,
diff --git a/src/include/parser/parse_relation.h
b/src/include/parser/parse_relation.h
index 3ece5cd4eef..d59599cf242 100644
--- a/src/include/parser/parse_relation.h
+++ b/src/include/parser/parse_relation.h
@@ -110,9 +110,9 @@ extern bool isLockedRefname(ParseState *pstate, const char
*refname);
extern void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem,
bool addToJoinList,
bool
addToRelNameSpace, bool addToVarNameSpace);
-extern void errorMissingRTE(ParseState *pstate, RangeVar *relation)
pg_attribute_noreturn();
-extern void errorMissingColumn(ParseState *pstate,
- const char *relname,
const char *colname, int location) pg_attribute_noreturn();
+pg_noreturn extern void errorMissingRTE(ParseState *pstate, RangeVar
*relation);
+pg_noreturn extern void errorMissingColumn(ParseState *pstate,
+
const char *relname, const char *colname, int location);
extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
VarReturningType returning_type,
int location, bool include_dropped,
diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h
index 74ad86698ac..8d202d5b284 100644
--- a/src/include/parser/scanner.h
+++ b/src/include/parser/scanner.h
@@ -145,6 +145,6 @@ extern void
setup_scanner_errposition_callback(ScannerCallbackState *scbstate,
core_yyscan_t yyscanner,
int location);
extern void cancel_scanner_errposition_callback(ScannerCallbackState
*scbstate);
-extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner)
pg_attribute_noreturn();
+pg_noreturn extern void scanner_yyerror(const char *message, core_yyscan_t
yyscanner);
#endif /* SCANNER_H */
diff --git a/src/include/postmaster/autovacuum.h
b/src/include/postmaster/autovacuum.h
index 06d4a593575..ce7bd0df433 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -58,8 +58,8 @@ extern void autovac_init(void);
/* called from postmaster when a worker could not be forked */
extern void AutoVacWorkerFailed(void);
-extern void AutoVacLauncherMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
-extern void AutoVacWorkerMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void AutoVacLauncherMain(char *startup_data, size_t
startup_data_len);
+pg_noreturn extern void AutoVacWorkerMain(char *startup_data, size_t
startup_data_len);
extern bool AutoVacuumRequestWork(AutoVacuumWorkItemType type,
Oid
relationId, BlockNumber blkno);
diff --git a/src/include/postmaster/bgworker_internals.h
b/src/include/postmaster/bgworker_internals.h
index 092b1610663..a26212d4746 100644
--- a/src/include/postmaster/bgworker_internals.h
+++ b/src/include/postmaster/bgworker_internals.h
@@ -52,6 +52,6 @@ extern void ForgetUnstartedBackgroundWorkers(void);
extern void ResetBackgroundWorkerCrashTimes(void);
/* Entry point for background worker processes */
-extern void BackgroundWorkerMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void BackgroundWorkerMain(char *startup_data, size_t
startup_data_len);
#endif /* BGWORKER_INTERNALS_H
*/
diff --git a/src/include/postmaster/bgwriter.h
b/src/include/postmaster/bgwriter.h
index 2d5854e6879..30fbcd54dc8 100644
--- a/src/include/postmaster/bgwriter.h
+++ b/src/include/postmaster/bgwriter.h
@@ -27,8 +27,8 @@ extern PGDLLIMPORT int CheckPointTimeout;
extern PGDLLIMPORT int CheckPointWarning;
extern PGDLLIMPORT double CheckPointCompletionTarget;
-extern void BackgroundWriterMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
-extern void CheckpointerMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void BackgroundWriterMain(char *startup_data, size_t
startup_data_len);
+pg_noreturn extern void CheckpointerMain(char *startup_data, size_t
startup_data_len);
extern void RequestCheckpoint(int flags);
extern void CheckpointWriteDelay(int flags, double progress);
diff --git a/src/include/postmaster/pgarch.h b/src/include/postmaster/pgarch.h
index 8fc6bfeec1b..66a111f6f65 100644
--- a/src/include/postmaster/pgarch.h
+++ b/src/include/postmaster/pgarch.h
@@ -29,7 +29,7 @@
extern Size PgArchShmemSize(void);
extern void PgArchShmemInit(void);
extern bool PgArchCanRestart(void);
-extern void PgArchiverMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void PgArchiverMain(char *startup_data, size_t
startup_data_len);
extern void PgArchWakeup(void);
extern void PgArchForceDirScan(void);
diff --git a/src/include/postmaster/postmaster.h
b/src/include/postmaster/postmaster.h
index 188a06e2379..b8a10a9723d 100644
--- a/src/include/postmaster/postmaster.h
+++ b/src/include/postmaster/postmaster.h
@@ -91,7 +91,7 @@ extern PGDLLIMPORT const char *progname;
extern PGDLLIMPORT bool redirection_done;
extern PGDLLIMPORT bool LoadedSSL;
-extern void PostmasterMain(int argc, char *argv[]) pg_attribute_noreturn();
+pg_noreturn extern void PostmasterMain(int argc, char *argv[]);
extern void ClosePostmasterPorts(bool am_syslogger);
extern void InitProcessGlobals(void);
@@ -114,7 +114,7 @@ extern pid_t postmaster_child_launch(BackendType child_type,
struct
ClientSocket *client_sock);
const char *PostmasterChildName(BackendType child_type);
#ifdef EXEC_BACKEND
-extern void SubPostmasterMain(int argc, char *argv[]) pg_attribute_noreturn();
+pg_noreturn extern void SubPostmasterMain(int argc, char *argv[]);
#endif
/* defined in pmchild.c */
diff --git a/src/include/postmaster/startup.h b/src/include/postmaster/startup.h
index 736c97d121a..68fcb54eab0 100644
--- a/src/include/postmaster/startup.h
+++ b/src/include/postmaster/startup.h
@@ -26,7 +26,7 @@
extern PGDLLIMPORT int log_startup_progress_interval;
extern void HandleStartupProcInterrupts(void);
-extern void StartupProcessMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void StartupProcessMain(char *startup_data, size_t
startup_data_len);
extern void PreRestoreCommand(void);
extern void PostRestoreCommand(void);
extern bool IsPromoteSignaled(void);
diff --git a/src/include/postmaster/syslogger.h
b/src/include/postmaster/syslogger.h
index e92d8531478..73fb3730be6 100644
--- a/src/include/postmaster/syslogger.h
+++ b/src/include/postmaster/syslogger.h
@@ -90,7 +90,7 @@ extern int SysLogger_Start(int child_slot);
extern void write_syslogger_file(const char *buffer, int count, int
destination);
-extern void SysLoggerMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void SysLoggerMain(char *startup_data, size_t
startup_data_len);
extern bool CheckLogrotateSignal(void);
extern void RemoveLogrotateSignalFiles(void);
diff --git a/src/include/postmaster/walsummarizer.h
b/src/include/postmaster/walsummarizer.h
index bfe86663ccb..98898088ef0 100644
--- a/src/include/postmaster/walsummarizer.h
+++ b/src/include/postmaster/walsummarizer.h
@@ -21,7 +21,7 @@ extern PGDLLIMPORT int wal_summary_keep_time;
extern Size WalSummarizerShmemSize(void);
extern void WalSummarizerShmemInit(void);
-extern void WalSummarizerMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void WalSummarizerMain(char *startup_data, size_t
startup_data_len);
extern void GetWalSummarizerState(TimeLineID *summarized_tli,
XLogRecPtr
*summarized_lsn,
diff --git a/src/include/postmaster/walwriter.h
b/src/include/postmaster/walwriter.h
index 9fc3c665774..35f13bc9dd7 100644
--- a/src/include/postmaster/walwriter.h
+++ b/src/include/postmaster/walwriter.h
@@ -18,6 +18,6 @@
extern PGDLLIMPORT int WalWriterDelay;
extern PGDLLIMPORT int WalWriterFlushAfter;
-extern void WalWriterMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void WalWriterMain(char *startup_data, size_t
startup_data_len);
#endif /* _WALWRITER_H */
diff --git a/src/include/replication/slotsync.h
b/src/include/replication/slotsync.h
index 3fad27f0a63..0f2ec1c00de 100644
--- a/src/include/replication/slotsync.h
+++ b/src/include/replication/slotsync.h
@@ -26,7 +26,7 @@ extern PGDLLIMPORT char *PrimarySlotName;
extern char *CheckAndGetDbnameFromConninfo(void);
extern bool ValidateSlotSyncParams(int elevel);
-extern void ReplSlotSyncWorkerMain(char *startup_data, size_t
startup_data_len) pg_attribute_noreturn();
+pg_noreturn extern void ReplSlotSyncWorkerMain(char *startup_data, size_t
startup_data_len);
extern void ShutDownSlotSync(void);
extern bool SlotSyncWorkerCanRestart(void);
diff --git a/src/include/replication/walreceiver.h
b/src/include/replication/walreceiver.h
index 204419bd8a3..1be6a026152 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -486,7 +486,7 @@ walrcv_clear_result(WalRcvExecResult *walres)
}
/* prototypes for functions in walreceiver.c */
-extern void WalReceiverMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void WalReceiverMain(char *startup_data, size_t
startup_data_len);
extern void ProcessWalRcvInterrupts(void);
extern void WalRcvForceReply(void);
diff --git a/src/include/replication/walsender_private.h
b/src/include/replication/walsender_private.h
index 814b812432a..0fc77f1b4af 100644
--- a/src/include/replication/walsender_private.h
+++ b/src/include/replication/walsender_private.h
@@ -132,7 +132,7 @@ typedef void *yyscan_t;
#endif
extern int replication_yyparse(Node **replication_parse_result_p, yyscan_t
yyscanner);
extern int replication_yylex(union YYSTYPE *yylval_param, yyscan_t
yyscanner);
-extern void replication_yyerror(Node **replication_parse_result_p, yyscan_t
yyscanner, const char *message) pg_attribute_noreturn();
+pg_noreturn extern void replication_yyerror(Node **replication_parse_result_p,
yyscan_t yyscanner, const char *message);
extern void replication_scanner_init(const char *str, yyscan_t *yyscannerp);
extern void replication_scanner_finish(yyscan_t yyscanner);
extern bool replication_scanner_is_replication_command(yyscan_t yyscanner);
diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h
index e0f5f92e947..3baf418b3d1 100644
--- a/src/include/storage/ipc.h
+++ b/src/include/storage/ipc.h
@@ -65,7 +65,7 @@ typedef void (*shmem_startup_hook_type) (void);
extern PGDLLIMPORT bool proc_exit_inprogress;
extern PGDLLIMPORT bool shmem_exit_inprogress;
-extern void proc_exit(int code) pg_attribute_noreturn();
+pg_noreturn extern void proc_exit(int code);
extern void shmem_exit(int code);
extern void on_proc_exit(pg_on_exit_callback function, Datum arg);
extern void on_shmem_exit(pg_on_exit_callback function, Datum arg);
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 1076995518f..c0c0b0f7a2d 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -605,7 +605,7 @@ extern void lock_twophase_standby_recover(TransactionId
xid, uint16 info,
extern DeadLockState DeadLockCheck(PGPROC *proc);
extern PGPROC *GetBlockingAutoVacuumPgproc(void);
-extern void DeadLockReport(void) pg_attribute_noreturn();
+pg_noreturn extern void DeadLockReport(void);
extern void RememberSimpleDeadLock(PGPROC *proc1,
LOCKMODE
lockmode,
LOCK *lock,
diff --git a/src/include/tcop/backend_startup.h
b/src/include/tcop/backend_startup.h
index 01baf4aad75..bb65f6fff4b 100644
--- a/src/include/tcop/backend_startup.h
+++ b/src/include/tcop/backend_startup.h
@@ -39,6 +39,6 @@ typedef struct BackendStartupData
CAC_state canAcceptConnections;
} BackendStartupData;
-extern void BackendMain(char *startup_data, size_t startup_data_len)
pg_attribute_noreturn();
+pg_noreturn extern void BackendMain(char *startup_data, size_t
startup_data_len);
#endif /* BACKEND_STARTUP_H */
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index a62367f7793..a83cc4f4850 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -69,19 +69,19 @@ extern List *pg_plan_queries(List *querytrees, const char
*query_string,
ParamListInfo
boundParams);
extern void die(SIGNAL_ARGS);
-extern void quickdie(SIGNAL_ARGS) pg_attribute_noreturn();
+pg_noreturn extern void quickdie(SIGNAL_ARGS);
extern void StatementCancelHandler(SIGNAL_ARGS);
-extern void FloatExceptionHandler(SIGNAL_ARGS) pg_attribute_noreturn();
+pg_noreturn extern void FloatExceptionHandler(SIGNAL_ARGS);
extern void HandleRecoveryConflictInterrupt(ProcSignalReason reason);
extern void ProcessClientReadInterrupt(bool blocked);
extern void ProcessClientWriteInterrupt(bool blocked);
extern void process_postgres_switches(int argc, char *argv[],
GucContext ctx, const char **dbname);
-extern void PostgresSingleUserMain(int argc, char *argv[],
- const char
*username) pg_attribute_noreturn();
-extern void PostgresMain(const char *dbname,
- const char *username)
pg_attribute_noreturn();
+pg_noreturn extern void PostgresSingleUserMain(int argc, char *argv[],
+
const char *username);
+pg_noreturn extern void PostgresMain(const char *dbname,
+ const
char *username);
extern void ResetUsage(void);
extern void ShowUsage(const char *title);
extern int check_log_duration(char *msec_str, bool was_logged);
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 7161f5c6ad6..b003a548219 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -415,17 +415,8 @@ extern PGDLLIMPORT ErrorContextCallback
*error_context_stack;
error_context_stack = _save_context_stack##__VA_ARGS__; \
} while (0)
-/*
- * Some compilers understand pg_attribute_noreturn(); for other compilers,
- * insert pg_unreachable() so that the compiler gets the point.
- */
-#ifdef HAVE_PG_ATTRIBUTE_NORETURN
#define PG_RE_THROW() \
pg_re_throw()
-#else
-#define PG_RE_THROW() \
- (pg_re_throw(), pg_unreachable())
-#endif
extern PGDLLIMPORT sigjmp_buf *PG_exception_stack;
@@ -476,9 +467,9 @@ extern void EmitErrorReport(void);
extern ErrorData *CopyErrorData(void);
extern void FreeErrorData(ErrorData *edata);
extern void FlushErrorState(void);
-extern void ReThrowError(ErrorData *edata) pg_attribute_noreturn();
+pg_noreturn extern void ReThrowError(ErrorData *edata);
extern void ThrowErrorData(ErrorData *edata);
-extern void pg_re_throw(void) pg_attribute_noreturn();
+pg_noreturn extern void pg_re_throw(void);
extern char *GetErrorContextStack(void);
diff --git a/src/include/utils/float.h b/src/include/utils/float.h
index 9233fa479c6..0e2e9ec5347 100644
--- a/src/include/utils/float.h
+++ b/src/include/utils/float.h
@@ -37,9 +37,9 @@ extern PGDLLIMPORT int extra_float_digits;
/*
* Utility functions in float.c
*/
-extern void float_overflow_error(void) pg_attribute_noreturn();
-extern void float_underflow_error(void) pg_attribute_noreturn();
-extern void float_zero_divide_error(void) pg_attribute_noreturn();
+pg_noreturn extern void float_overflow_error(void);
+pg_noreturn extern void float_underflow_error(void);
+pg_noreturn extern void float_zero_divide_error(void);
extern int is_infinite(float8 val);
extern float8 float8in_internal(char *num, char **endptr_p,
const char
*type_name, const char *orig_string,
diff --git a/src/include/utils/help_config.h b/src/include/utils/help_config.h
index d4f26eb49d0..4e58f130054 100644
--- a/src/include/utils/help_config.h
+++ b/src/include/utils/help_config.h
@@ -12,6 +12,6 @@
#ifndef HELP_CONFIG_H
#define HELP_CONFIG_H 1
-extern void GucInfoMain(void) pg_attribute_noreturn();
+pg_noreturn extern void GucInfoMain(void);
#endif
diff --git a/src/include/utils/memutils_internal.h
b/src/include/utils/memutils_internal.h
index 693650353c6..a6caa6335e3 100644
--- a/src/include/utils/memutils_internal.h
+++ b/src/include/utils/memutils_internal.h
@@ -160,8 +160,8 @@ extern void MemoryContextCreate(MemoryContext node,
extern void *MemoryContextAllocationFailure(MemoryContext context, Size size,
int flags);
-extern void MemoryContextSizeFailure(MemoryContext context, Size size,
- int
flags) pg_attribute_noreturn();
+pg_noreturn extern void MemoryContextSizeFailure(MemoryContext context, Size
size,
+
int flags);
static inline void
MemoryContextCheckSize(MemoryContext context, Size size, int flags)
diff --git a/src/interfaces/ecpg/preproc/preproc_extern.h
b/src/interfaces/ecpg/preproc/preproc_extern.h
index a60b0381fbb..2c89e30621e 100644
--- a/src/interfaces/ecpg/preproc/preproc_extern.h
+++ b/src/interfaces/ecpg/preproc/preproc_extern.h
@@ -89,7 +89,7 @@ extern char *cat_str(int count,...);
extern char *make2_str(const char *str1, const char *str2);
extern char *make3_str(const char *str1, const char *str2, const char *str3);
extern void mmerror(int error_code, enum errortype type, const char
*error,...) pg_attribute_printf(3, 4);
-extern void mmfatal(int error_code, const char *error,...)
pg_attribute_printf(2, 3) pg_attribute_noreturn();
+pg_noreturn extern void mmfatal(int error_code, const char *error,...)
pg_attribute_printf(2, 3);
extern void output_get_descr_header(const char *desc_name);
extern void output_get_descr(const char *desc_name, const char *index);
extern void output_set_descr_header(const char *desc_name);
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index d73996e09c0..aea0d0f98b2 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -1354,7 +1354,7 @@ extern int plpgsql_peek(yyscan_t yyscanner);
extern void plpgsql_peek2(int *tok1_p, int *tok2_p, int *tok1_loc,
int *tok2_loc, yyscan_t
yyscanner);
extern int plpgsql_scanner_errposition(int location, yyscan_t yyscanner);
-extern void plpgsql_yyerror(YYLTYPE *yyllocp, PLpgSQL_stmt_block
**plpgsql_parse_result_p, yyscan_t yyscanner, const char *message)
pg_attribute_noreturn();
+pg_noreturn extern void plpgsql_yyerror(YYLTYPE *yyllocp, PLpgSQL_stmt_block
**plpgsql_parse_result_p, yyscan_t yyscanner, const char *message);
extern int plpgsql_location_to_lineno(int location, yyscan_t yyscanner);
extern int plpgsql_latest_lineno(yyscan_t yyscanner);
extern yyscan_t plpgsql_scanner_init(const char *str);
diff --git a/src/test/modules/libpq_pipeline/libpq_pipeline.c
b/src/test/modules/libpq_pipeline/libpq_pipeline.c
index 7ff18e91e66..ac9ac95135f 100644
--- a/src/test/modules/libpq_pipeline/libpq_pipeline.c
+++ b/src/test/modules/libpq_pipeline/libpq_pipeline.c
@@ -24,7 +24,7 @@
static void exit_nicely(PGconn *conn);
-static void pg_attribute_noreturn() pg_fatal_impl(int line, const char
*fmt,...)
+pg_noreturn static void pg_fatal_impl(int line, const char *fmt,...)
pg_attribute_printf(2, 3);
static bool process_result(PGconn *conn, PGresult *res, int results,
int numsent);
@@ -71,8 +71,7 @@ exit_nicely(PGconn *conn)
* Print an error to stderr and terminate the program.
*/
#define pg_fatal(...) pg_fatal_impl(__LINE__, __VA_ARGS__)
-static void
-pg_attribute_noreturn()
+pg_noreturn static void
pg_fatal_impl(int line, const char *fmt,...)
{
va_list args;
diff --git a/src/test/modules/test_shm_mq/test_shm_mq.h
b/src/test/modules/test_shm_mq/test_shm_mq.h
index 9ad9f63b44e..5346557d473 100644
--- a/src/test/modules/test_shm_mq/test_shm_mq.h
+++ b/src/test/modules/test_shm_mq/test_shm_mq.h
@@ -40,6 +40,6 @@ extern void test_shm_mq_setup(int64 queue_size, int32
nworkers,
shm_mq_handle
**input);
/* Main entrypoint for a worker. */
-extern PGDLLEXPORT void test_shm_mq_main(Datum) pg_attribute_noreturn();
+pg_noreturn extern PGDLLEXPORT void test_shm_mq_main(Datum);
#endif
diff --git a/src/test/modules/worker_spi/worker_spi.c
b/src/test/modules/worker_spi/worker_spi.c
index 5b87d4f7038..9c53d896b6a 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -44,7 +44,7 @@ PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(worker_spi_launch);
-PGDLLEXPORT void worker_spi_main(Datum main_arg) pg_attribute_noreturn();
+PGDLLEXPORT pg_noreturn void worker_spi_main(Datum main_arg);
/* GUC variables */
static int worker_spi_naptime = 10;
diff --git a/src/timezone/zic.c b/src/timezone/zic.c
index d605c721ecf..3b70b888180 100644
--- a/src/timezone/zic.c
+++ b/src/timezone/zic.c
@@ -117,11 +117,11 @@ extern int link(const char *target, const char
*linkname);
(itssymlink(target) ? (errno = ENOTSUP, -1) : link(target, linkname))
#endif
-static void memory_exhausted(const char *msg) pg_attribute_noreturn();
+pg_noreturn static void memory_exhausted(const char *msg);
static void verror(const char *string, va_list args) pg_attribute_printf(1, 0);
static void error(const char *string,...) pg_attribute_printf(1, 2);
static void warning(const char *string,...) pg_attribute_printf(1, 2);
-static void usage(FILE *stream, int status) pg_attribute_noreturn();
+pg_noreturn static void usage(FILE *stream, int status);
static void addtt(zic_t starttime, int type);
static int addtype(zic_t utoff, char const *abbr,
bool isdst, bool ttisstd, bool ttisut);
diff --git a/src/tools/pg_bsd_indent/err.h b/src/tools/pg_bsd_indent/err.h
index a3e8f978255..1083462088e 100644
--- a/src/tools/pg_bsd_indent/err.h
+++ b/src/tools/pg_bsd_indent/err.h
@@ -37,9 +37,9 @@
* This is cut down to just the minimum that we need to build indent.
*/
-void err(int, const char *, ...)
- pg_attribute_noreturn() pg_attribute_printf(2, 3);
-void errx(int, const char *, ...)
- pg_attribute_noreturn() pg_attribute_printf(2, 3);
+pg_noreturn void err(int, const char *, ...)
+ pg_attribute_printf(2, 3);
+pg_noreturn void errx(int, const char *, ...)
+ pg_attribute_printf(2, 3);
#endif /* !_ERR_H_ */
base-commit: ed5e5f071033c8bdaabc8d9cd015f89aa3ccfeef
--
2.48.1
From dbef9fb84b0deceb7ee576958a2d785a1bf15681 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Sat, 28 Dec 2024 11:00:24 +0100
Subject: [PATCH v2 2/4] Add another pg_noreturn
The previous change revealed a compiler warning about possibly
uninitialized variables, which this fixes.
Discussion:
https://www.postgresql.org/message-id/flat/pxr5b3z7jmkpenssra5zroxi7qzzp6eswuggokw64axmdixpnk@zbwxuq7gbbcw
---
src/common/parse_manifest.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/common/parse_manifest.c b/src/common/parse_manifest.c
index 05858578207..71973af199b 100644
--- a/src/common/parse_manifest.c
+++ b/src/common/parse_manifest.c
@@ -114,8 +114,8 @@ static void
json_manifest_finalize_wal_range(JsonManifestParseState *parse);
static void verify_manifest_checksum(JsonManifestParseState *parse,
const
char *buffer, size_t size,
pg_cryptohash_ctx *incr_ctx);
-static void json_manifest_parse_failure(JsonManifestParseContext *context,
-
char *msg);
+pg_noreturn static void json_manifest_parse_failure(JsonManifestParseContext
*context,
+
char *msg);
static int hexdecode_char(char c);
static bool hexdecode_string(uint8 *result, char *input, int nbytes);
@@ -889,6 +889,7 @@ static void
json_manifest_parse_failure(JsonManifestParseContext *context, char *msg)
{
context->error_cb(context, "could not parse backup manifest: %s", msg);
+ pg_unreachable();
}
/*
--
2.48.1
From e15b69ae84977894532fd5557c0735a9e7d6bb37 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Sat, 28 Dec 2024 11:00:24 +0100
Subject: [PATCH v2 3/4] Swap order of extern/static and pg_nodiscard
Clang in C23 mode requires all attributes to be before extern or
static. So just swap these. This also keeps the order consistent
with the previously introduced pg_noreturn.
Discussion:
https://www.postgresql.org/message-id/flat/pxr5b3z7jmkpenssra5zroxi7qzzp6eswuggokw64axmdixpnk@zbwxuq7gbbcw
---
src/include/common/base64.h | 4 +--
src/include/nodes/pg_list.h | 68 +++++++++++++++++------------------
src/include/storage/buffile.h | 2 +-
src/include/utils/guc.h | 2 +-
src/include/utils/palloc.h | 8 ++---
5 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/src/include/common/base64.h b/src/include/common/base64.h
index b064275bbb4..3f74aa301f0 100644
--- a/src/include/common/base64.h
+++ b/src/include/common/base64.h
@@ -11,8 +11,8 @@
#define BASE64_H
/* base 64 */
-extern pg_nodiscard int pg_b64_encode(const char *src, int len, char *dst, int
dstlen);
-extern pg_nodiscard int pg_b64_decode(const char *src, int len, char *dst, int
dstlen);
+pg_nodiscard extern int pg_b64_encode(const char *src, int len, char *dst, int
dstlen);
+pg_nodiscard extern int pg_b64_decode(const char *src, int len, char *dst, int
dstlen);
extern int pg_b64_enc_len(int srclen);
extern int pg_b64_dec_len(int srclen);
diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h
index a872fc501e0..4d1cdbbcfdd 100644
--- a/src/include/nodes/pg_list.h
+++ b/src/include/nodes/pg_list.h
@@ -608,23 +608,23 @@ extern List *list_make5_impl(NodeTag t, ListCell datum1,
ListCell datum2,
ListCell datum3,
ListCell datum4,
ListCell datum5);
-extern pg_nodiscard List *lappend(List *list, void *datum);
-extern pg_nodiscard List *lappend_int(List *list, int datum);
-extern pg_nodiscard List *lappend_oid(List *list, Oid datum);
-extern pg_nodiscard List *lappend_xid(List *list, TransactionId datum);
+pg_nodiscard extern List *lappend(List *list, void *datum);
+pg_nodiscard extern List *lappend_int(List *list, int datum);
+pg_nodiscard extern List *lappend_oid(List *list, Oid datum);
+pg_nodiscard extern List *lappend_xid(List *list, TransactionId datum);
-extern pg_nodiscard List *list_insert_nth(List *list, int pos, void *datum);
-extern pg_nodiscard List *list_insert_nth_int(List *list, int pos, int datum);
-extern pg_nodiscard List *list_insert_nth_oid(List *list, int pos, Oid datum);
+pg_nodiscard extern List *list_insert_nth(List *list, int pos, void *datum);
+pg_nodiscard extern List *list_insert_nth_int(List *list, int pos, int datum);
+pg_nodiscard extern List *list_insert_nth_oid(List *list, int pos, Oid datum);
-extern pg_nodiscard List *lcons(void *datum, List *list);
-extern pg_nodiscard List *lcons_int(int datum, List *list);
-extern pg_nodiscard List *lcons_oid(Oid datum, List *list);
+pg_nodiscard extern List *lcons(void *datum, List *list);
+pg_nodiscard extern List *lcons_int(int datum, List *list);
+pg_nodiscard extern List *lcons_oid(Oid datum, List *list);
-extern pg_nodiscard List *list_concat(List *list1, const List *list2);
-extern pg_nodiscard List *list_concat_copy(const List *list1, const List
*list2);
+pg_nodiscard extern List *list_concat(List *list1, const List *list2);
+pg_nodiscard extern List *list_concat_copy(const List *list1, const List
*list2);
-extern pg_nodiscard List *list_truncate(List *list, int new_size);
+pg_nodiscard extern List *list_truncate(List *list, int new_size);
extern bool list_member(const List *list, const void *datum);
extern bool list_member_ptr(const List *list, const void *datum);
@@ -632,15 +632,15 @@ extern bool list_member_int(const List *list, int datum);
extern bool list_member_oid(const List *list, Oid datum);
extern bool list_member_xid(const List *list, TransactionId datum);
-extern pg_nodiscard List *list_delete(List *list, void *datum);
-extern pg_nodiscard List *list_delete_ptr(List *list, void *datum);
-extern pg_nodiscard List *list_delete_int(List *list, int datum);
-extern pg_nodiscard List *list_delete_oid(List *list, Oid datum);
-extern pg_nodiscard List *list_delete_first(List *list);
-extern pg_nodiscard List *list_delete_last(List *list);
-extern pg_nodiscard List *list_delete_first_n(List *list, int n);
-extern pg_nodiscard List *list_delete_nth_cell(List *list, int n);
-extern pg_nodiscard List *list_delete_cell(List *list, ListCell *cell);
+pg_nodiscard extern List *list_delete(List *list, void *datum);
+pg_nodiscard extern List *list_delete_ptr(List *list, void *datum);
+pg_nodiscard extern List *list_delete_int(List *list, int datum);
+pg_nodiscard extern List *list_delete_oid(List *list, Oid datum);
+pg_nodiscard extern List *list_delete_first(List *list);
+pg_nodiscard extern List *list_delete_last(List *list);
+pg_nodiscard extern List *list_delete_first_n(List *list, int n);
+pg_nodiscard extern List *list_delete_nth_cell(List *list, int n);
+pg_nodiscard extern List *list_delete_cell(List *list, ListCell *cell);
extern List *list_union(const List *list1, const List *list2);
extern List *list_union_ptr(const List *list1, const List *list2);
@@ -657,25 +657,25 @@ extern List *list_difference_ptr(const List *list1, const
List *list2);
extern List *list_difference_int(const List *list1, const List *list2);
extern List *list_difference_oid(const List *list1, const List *list2);
-extern pg_nodiscard List *list_append_unique(List *list, void *datum);
-extern pg_nodiscard List *list_append_unique_ptr(List *list, void *datum);
-extern pg_nodiscard List *list_append_unique_int(List *list, int datum);
-extern pg_nodiscard List *list_append_unique_oid(List *list, Oid datum);
+pg_nodiscard extern List *list_append_unique(List *list, void *datum);
+pg_nodiscard extern List *list_append_unique_ptr(List *list, void *datum);
+pg_nodiscard extern List *list_append_unique_int(List *list, int datum);
+pg_nodiscard extern List *list_append_unique_oid(List *list, Oid datum);
-extern pg_nodiscard List *list_concat_unique(List *list1, const List *list2);
-extern pg_nodiscard List *list_concat_unique_ptr(List *list1, const List
*list2);
-extern pg_nodiscard List *list_concat_unique_int(List *list1, const List
*list2);
-extern pg_nodiscard List *list_concat_unique_oid(List *list1, const List
*list2);
+pg_nodiscard extern List *list_concat_unique(List *list1, const List *list2);
+pg_nodiscard extern List *list_concat_unique_ptr(List *list1, const List
*list2);
+pg_nodiscard extern List *list_concat_unique_int(List *list1, const List
*list2);
+pg_nodiscard extern List *list_concat_unique_oid(List *list1, const List
*list2);
extern void list_deduplicate_oid(List *list);
extern void list_free(List *list);
extern void list_free_deep(List *list);
-extern pg_nodiscard List *list_copy(const List *oldlist);
-extern pg_nodiscard List *list_copy_head(const List *oldlist, int len);
-extern pg_nodiscard List *list_copy_tail(const List *oldlist, int nskip);
-extern pg_nodiscard List *list_copy_deep(const List *oldlist);
+pg_nodiscard extern List *list_copy(const List *oldlist);
+pg_nodiscard extern List *list_copy_head(const List *oldlist, int len);
+pg_nodiscard extern List *list_copy_tail(const List *oldlist, int nskip);
+pg_nodiscard extern List *list_copy_deep(const List *oldlist);
typedef int (*list_sort_comparator) (const ListCell *a, const ListCell *b);
extern void list_sort(List *list, list_sort_comparator cmp);
diff --git a/src/include/storage/buffile.h b/src/include/storage/buffile.h
index 6b92668d90f..a2f4821f240 100644
--- a/src/include/storage/buffile.h
+++ b/src/include/storage/buffile.h
@@ -38,7 +38,7 @@ typedef struct BufFile BufFile;
extern BufFile *BufFileCreateTemp(bool interXact);
extern void BufFileClose(BufFile *file);
-extern pg_nodiscard size_t BufFileRead(BufFile *file, void *ptr, size_t size);
+pg_nodiscard extern size_t BufFileRead(BufFile *file, void *ptr, size_t size);
extern void BufFileReadExact(BufFile *file, void *ptr, size_t size);
extern size_t BufFileReadMaybeEOF(BufFile *file, void *ptr, size_t size, bool
eofOK);
extern void BufFileWrite(BufFile *file, const void *ptr, size_t size);
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 1233e07d7da..24444cbc365 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -444,7 +444,7 @@ extern ArrayType *GUCArrayDelete(ArrayType *array, const
char *name);
extern ArrayType *GUCArrayReset(ArrayType *array);
extern void *guc_malloc(int elevel, size_t size);
-extern pg_nodiscard void *guc_realloc(int elevel, void *old, size_t size);
+pg_nodiscard extern void *guc_realloc(int elevel, void *old, size_t size);
extern char *guc_strdup(int elevel, const char *src);
extern void guc_free(void *ptr);
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index 84e0fc96d96..e1b42267b22 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -79,10 +79,10 @@ extern void *palloc(Size size);
extern void *palloc0(Size size);
extern void *palloc_extended(Size size, int flags);
extern void *palloc_aligned(Size size, Size alignto, int flags);
-extern pg_nodiscard void *repalloc(void *pointer, Size size);
-extern pg_nodiscard void *repalloc_extended(void *pointer,
+pg_nodiscard extern void *repalloc(void *pointer, Size size);
+pg_nodiscard extern void *repalloc_extended(void *pointer,
Size size, int flags);
-extern pg_nodiscard void *repalloc0(void *pointer, Size oldsize, Size size);
+pg_nodiscard extern void *repalloc0(void *pointer, Size oldsize, Size size);
extern void pfree(void *pointer);
/*
@@ -110,7 +110,7 @@ extern void pfree(void *pointer);
/* Higher-limit allocators. */
extern void *MemoryContextAllocHuge(MemoryContext context, Size size);
-extern pg_nodiscard void *repalloc_huge(void *pointer, Size size);
+pg_nodiscard extern void *repalloc_huge(void *pointer, Size size);
/*
* Although this header file is nominally backend-only, certain frontend
--
2.48.1
From 80e2527bf8d55cdb33a7dfa33a888f25e9914850 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Sat, 28 Dec 2024 11:00:24 +0100
Subject: [PATCH v2 4/4] Support pg_nodiscard on non-GNU compilers that support
C23
Support pg_nodiscard on compilers that support C23 attribute syntax.
Previously, only GCC-compatible compilers were supported.
Also, define pg_noreturn similarly using C23 attribute syntax if the
compiler supports C23. This doesn't have much of an effect right now,
since all compilers that support C23 surely also support the existing
C11-compatible code. But it keeps pg_nodiscard and pg_noreturn
consistent.
Discussion:
https://www.postgresql.org/message-id/flat/pxr5b3z7jmkpenssra5zroxi7qzzp6eswuggokw64axmdixpnk@zbwxuq7gbbcw
---
src/include/c.h | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/include/c.h b/src/include/c.h
index d42548cb1c1..a63439c9cf4 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -135,11 +135,11 @@
/*
* pg_nodiscard means the compiler should warn if the result of a function
- * call is ignored. The name "nodiscard" is chosen in alignment with
- * (possibly future) C and C++ standards. For maximum compatibility, use it
- * as a function declaration specifier, so it goes before the return type.
+ * call is ignored.
*/
-#ifdef __GNUC__
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define pg_nodiscard [[__nodiscard__]]
+#elif defined(__GNUC__)
#define pg_nodiscard __attribute__((warn_unused_result))
#else
#define pg_nodiscard
@@ -151,7 +151,9 @@
* uses __attribute__((noreturn)) in headers, which would get confused if
* "noreturn" is defined to "_Noreturn", as is done by <stdnoreturn.h>.
*/
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define pg_noreturn [[__noreturn__]]
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define pg_noreturn _Noreturn
#elif defined(_MSC_VER)
#define pg_noreturn __declspec(noreturn)
--
2.48.1