__attribute__ for non-gcc compilers

Started by Oskari Saarenmaaalmost 11 years ago13 messages
1 attachment(s)

Commit db4ec2ffce35 added alignment attributes for 64-bit atomic
variables as required on 32-bit platforms using
__attribute__((aligned(8)). That works fine with GCC, and would work
with Solaris Studio Compiler [1]https://docs.oracle.com/cd/E18659_01/html/821-1384/gjzke.html and IBM XL C [2]http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/var_attrib_aligned.html, but src/include/c.h
defines __attribute__ as an empty macro when not using GCC.
Unfortunately we can't just disable that #define and enable all
__attributes__ for Solaris CC and XLC as we use a bunch of attributes
that are not supported by those compilers and using them unconditionally
would generate a lot of warnings.

Attached a patch that defines custom macros for each attribute and
enables them individually for compilers that support them and never
defines __attribute__.

I have tested this with GCC 4.9.2 on Linux x86-64 and Solaris CC 5.12 on
Sparc (32-bit build); I don't have access to an IBM box with XLC.

/ Oskari

[1]: https://docs.oracle.com/cd/E18659_01/html/821-1384/gjzke.html
[2]: http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/var_attrib_aligned.html
http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/var_attrib_aligned.html

Attachments:

0001-Use-custom-macros-for-all-C-__attributes__.patchtext/x-patch; name=0001-Use-custom-macros-for-all-C-__attributes__.patchDownload
From 18c4737eb9f21a4210f8d69a6cd87e371feaca05 Mon Sep 17 00:00:00 2001
From: Oskari Saarenmaa <os@ohmu.fi>
Date: Tue, 13 Jan 2015 21:46:55 +0200
Subject: [PATCH] Use custom macros for all C __attributes__

Previously __attribute__ was defined as an empty macro when __GNUC__ wasn't
defined as the source tree used various GCC specific attributes.  Other
compilers implement a subset of the attributes supported by GCC and we
should use them when possible, especially in the cases where they make a
functional difference like in the case of 'aligned' and 'packed'.

Replace all direct __attribute__ uses with new pg_attribute_X macros which
are defined as __attribute__(()) calls when supported by GCC, Solaris Studio
and XL C and empty in other cases.
---
 contrib/cube/cubescan.l                     |  2 +-
 contrib/pg_upgrade/pg_upgrade.h             | 14 +++++-----
 contrib/pg_upgrade/util.c                   |  2 +-
 contrib/pg_xlogdump/pg_xlogdump.c           |  2 +-
 contrib/pgcrypto/px.h                       |  2 +-
 contrib/seg/segscan.l                       |  2 +-
 src/backend/access/transam/xlogreader.c     |  2 +-
 src/backend/postmaster/autovacuum.c         |  4 +--
 src/backend/postmaster/pgarch.c             |  2 +-
 src/backend/postmaster/pgstat.c             |  2 +-
 src/backend/postmaster/postmaster.c         |  4 +--
 src/backend/postmaster/syslogger.c          |  2 +-
 src/backend/replication/repl_scanner.l      |  2 +-
 src/backend/replication/walsender.c         |  2 +-
 src/backend/utils/error/elog.c              |  2 +-
 src/backend/utils/misc/guc.c                |  2 +-
 src/bin/pg_ctl/pg_ctl.c                     |  2 +-
 src/bin/pg_dump/parallel.c                  |  2 +-
 src/bin/pg_dump/pg_backup.h                 |  2 +-
 src/bin/pg_dump/pg_backup_archiver.h        |  6 ++---
 src/bin/pg_dump/pg_backup_tar.c             |  2 +-
 src/bin/pg_dump/pg_backup_utils.h           |  8 +++---
 src/bin/psql/common.h                       |  2 +-
 src/bin/psql/large_obj.c                    |  2 +-
 src/include/bootstrap/bootstrap.h           |  4 +--
 src/include/c.h                             | 40 ++++++++++++++++++++++++++---
 src/include/common/fe_memutils.h            |  4 +--
 src/include/lib/stringinfo.h                |  4 +--
 src/include/mb/pg_wchar.h                   |  4 +--
 src/include/parser/parse_relation.h         |  4 +--
 src/include/parser/scanner.h                |  2 +-
 src/include/pgstat.h                        |  2 +-
 src/include/port.h                          |  8 +++---
 src/include/port/atomics/generic-gcc.h      |  2 +-
 src/include/port/atomics/generic-sunpro.h   |  2 +-
 src/include/port/atomics/generic-xlc.h      |  2 +-
 src/include/postgres.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/walwriter.h          |  2 +-
 src/include/replication/walreceiver.h       |  2 +-
 src/include/storage/ipc.h                   |  2 +-
 src/include/storage/itemptr.h               |  2 +-
 src/include/storage/lock.h                  |  2 +-
 src/include/tcop/tcopprot.h                 |  6 ++---
 src/include/utils/datetime.h                |  2 +-
 src/include/utils/elog.h                    | 38 +++++++++++++--------------
 src/include/utils/help_config.h             |  2 +-
 src/include/utils/palloc.h                  |  4 +--
 src/interfaces/ecpg/ecpglib/extern.h        |  2 +-
 src/interfaces/ecpg/include/ecpglib.h       |  2 +-
 src/interfaces/ecpg/preproc/ecpg.header     |  2 +-
 src/interfaces/ecpg/preproc/extern.h        |  4 +--
 src/interfaces/libpq/libpq-int.h            |  6 ++---
 src/interfaces/libpq/pqexpbuffer.c          |  2 +-
 src/interfaces/libpq/pqexpbuffer.h          |  4 +--
 src/interfaces/libpq/win32.c                |  2 +-
 src/pl/plperl/plperl.h                      |  4 +--
 src/pl/plpgsql/src/pl_scanner.c             |  2 +-
 src/pl/plpython/plpy_elog.h                 |  8 +++---
 src/test/modules/test_shm_mq/test_shm_mq.h  |  2 +-
 src/test/modules/worker_spi/worker_spi.c    |  2 +-
 src/test/regress/pg_regress.c               |  6 ++---
 68 files changed, 157 insertions(+), 127 deletions(-)

diff --git a/contrib/cube/cubescan.l b/contrib/cube/cubescan.l
index e383b59..1c2522a 100644
--- a/contrib/cube/cubescan.l
+++ b/contrib/cube/cubescan.l
@@ -60,7 +60,7 @@ float        ({integer}|{real})([eE]{integer})?
 
 %%
 
-void __attribute__((noreturn))
+void pg_attribute_noreturn
 yyerror(NDBOX **result, const char *message)
 {
 	if (*yytext == YY_END_OF_BUFFER_CHAR)
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
index 19d59f5..9b873ad 100644
--- a/contrib/pg_upgrade/pg_upgrade.h
+++ b/contrib/pg_upgrade/pg_upgrade.h
@@ -359,7 +359,7 @@ void		optionally_create_toast_tables(void);
 bool
 exec_prog(const char *log_file, const char *opt_log_file,
 		  bool throw_error, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5)));
+pg_attribute_printf(4, 5);
 void		verify_directories(void);
 bool		pid_lock_file_exists(const char *datadir);
 
@@ -445,7 +445,7 @@ void		init_tablespaces(void);
 PGconn	   *connectToServer(ClusterInfo *cluster, const char *db_name);
 PGresult *
 executeQueryOrDie(PGconn *conn, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 char	   *cluster_conn_opts(ClusterInfo *cluster);
 
@@ -462,17 +462,17 @@ int			get_user_info(char **user_name_p);
 void		check_ok(void);
 void
 report_status(eLogType type, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 void
 pg_log(eLogType type, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 void
 pg_fatal(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2), noreturn));
+pg_attribute_printf(1, 2) pg_attribute_noreturn;
 void		end_progress_output(void);
 void
 prep_status(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 void		check_ok(void);
 const char *getErrorText(int errNum);
 unsigned int str2uint(const char *str);
@@ -489,7 +489,7 @@ void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster);
 void
 parallel_exec_prog(const char *log_file, const char *opt_log_file,
 				   const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+pg_attribute_printf(3, 4);
 void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr,
 							  char *old_pgdata, char *new_pgdata,
 							  char *old_tablespace);
diff --git a/contrib/pg_upgrade/util.c b/contrib/pg_upgrade/util.c
index ec18526..ce17aa0 100644
--- a/contrib/pg_upgrade/util.c
+++ b/contrib/pg_upgrade/util.c
@@ -82,7 +82,7 @@ prep_status(const char *fmt,...)
 
 
 static
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)))
+pg_attribute_printf(2, 0)
 void
 pg_log_v(eLogType type, const char *fmt, va_list ap)
 {
diff --git a/contrib/pg_xlogdump/pg_xlogdump.c b/contrib/pg_xlogdump/pg_xlogdump.c
index c1bfbc2..6720f2e 100644
--- a/contrib/pg_xlogdump/pg_xlogdump.c
+++ b/contrib/pg_xlogdump/pg_xlogdump.c
@@ -69,7 +69,7 @@ typedef struct XLogDumpStats
 
 static void
 fatal_error(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 /*
  * Big red button to push when things go horribly wrong.
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index a01a58e..297747c 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -208,7 +208,7 @@ void		px_memset(void *ptr, int c, size_t len);
 #ifdef PX_DEBUG
 void
 px_debug(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 #else
 #define px_debug(...)
 #endif
diff --git a/contrib/seg/segscan.l b/contrib/seg/segscan.l
index a3e6854..5fe4a2c 100644
--- a/contrib/seg/segscan.l
+++ b/contrib/seg/segscan.l
@@ -59,7 +59,7 @@ float        ({integer}|{real})([eE]{integer})?
 
 %%
 
-void __attribute__((noreturn))
+void pg_attribute_noreturn
 yyerror(SEG *result, const char *message)
 {
 	if (*yytext == YY_END_OF_BUFFER_CHAR)
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 60470b5..0166f56 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -35,7 +35,7 @@ static void
 report_invalid_record(XLogReaderState *state, const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 static void ResetDecoder(XLogReaderState *state);
 
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 062b120..c87ca8b 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -287,8 +287,8 @@ int			AutovacuumLauncherPid = 0;
 static pid_t avlauncher_forkexec(void);
 static pid_t avworker_forkexec(void);
 #endif
-NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]) __attribute__((noreturn));
-NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]) __attribute__((noreturn));
+NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn;
+NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn;
 
 static Oid	do_start_worker(void);
 static void launcher_determine_sleep(bool canlaunch, bool recursing,
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 75e7e1b..92e1208 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -91,7 +91,7 @@ static Latch mainloop_latch;
 static pid_t pgarch_forkexec(void);
 #endif
 
-NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) __attribute__((noreturn));
+NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) pg_attribute_noreturn;
 static void pgarch_exit(SIGNAL_ARGS);
 static void ArchSigHupHandler(SIGNAL_ARGS);
 static void ArchSigTermHandler(SIGNAL_ARGS);
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index ea3bd4b..4e7bf9d 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -249,7 +249,7 @@ static instr_time total_func_time;
 static pid_t pgstat_forkexec(void);
 #endif
 
-NON_EXEC_STATIC void PgstatCollectorMain(int argc, char *argv[]) __attribute__((noreturn));
+NON_EXEC_STATIC void PgstatCollectorMain(int argc, char *argv[]) pg_attribute_noreturn;
 static void pgstat_exit(SIGNAL_ARGS);
 static void pgstat_beshutdown_hook(int code, Datum arg);
 static void pgstat_sighup_handler(SIGNAL_ARGS);
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index e2b3b81..719bf6e 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -380,8 +380,8 @@ static void LogChildExit(int lev, const char *procname,
 			 int pid, int exitstatus);
 static void PostmasterStateMachine(void);
 static void BackendInitialize(Port *port);
-static void BackendRun(Port *port) __attribute__((noreturn));
-static void ExitPostmaster(int status) __attribute__((noreturn));
+static void BackendRun(Port *port) pg_attribute_noreturn;
+static void ExitPostmaster(int status) pg_attribute_noreturn;
 static int	ServerLoop(void);
 static int	BackendStartup(Port *port);
 static int	ProcessStartupPacket(Port *port, bool SSLdone);
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index c1b64ac..2f62b6b 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -131,7 +131,7 @@ static volatile sig_atomic_t rotation_requested = false;
 static pid_t syslogger_forkexec(void);
 static void syslogger_parseArgs(int argc, char *argv[]);
 #endif
-NON_EXEC_STATIC void SysLoggerMain(int argc, char *argv[]) __attribute__((noreturn));
+NON_EXEC_STATIC void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn;
 static void process_pipe_input(char *logbuffer, int *bytes_in_logbuffer);
 static void flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer);
 static void open_csvlogfile(void);
diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l
index 449c127..9abe475 100644
--- a/src/backend/replication/repl_scanner.l
+++ b/src/backend/replication/repl_scanner.l
@@ -205,7 +205,7 @@ addlitchar(unsigned char ychar)
 	appendStringInfoChar(&litbuf, ychar);
 }
 
-void __attribute__((noreturn))
+void pg_attribute_noreturn
 yyerror(const char *message)
 {
 	ereport(ERROR,
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 86c36bf..94765a7 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -193,7 +193,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) __attribute__((noreturn));
+static void WalSndShutdown(void) pg_attribute_noreturn;
 static void XLogSendPhysical(void);
 static void XLogSendLogical(void);
 static void WalSndDone(WalSndSendDataCallback send_data);
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index bee2c92..2689e9a 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -86,7 +86,7 @@ static const char *
 err_gettext(const char *str)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format_arg(1)));
+pg_attribute_format_arg(1);
 static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str);
 
 /* Global variables */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index f6df077..86002b9 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -146,7 +146,7 @@ char	   *GUC_check_errhint_string;
 static void
 do_serialize(char **destptr, Size *maxbytes, const char *fmt,...)
 /* This lets gcc check the format string for consistency. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+pg_attribute_printf(3, 4);
 
 static void set_config_sourcefile(const char *name, char *sourcefile,
 					  int sourceline);
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 789fe8f..052caff 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -120,7 +120,7 @@ static void
 write_stderr(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 static void do_advice(void);
 static void do_help(void);
 static void set_mode(char *modeopt);
diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c
index d942a75..db9ec3f 100644
--- a/src/bin/pg_dump/parallel.c
+++ b/src/bin/pg_dump/parallel.c
@@ -81,7 +81,7 @@ static ParallelSlot *GetMyPSlot(ParallelState *pstate);
 static void
 parallel_msg_master(ParallelSlot *slot, const char *modulename,
 					const char *fmt, va_list ap)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
+pg_attribute_printf(3, 0);
 static void archive_close_connection(int code, void *arg);
 static void ShutdownWorkersHard(ParallelState *pstate);
 static void WaitForTerminatingWorkers(ParallelState *pstate);
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index a936ff8..d484236 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -280,7 +280,7 @@ extern void archputs(const char *s, Archive *AH);
 extern int
 archprintf(Archive *AH, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 #define appendStringLiteralAH(buf,str,AH) \
 	appendStringLiteral(buf, str, (AH)->encoding, (AH)->std_strings)
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 144027c..620ada5 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -378,7 +378,7 @@ struct _tocEntry
 extern int	parallel_restore(struct ParallelArgs *args);
 extern void on_exit_close_archive(Archive *AHX);
 
-extern void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+extern void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) pg_attribute_printf(3, 4);
 
 extern void WriteTOC(ArchiveHandle *AH);
 extern void ReadTOC(ArchiveHandle *AH);
@@ -429,8 +429,8 @@ extern int	ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *
 extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid);
 
 void		ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH);
-int			ahprintf(ArchiveHandle *AH, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+int			ahprintf(ArchiveHandle *AH, const char *fmt,...) pg_attribute_printf(2, 3);
 
-void		ahlog(ArchiveHandle *AH, int level, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+void		ahlog(ArchiveHandle *AH, int level, const char *fmt,...) pg_attribute_printf(3, 4);
 
 #endif
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index f48d369..309b4b5 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -115,7 +115,7 @@ static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH);
 #ifdef __NOT_USED__
 static char *tarGets(char *buf, size_t len, TAR_MEMBER *th);
 #endif
-static int	tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+static int	tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) pg_attribute_printf(3, 4);
 
 static void _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th);
 static TAR_MEMBER *_tarPositionTo(ArchiveHandle *AH, const char *filename);
diff --git a/src/bin/pg_dump/pg_backup_utils.h b/src/bin/pg_dump/pg_backup_utils.h
index 1bcc1a7..2e9a69a 100644
--- a/src/bin/pg_dump/pg_backup_utils.h
+++ b/src/bin/pg_dump/pg_backup_utils.h
@@ -30,15 +30,15 @@ extern const char *progname;
 extern void set_dump_section(const char *arg, int *dumpSections);
 extern void
 write_msg(const char *modulename, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 extern void
 vwrite_msg(const char *modulename, const char *fmt, va_list ap)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+pg_attribute_printf(2, 0);
 extern void on_exit_nicely(on_exit_nicely_callback function, void *arg);
-extern void exit_nicely(int code) __attribute__((noreturn));
+extern void exit_nicely(int code) pg_attribute_noreturn;
 
 extern void
 exit_horribly(const char *modulename, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
+pg_attribute_printf(2, 3) pg_attribute_noreturn;
 
 #endif   /* PG_BACKUP_UTILS_H */
diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h
index eb14d1c..54266c1 100644
--- a/src/bin/psql/common.h
+++ b/src/bin/psql/common.h
@@ -21,7 +21,7 @@ extern bool setQFout(const char *fname);
 extern void
 psql_error(const char *fmt,...)
 /* This lets gcc check the format string for consistency. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern void NoticeProcessor(void *arg, const char *message);
 
diff --git a/src/bin/psql/large_obj.c b/src/bin/psql/large_obj.c
index 709869e..48d2d77 100644
--- a/src/bin/psql/large_obj.c
+++ b/src/bin/psql/large_obj.c
@@ -14,7 +14,7 @@
 
 static void
 print_lo_result(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 static void
 print_lo_result(const char *fmt,...)
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index be4430a..0966b73 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -28,7 +28,7 @@ extern Form_pg_attribute attrtypes[MAXATTR];
 extern int	numattr;
 
 
-extern void AuxiliaryProcessMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void AuxiliaryProcessMain(int argc, char *argv[]) pg_attribute_noreturn;
 
 extern void err_out(void);
 
@@ -57,6 +57,6 @@ extern void boot_get_type_io_data(Oid typid,
 extern int	boot_yyparse(void);
 
 extern int	boot_yylex(void);
-extern void boot_yyerror(const char *str) __attribute__((noreturn));
+extern void boot_yyerror(const char *str) pg_attribute_noreturn;
 
 #endif   /* BOOTSTRAP_H */
diff --git a/src/include/c.h b/src/include/c.h
index c929d3d..660ae8e 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -156,8 +156,40 @@
 #define dummyret	char
 #endif
 
-#ifndef __GNUC__
-#define __attribute__(_arg_)
+/*
+ * Attribute macros
+ * GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
+ * GCC: https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
+ * Sunpro: https://docs.oracle.com/cd/E18659_01/html/821-1384/gjzke.html
+ * XLC: http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/function_attributes.html
+ * XLC: http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/type_attrib.html
+ */
+
+/* GCC supports unused attribute */
+#ifdef __GNUC__
+#define pg_attribute_unused __attribute__((unused))
+#else
+#define pg_attribute_unused
+#endif
+
+/* GCC and XLC support format attributes */
+#if defined(__GNUC__) || defined(__IBMC__)
+#define pg_attribute_format_arg(a) __attribute__((format_arg(a)))
+#define pg_attribute_printf(f,a) __attribute__((format(PG_PRINTF_ATTRIBUTE, f, a)))
+#else
+#define pg_attribute_format_arg(a)
+#define pg_attribute_printf(f,a)
+#endif
+
+/* GCC, Sunpro and XLC support aligned, packed and noreturn */
+#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__)
+#define pg_attribute_aligned(a) __attribute__((aligned(a)))
+#define pg_attribute_noreturn __attribute__((noreturn))
+#define pg_attribute_packed __attribute__((packed))
+#else
+#define pg_attribute_aligned(a)
+#define pg_attribute_noreturn
+#define pg_attribute_packed
 #endif
 
 /* ----------------------------------------------------------------
@@ -905,7 +937,7 @@ typedef NameData *Name;
 #ifdef USE_ASSERT_CHECKING
 #define PG_USED_FOR_ASSERTS_ONLY
 #else
-#define PG_USED_FOR_ASSERTS_ONLY __attribute__((unused))
+#define PG_USED_FOR_ASSERTS_ONLY pg_attribute_unused
 #endif
 
 
@@ -972,7 +1004,7 @@ typedef NameData *Name;
 extern int
 snprintf(char *str, size_t count, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+pg_attribute_printf(3, 4);
 #endif
 
 #if !HAVE_DECL_VSNPRINTF
diff --git a/src/include/common/fe_memutils.h b/src/include/common/fe_memutils.h
index f7114c2..33123cb 100644
--- a/src/include/common/fe_memutils.h
+++ b/src/include/common/fe_memutils.h
@@ -26,9 +26,9 @@ extern void pfree(void *pointer);
 /* sprintf into a palloc'd buffer --- these are in psprintf.c */
 extern char *
 psprintf(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 extern size_t
 pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
+pg_attribute_printf(3, 0);
 
 #endif   /* FE_MEMUTILS_H */
diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h
index 63d39e5..fdb8285 100644
--- a/src/include/lib/stringinfo.h
+++ b/src/include/lib/stringinfo.h
@@ -95,7 +95,7 @@ extern void resetStringInfo(StringInfo str);
 extern void
 appendStringInfo(StringInfo str, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 /*------------------------
  * appendStringInfoVA
@@ -108,7 +108,7 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
  */
 extern int
 appendStringInfoVA(StringInfo str, const char *fmt, va_list args)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+pg_attribute_printf(2, 0);
 
 /*------------------------
  * appendStringInfoString
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 231003f..0a2234d 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -514,9 +514,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) __attribute__((noreturn));
+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) __attribute__((noreturn));
+					   const char *mbstr, int len) pg_attribute_noreturn;
 
 extern void pg_ascii2mic(const unsigned char *l, unsigned char *p, int len);
 extern void pg_mic2ascii(const unsigned char *mic, unsigned char *p, int len);
diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h
index c886335..fc0a257 100644
--- a/src/include/parser/parse_relation.h
+++ b/src/include/parser/parse_relation.h
@@ -85,9 +85,9 @@ extern bool isLockedRefname(ParseState *pstate, const char *refname);
 extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
 			  bool addToJoinList,
 			  bool addToRelNameSpace, bool addToVarNameSpace);
-extern void errorMissingRTE(ParseState *pstate, RangeVar *relation) __attribute__((noreturn));
+extern void errorMissingRTE(ParseState *pstate, RangeVar *relation) pg_attribute_noreturn;
 extern void errorMissingColumn(ParseState *pstate,
-	   char *relname, char *colname, int location) __attribute__((noreturn));
+	   char *relname, char *colname, int location) pg_attribute_noreturn;
 extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
 		  int location, bool include_dropped,
 		  List **colnames, List **colvars);
diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h
index 02e8764..6657fb6 100644
--- a/src/include/parser/scanner.h
+++ b/src/include/parser/scanner.h
@@ -114,6 +114,6 @@ extern void scanner_finish(core_yyscan_t yyscanner);
 extern int core_yylex(core_YYSTYPE *lvalp, YYLTYPE *llocp,
 		   core_yyscan_t yyscanner);
 extern int	scanner_errposition(int location, core_yyscan_t yyscanner);
-extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner) __attribute__((noreturn));
+extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner) pg_attribute_noreturn;
 
 #endif   /* SCANNER_H */
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 416769a..ac1512d 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -870,7 +870,7 @@ extern void pgstat_reset_all(void);
 extern void allow_immediate_pgstat_restart(void);
 
 #ifdef EXEC_BACKEND
-extern void PgstatCollectorMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void PgstatCollectorMain(int argc, char *argv[]) pg_attribute_noreturn;
 #endif
 
 
diff --git a/src/include/port.h b/src/include/port.h
index 26d7fcd..8b67c35 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -156,20 +156,20 @@ extern int	pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
 extern int
 pg_snprintf(char *str, size_t count, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+pg_attribute_printf(3, 4);
 extern int
 pg_sprintf(char *str, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 extern int	pg_vfprintf(FILE *stream, const char *fmt, va_list args);
 extern int
 pg_fprintf(FILE *stream, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 extern int
 pg_printf(const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 /*
  *	The GCC-specific code below prevents the __attribute__(... 'printf')
diff --git a/src/include/port/atomics/generic-gcc.h b/src/include/port/atomics/generic-gcc.h
index fea1cb5..c9fc87b 100644
--- a/src/include/port/atomics/generic-gcc.h
+++ b/src/include/port/atomics/generic-gcc.h
@@ -98,7 +98,7 @@ typedef struct pg_atomic_uint32
 
 typedef struct pg_atomic_uint64
 {
-	volatile uint64 value __attribute__((aligned(8)));
+	volatile uint64 value pg_attribute_aligned(8);
 } pg_atomic_uint64;
 
 #endif /* defined(HAVE_GCC__ATOMIC_INT64_CAS) || defined(HAVE_GCC__SYNC_INT64_CAS) */
diff --git a/src/include/port/atomics/generic-sunpro.h b/src/include/port/atomics/generic-sunpro.h
index 7a3028e..d369207 100644
--- a/src/include/port/atomics/generic-sunpro.h
+++ b/src/include/port/atomics/generic-sunpro.h
@@ -61,7 +61,7 @@ typedef struct pg_atomic_uint64
 	 * it proves to be a problem, we'll have to add more version checks for 64
 	 * bit support.
 	 */
-	volatile uint64 value __attribute__((__aligned__(8)));
+	volatile uint64 value pg_attribute_aligned(8);
 } pg_atomic_uint64;
 
 #endif /* HAVE_ATOMIC_H */
diff --git a/src/include/port/atomics/generic-xlc.h b/src/include/port/atomics/generic-xlc.h
index 7a4c12a..1c743f2 100644
--- a/src/include/port/atomics/generic-xlc.h
+++ b/src/include/port/atomics/generic-xlc.h
@@ -32,7 +32,7 @@ typedef struct pg_atomic_uint32
 #define PG_HAVE_ATOMIC_U64_SUPPORT
 typedef struct pg_atomic_uint64
 {
-	volatile uint64 value __attribute__((__aligned__(8)));
+	volatile uint64 value pg_attribute_aligned(8);
 } pg_atomic_uint64;
 
 #endif /* __64BIT__ */
diff --git a/src/include/postgres.h b/src/include/postgres.h
index dfce01b..49d54d3 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -686,6 +686,6 @@ extern Datum Float8GetDatum(float8 X);
  */
 extern void ExceptionalCondition(const char *conditionName,
 					 const char *errorType,
-			 const char *fileName, int lineNumber) __attribute__((noreturn));
+			 const char *fileName, int lineNumber) pg_attribute_noreturn;
 
 #endif   /* POSTGRES_H */
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index 121f107..0bd5044 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -54,8 +54,8 @@ extern void AutoVacWorkerFailed(void);
 extern void AutoVacuumUpdateDelay(void);
 
 #ifdef EXEC_BACKEND
-extern void AutoVacLauncherMain(int argc, char *argv[]) __attribute__((noreturn));
-extern void AutoVacWorkerMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn;
+extern void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn;
 extern void AutovacuumWorkerIAm(void);
 extern void AutovacuumLauncherIAm(void);
 #endif
diff --git a/src/include/postmaster/bgworker_internals.h b/src/include/postmaster/bgworker_internals.h
index 81c03e4..fe7c328 100644
--- a/src/include/postmaster/bgworker_internals.h
+++ b/src/include/postmaster/bgworker_internals.h
@@ -46,7 +46,7 @@ extern void BackgroundWorkerStopNotifications(pid_t pid);
 extern void ResetBackgroundWorkerCrashTimes(void);
 
 /* Function to start a background worker, called from postmaster.c */
-extern void StartBackgroundWorker(void) __attribute__((noreturn));
+extern void StartBackgroundWorker(void) pg_attribute_noreturn;
 
 #ifdef EXEC_BACKEND
 extern BackgroundWorker *BackgroundWorkerEntry(int slotno);
diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h
index ce12619..f584d85 100644
--- a/src/include/postmaster/bgwriter.h
+++ b/src/include/postmaster/bgwriter.h
@@ -25,8 +25,8 @@ extern int	CheckPointTimeout;
 extern int	CheckPointWarning;
 extern double CheckPointCompletionTarget;
 
-extern void BackgroundWriterMain(void) __attribute__((noreturn));
-extern void CheckpointerMain(void) __attribute__((noreturn));
+extern void BackgroundWriterMain(void) pg_attribute_noreturn;
+extern void CheckpointerMain(void) pg_attribute_noreturn;
 
 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 a585e67..60e4f50 100644
--- a/src/include/postmaster/pgarch.h
+++ b/src/include/postmaster/pgarch.h
@@ -33,7 +33,7 @@
 extern int	pgarch_start(void);
 
 #ifdef EXEC_BACKEND
-extern void PgArchiverMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void PgArchiverMain(int argc, char *argv[]) pg_attribute_noreturn;
 #endif
 
 #endif   /* _PGARCH_H */
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
index 91723f7..d41761f 100644
--- a/src/include/postmaster/postmaster.h
+++ b/src/include/postmaster/postmaster.h
@@ -46,7 +46,7 @@ extern int	postmaster_alive_fds[2];
 
 extern const char *progname;
 
-extern void PostmasterMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void PostmasterMain(int argc, char *argv[]) pg_attribute_noreturn;
 extern void ClosePostmasterPorts(bool am_syslogger);
 
 extern int	MaxLivePostmasterChildren(void);
@@ -56,7 +56,7 @@ extern bool PostmasterMarkPIDForWorkerNotify(int);
 
 #ifdef EXEC_BACKEND
 extern pid_t postmaster_forkexec(int argc, char *argv[]);
-extern void SubPostmasterMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void SubPostmasterMain(int argc, char *argv[]) pg_attribute_noreturn;
 
 extern Size ShmemBackendArraySize(void);
 extern void ShmemBackendArrayAllocation(void);
diff --git a/src/include/postmaster/startup.h b/src/include/postmaster/startup.h
index da1f6e9..9a2092e 100644
--- a/src/include/postmaster/startup.h
+++ b/src/include/postmaster/startup.h
@@ -13,7 +13,7 @@
 #define _STARTUP_H
 
 extern void HandleStartupProcInterrupts(void);
-extern void StartupProcessMain(void) __attribute__((noreturn));
+extern void StartupProcessMain(void) pg_attribute_noreturn;
 extern void PreRestoreCommand(void);
 extern void PostRestoreCommand(void);
 extern bool IsPromoteTriggered(void);
diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h
index 602b13c..c6a48dc 100644
--- a/src/include/postmaster/syslogger.h
+++ b/src/include/postmaster/syslogger.h
@@ -84,7 +84,7 @@ extern int	SysLogger_Start(void);
 extern void write_syslogger_file(const char *buffer, int count, int dest);
 
 #ifdef EXEC_BACKEND
-extern void SysLoggerMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn;
 #endif
 
 #endif   /* _SYSLOGGER_H */
diff --git a/src/include/postmaster/walwriter.h b/src/include/postmaster/walwriter.h
index de45a01..55de6c7 100644
--- a/src/include/postmaster/walwriter.h
+++ b/src/include/postmaster/walwriter.h
@@ -15,6 +15,6 @@
 /* GUC options */
 extern int	WalWriterDelay;
 
-extern void WalWriterMain(void) __attribute__((noreturn));
+extern void WalWriterMain(void) pg_attribute_noreturn;
 
 #endif   /* _WALWRITER_H */
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index defe8f9..4afdf91 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -147,7 +147,7 @@ typedef void (*walrcv_disconnect_type) (void);
 extern PGDLLIMPORT walrcv_disconnect_type walrcv_disconnect;
 
 /* prototypes for functions in walreceiver.c */
-extern void WalReceiverMain(void) __attribute__((noreturn));
+extern void WalReceiverMain(void) pg_attribute_noreturn;
 
 /* prototypes for functions in walreceiverfuncs.c */
 extern Size WalRcvShmemSize(void);
diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h
index 54fa2ba..7da434e 100644
--- a/src/include/storage/ipc.h
+++ b/src/include/storage/ipc.h
@@ -64,7 +64,7 @@ typedef void (*shmem_startup_hook_type) (void);
 /* ipc.c */
 extern PGDLLIMPORT bool proc_exit_inprogress;
 
-extern void proc_exit(int code) __attribute__((noreturn));
+extern void proc_exit(int code) pg_attribute_noreturn;
 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/itemptr.h b/src/include/storage/itemptr.h
index 944812c..1f0ea7d 100644
--- a/src/include/storage/itemptr.h
+++ b/src/include/storage/itemptr.h
@@ -41,7 +41,7 @@ typedef struct ItemPointerData
 }
 
 #ifdef __arm__
-__attribute__((packed))			/* Appropriate whack upside the head for ARM */
+pg_attribute_packed			/* Appropriate whack upside the head for ARM */
 #endif
 ItemPointerData;
 
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 1100923..1477a6f 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -547,7 +547,7 @@ extern void lock_twophase_standby_recover(TransactionId xid, uint16 info,
 
 extern DeadLockState DeadLockCheck(PGPROC *proc);
 extern PGPROC *GetBlockingAutoVacuumPgproc(void);
-extern void DeadLockReport(void) __attribute__((noreturn));
+extern void DeadLockReport(void) pg_attribute_noreturn;
 extern void RememberSimpleDeadLock(PGPROC *proc1,
 					   LOCKMODE lockmode,
 					   LOCK *lock,
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 0a350fd..0a9ad3f 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -62,9 +62,9 @@ extern bool check_max_stack_depth(int *newval, void **extra, GucSource source);
 extern void assign_max_stack_depth(int newval, void *extra);
 
 extern void die(SIGNAL_ARGS);
-extern void quickdie(SIGNAL_ARGS) __attribute__((noreturn));
+extern void quickdie(SIGNAL_ARGS) pg_attribute_noreturn;
 extern void StatementCancelHandler(SIGNAL_ARGS);
-extern void FloatExceptionHandler(SIGNAL_ARGS) __attribute__((noreturn));
+extern void FloatExceptionHandler(SIGNAL_ARGS) pg_attribute_noreturn;
 extern void RecoveryConflictInterrupt(ProcSignalReason reason); /* called from SIGUSR1
 																 * handler */
 extern void prepare_for_client_read(void);
@@ -73,7 +73,7 @@ extern void process_postgres_switches(int argc, char *argv[],
 						  GucContext ctx, const char **dbname);
 extern void PostgresMain(int argc, char *argv[],
 			 const char *dbname,
-			 const char *username) __attribute__((noreturn));
+			 const char *username) pg_attribute_noreturn;
 extern long get_stack_depth_rlimit(void);
 extern void ResetUsage(void);
 extern void ShowUsage(const char *title);
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 8912ba5..a403374 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -315,7 +315,7 @@ extern int DecodeISO8601Interval(char *str,
 					  int *dtype, struct pg_tm * tm, fsec_t *fsec);
 
 extern void DateTimeParseError(int dterr, const char *str,
-				   const char *datatype) __attribute__((noreturn));
+				   const char *datatype) pg_attribute_noreturn;
 
 extern int	DetermineTimeZoneOffset(struct pg_tm * tm, pg_tz *tzp);
 extern int	DetermineTimeZoneAbbrevOffset(struct pg_tm * tm, const char *abbr, pg_tz *tzp);
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index fe5dec0..d804afd 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -147,61 +147,61 @@ extern int
 errmsg(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errmsg_internal(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errmsg_plural(const char *fmt_singular, const char *fmt_plural,
 			  unsigned long n,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4)))
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4)));
+pg_attribute_printf(1, 4)
+pg_attribute_printf(2, 4);
 
 extern int
 errdetail(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errdetail_internal(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errdetail_log(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errdetail_log_plural(const char *fmt_singular, const char *fmt_plural,
 					 unsigned long n,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4)))
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4)));
+pg_attribute_printf(1, 4)
+pg_attribute_printf(2, 4);
 
 extern int
 errdetail_plural(const char *fmt_singular, const char *fmt_plural,
 				 unsigned long n,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4)))
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4)));
+pg_attribute_printf(1, 4)
+pg_attribute_printf(2, 4);
 
 extern int
 errhint(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 /*
  * errcontext() is typically called in error context callback functions, not
@@ -218,7 +218,7 @@ extern int
 errcontext_msg(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int	errhidestmt(bool hide_stmt);
 extern int	errhidecontext(bool hide_ctx);
@@ -278,7 +278,7 @@ extern void
 elog_finish(int elevel, const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 
 /* Support for constructing error strings separately from ereport() calls */
@@ -288,7 +288,7 @@ extern char *
 format_elog_string(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 
 /* Support for attaching context information to error reports */
@@ -357,7 +357,7 @@ extern PGDLLIMPORT ErrorContextCallback *error_context_stack;
 	} while (0)
 
 /*
- * gcc understands __attribute__((noreturn)); for other compilers, insert
+ * gcc understands pg_attribute_noreturn; for other compilers, insert
  * pg_unreachable() so that the compiler gets the point.
  */
 #ifdef __GNUC__
@@ -416,9 +416,9 @@ extern void EmitErrorReport(void);
 extern ErrorData *CopyErrorData(void);
 extern void FreeErrorData(ErrorData *edata);
 extern void FlushErrorState(void);
-extern void ReThrowError(ErrorData *edata) __attribute__((noreturn));
+extern void ReThrowError(ErrorData *edata) pg_attribute_noreturn;
 extern void ThrowErrorData(ErrorData *edata);
-extern void pg_re_throw(void) __attribute__((noreturn));
+extern void pg_re_throw(void) pg_attribute_noreturn;
 
 extern char *GetErrorContextStack(void);
 
@@ -465,6 +465,6 @@ extern void
 write_stderr(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 #endif   /* ELOG_H */
diff --git a/src/include/utils/help_config.h b/src/include/utils/help_config.h
index 481687f..af52996 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) __attribute__((noreturn));
+extern void GucInfoMain(void) pg_attribute_noreturn;
 
 #endif
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index ca03f2b..a3e3697 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -109,9 +109,9 @@ extern char *pnstrdup(const char *in, Size len);
 /* sprintf into a palloc'd buffer --- these are in psprintf.c */
 extern char *
 psprintf(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 extern size_t
 pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
+pg_attribute_printf(3, 0);
 
 #endif   /* PALLOC_H */
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 3836007..139de7c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -185,7 +185,7 @@ void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
 void		ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat);
 char	   *ecpg_prepared(const char *, struct connection *);
 bool		ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection * conn);
-void		ecpg_log(const char *format,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+void		ecpg_log(const char *format,...) pg_attribute_printf(1, 2);
 bool		ecpg_auto_prepare(int, const char *, const int, char **, const char *);
 void		ecpg_init_sqlca(struct sqlca_t * sqlca);
 
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 3b8ed4c..5efe593 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -15,7 +15,7 @@
 #ifdef ENABLE_NLS
 extern char *
 ecpg_gettext(const char *msgid)
-__attribute__((format_arg(1)));
+pg_attribute_format_arg(1);
 #else
 #define ecpg_gettext(x) (x)
 #endif
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index a2be29c..e23407e 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -64,7 +64,7 @@ static struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NUL
 /*
  * Handle parsing errors and warnings
  */
-static void __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)))
+static void pg_attribute_printf(3, 0)
 vmmerror(int error_code, enum errortype type, const char *error, va_list ap)
 {
 	/* localize the error message string */
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index dfc75bc..1ce25eb 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -77,8 +77,8 @@ extern int	base_yylex(void);
 extern void base_yyerror(const char *);
 extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
 extern char *mm_strdup(const char *);
-extern void mmerror(int errorcode, enum errortype type, const char *error,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
-extern void mmfatal(int errorcode, const char *error,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
+extern void mmerror(int errorcode, enum errortype type, const char *error,...) pg_attribute_printf(3, 4);
+extern void mmfatal(int errorcode, const char *error,...) pg_attribute_printf(2, 3) pg_attribute_noreturn;
 extern void output_get_descr_header(char *);
 extern void output_get_descr(char *, char *);
 extern void output_set_descr_header(char *);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 008fd67..68e1ac2 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -548,7 +548,7 @@ extern PGresult *pqPrepareAsyncResult(PGconn *conn);
 extern void
 pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
 /* This lets gcc check the format string for consistency. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 extern void pqSaveMessageField(PGresult *res, char code,
 				   const char *value);
 extern void pqSaveParameterStatus(PGconn *conn, const char *name,
@@ -653,10 +653,10 @@ extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
 #ifdef ENABLE_NLS
 extern char *
 libpq_gettext(const char *msgid)
-__attribute__((format_arg(1)));
+pg_attribute_format_arg(1);
 extern char *
 libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n)
-__attribute__((format_arg(1))) __attribute__((format_arg(2)));
+pg_attribute_format_arg(1) pg_attribute_format_arg(2);
 #else
 #define libpq_gettext(x) (x)
 #define libpq_ngettext(s, p, n) ((n) == 1 ? (s) : (p))
diff --git a/src/interfaces/libpq/pqexpbuffer.c b/src/interfaces/libpq/pqexpbuffer.c
index 15117a3..43df56a 100644
--- a/src/interfaces/libpq/pqexpbuffer.c
+++ b/src/interfaces/libpq/pqexpbuffer.c
@@ -39,7 +39,7 @@ static const char oom_buffer[1] = "";
 
 static bool
 appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+pg_attribute_printf(2, 0);
 
 
 /*
diff --git a/src/interfaces/libpq/pqexpbuffer.h b/src/interfaces/libpq/pqexpbuffer.h
index 3598271..345d203 100644
--- a/src/interfaces/libpq/pqexpbuffer.h
+++ b/src/interfaces/libpq/pqexpbuffer.h
@@ -149,7 +149,7 @@ extern int	enlargePQExpBuffer(PQExpBuffer str, size_t needed);
 extern void
 printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 /*------------------------
  * appendPQExpBuffer
@@ -161,7 +161,7 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
 extern void
 appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 /*------------------------
  * appendPQExpBufferStr
diff --git a/src/interfaces/libpq/win32.c b/src/interfaces/libpq/win32.c
index 4d2497a..04c5ed4 100644
--- a/src/interfaces/libpq/win32.c
+++ b/src/interfaces/libpq/win32.c
@@ -36,7 +36,7 @@
 #ifdef ENABLE_NLS
 extern char *
 libpq_gettext(const char *msgid)
-__attribute__((format_arg(1)));
+pg_attribute_format_arg(1);
 #else
 #define libpq_gettext(x) (x)
 #endif
diff --git a/src/pl/plperl/plperl.h b/src/pl/plperl/plperl.h
index 89bbd7c..aadb888 100644
--- a/src/pl/plperl/plperl.h
+++ b/src/pl/plperl/plperl.h
@@ -30,9 +30,7 @@
  * Supply a value of PERL_UNUSED_DECL that will satisfy gcc - the one
  * perl itself supplies doesn't seem to.
  */
-#if defined(__GNUC__)
-#define PERL_UNUSED_DECL __attribute__ ((unused))
-#endif
+#define PERL_UNUSED_DECL pg_attribute_unused
 
 /*
  * Sometimes perl carefully scribbles on our *printf macros.
diff --git a/src/pl/plpgsql/src/pl_scanner.c b/src/pl/plpgsql/src/pl_scanner.c
index ec08b02..f932377 100644
--- a/src/pl/plpgsql/src/pl_scanner.c
+++ b/src/pl/plpgsql/src/pl_scanner.c
@@ -608,7 +608,7 @@ plpgsql_scanner_errposition(int location)
  * be misleading!
  */
 void
-__attribute__((noreturn))
+pg_attribute_noreturn
 plpgsql_yyerror(const char *message)
 {
 	char	   *yytext = core_yy.scanbuf + plpgsql_yylloc;
diff --git a/src/pl/plpython/plpy_elog.h b/src/pl/plpython/plpy_elog.h
index 6b8d485..e4e4dfb 100644
--- a/src/pl/plpython/plpy_elog.h
+++ b/src/pl/plpython/plpy_elog.h
@@ -12,16 +12,16 @@ extern PyObject *PLy_exc_spi_error;
 
 extern void
 PLy_elog(int elevel, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 extern void
 PLy_exception_set(PyObject *exc, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 extern void
 PLy_exception_set_plural(PyObject *exc, const char *fmt_singular, const char *fmt_plural,
 						 unsigned long n,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 5)))
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 5)));
+pg_attribute_printf(2, 5)
+pg_attribute_printf(3, 5);
 
 #endif   /* PLPY_ELOG_H */
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 144345b..94d2880 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 void test_shm_mq_main(Datum) __attribute__((noreturn));
+extern void test_shm_mq_main(Datum) pg_attribute_noreturn;
 
 #endif
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index ac0f59c..7fa66d8 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -46,7 +46,7 @@ PG_MODULE_MAGIC;
 PG_FUNCTION_INFO_V1(worker_spi_launch);
 
 void		_PG_init(void);
-void		worker_spi_main(Datum) __attribute__((noreturn));
+void		worker_spi_main(Datum) pg_attribute_noreturn;
 
 /* flags set by signal handlers */
 static volatile sig_atomic_t got_sighup = false;
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 2cd2d0b..71bb8e9 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -135,17 +135,17 @@ static void
 header(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 static void
 status(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 static void
 psql_command(const char *database, const char *query,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 #ifdef WIN32
 typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
-- 
2.1.0

#2Robert Haas
robertmhaas@gmail.com
In reply to: Oskari Saarenmaa (#1)
Re: __attribute__ for non-gcc compilers

On Tue, Jan 13, 2015 at 4:18 PM, Oskari Saarenmaa <os@ohmu.fi> wrote:

Commit db4ec2ffce35 added alignment attributes for 64-bit atomic
variables as required on 32-bit platforms using
__attribute__((aligned(8)). That works fine with GCC, and would work
with Solaris Studio Compiler [1] and IBM XL C [2], but src/include/c.h
defines __attribute__ as an empty macro when not using GCC.
Unfortunately we can't just disable that #define and enable all
__attributes__ for Solaris CC and XLC as we use a bunch of attributes
that are not supported by those compilers and using them unconditionally
would generate a lot of warnings.

Attached a patch that defines custom macros for each attribute and
enables them individually for compilers that support them and never
defines __attribute__.

I have tested this with GCC 4.9.2 on Linux x86-64 and Solaris CC 5.12 on
Sparc (32-bit build); I don't have access to an IBM box with XLC.

I guess my first question is whether we want to be relying on
__attribute__((aligned)) in the first place. If we do, then this
seems like a pretty sensible and necessary change.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Andres Freund
andres@2ndquadrant.com
In reply to: Robert Haas (#2)
Re: __attribute__ for non-gcc compilers

On 2015-01-14 15:48:47 -0500, Robert Haas wrote:

On Tue, Jan 13, 2015 at 4:18 PM, Oskari Saarenmaa <os@ohmu.fi> wrote:

Commit db4ec2ffce35 added alignment attributes for 64-bit atomic
variables as required on 32-bit platforms using
__attribute__((aligned(8)). That works fine with GCC, and would work
with Solaris Studio Compiler [1] and IBM XL C [2], but src/include/c.h
defines __attribute__ as an empty macro when not using GCC.
Unfortunately we can't just disable that #define and enable all
__attributes__ for Solaris CC and XLC as we use a bunch of attributes
that are not supported by those compilers and using them unconditionally
would generate a lot of warnings.

Attached a patch that defines custom macros for each attribute and
enables them individually for compilers that support them and never
defines __attribute__.

I have tested this with GCC 4.9.2 on Linux x86-64 and Solaris CC 5.12 on
Sparc (32-bit build); I don't have access to an IBM box with XLC.

I guess my first question is whether we want to be relying on
__attribute__((aligned)) in the first place.

I think it's better than the alternatives:

a) Don't support 64bit atomics on any 32bit platform. I think that'd be
sad because there's some places that could greatly benefit from being
able to read/store/manipulate e.g. LSNs atomically.
b) Double the size of 64bit atomics on 32bit platforms, and add
TYPEALIGN() to every access inside the atomics implementation.
c) Require 64 atomics to be aligned appropriately manually in every
place they're embedded. I think that's completely impractical.

The only viable one imo is a)

Since the atomics code is compiler dependant anyway, I don't much of a
problem with relying on compiler specific alignment
instructions. Really, the only problem right now is that __attribute__
is defined to be empty on compilers where it has meaning.

If we do, then this seems like a pretty sensible and necessary change.

I think it's also an improvment independent from the alignment
code. Having a more widely portable __attribute__((noreturn)),
__attribute__((unused)), __attribute__((format(..))) seems like a good
general improvement. And all of these are supported in other compilers
than gcc.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Robert Haas
robertmhaas@gmail.com
In reply to: Andres Freund (#3)
Re: __attribute__ for non-gcc compilers

On Wed, Jan 14, 2015 at 5:29 PM, Andres Freund <andres@2ndquadrant.com> wrote:

I think it's better than the alternatives:

a) Don't support 64bit atomics on any 32bit platform. I think that'd be
sad because there's some places that could greatly benefit from being
able to read/store/manipulate e.g. LSNs atomically.
b) Double the size of 64bit atomics on 32bit platforms, and add
TYPEALIGN() to every access inside the atomics implementation.
c) Require 64 atomics to be aligned appropriately manually in every
place they're embedded. I think that's completely impractical.

The only viable one imo is a)

I can't really fault that reasoning, but if __attribute__((align))
only works on some platforms, then you've got silent, subtle breakage
on the ones where it doesn't.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Andres Freund
andres@2ndquadrant.com
In reply to: Robert Haas (#4)
Re: __attribute__ for non-gcc compilers

On 2015-01-14 17:46:39 -0500, Robert Haas wrote:

On Wed, Jan 14, 2015 at 5:29 PM, Andres Freund <andres@2ndquadrant.com> wrote:

I think it's better than the alternatives:

a) Don't support 64bit atomics on any 32bit platform. I think that'd be
sad because there's some places that could greatly benefit from being
able to read/store/manipulate e.g. LSNs atomically.
b) Double the size of 64bit atomics on 32bit platforms, and add
TYPEALIGN() to every access inside the atomics implementation.
c) Require 64 atomics to be aligned appropriately manually in every
place they're embedded. I think that's completely impractical.

The only viable one imo is a)

I can't really fault that reasoning, but if __attribute__((align))
only works on some platforms, then you've got silent, subtle breakage
on the ones where it doesn't.

The __attribute__((align()))'s are in compiler specific code sections
anyway - and there's asserts ensuring that the alignment is correct in
all routines where it matters (IIRC). Those are what caught the
problem. C.f.
http://archives.postgresql.org/message-id/20150108204635.GK6299%40alap3.anarazel.de

I think I'd for now simply not define pg_attribute_aligned() on
platforms where it's not supported, instead of defining it empty. If we
need a softer variant we can name it pg_attribute_aligned_if_possible or
something.

Sounds sane?

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

In reply to: Andres Freund (#5)
Re: __attribute__ for non-gcc compilers

15.01.2015, 00:54, Andres Freund kirjoitti:

I think I'd for now simply not define pg_attribute_aligned() on
platforms where it's not supported, instead of defining it empty. If we
need a softer variant we can name it pg_attribute_aligned_if_possible or
something.

Good point, all attributes that actually change program behavior
(aligned and packed for now) need to error out during compilation if
they're used and they're not supported by the compiler.

Attributes which may improve optimization or just provide more
information for the developers (noreturn, unused, format) can be defined
empty when they're not supported (or are not supported well enough: GCC
< 3 doesn't know about %z in printf format.)

/ Oskari

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Robert Haas
robertmhaas@gmail.com
In reply to: Andres Freund (#5)
Re: __attribute__ for non-gcc compilers

On Wed, Jan 14, 2015 at 5:54 PM, Andres Freund <andres@2ndquadrant.com> wrote:

I think I'd for now simply not define pg_attribute_aligned() on
platforms where it's not supported, instead of defining it empty. If we
need a softer variant we can name it pg_attribute_aligned_if_possible or
something.

Sounds sane?

Yes, that sounds like a much better plan.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

In reply to: Robert Haas (#7)
1 attachment(s)
Re: __attribute__ for non-gcc compilers

15.01.2015, 21:58, Robert Haas kirjoitti:

On Wed, Jan 14, 2015 at 5:54 PM, Andres Freund <andres@2ndquadrant.com> wrote:

I think I'd for now simply not define pg_attribute_aligned() on
platforms where it's not supported, instead of defining it empty. If we
need a softer variant we can name it pg_attribute_aligned_if_possible or
something.

Sounds sane?

Yes, that sounds like a much better plan.

Attached an updated patch rebased on today's git master that never
defines aligned or packed empty.

This is also included in the current commitfest,
https://commitfest.postgresql.org/4/115/

/ Oskari

Attachments:

0001-Fix-aligned-attribute-for-Sun-CC-and-use-custom-macr.patchtext/x-patch; name=0001-Fix-aligned-attribute-for-Sun-CC-and-use-custom-macr.patchDownload
From 966fade79a57d2a63cdfb74d326a33d758038d2c Mon Sep 17 00:00:00 2001
From: Oskari Saarenmaa <os@ohmu.fi>
Date: Tue, 13 Jan 2015 21:46:55 +0200
Subject: [PATCH] Fix aligned attribute for Sun CC and use custom macros for
 all attributes

Previously __attribute__ was defined as an empty macro when __GNUC__ wasn't
defined as the source tree used various GCC specific attributes.  Other
compilers implement a subset of the attributes supported by GCC and we
should use them when possible, especially in the cases where they make a
functional difference like in the case of 'aligned' and 'packed'.

Replace all direct __attribute__ uses with new pg_attribute_X macros which
are defined as __attribute__(()) calls when supported by GCC, Solaris Studio
and XL C and empty in other cases.
---
 contrib/cube/cubescan.l                     |  2 +-
 contrib/pg_upgrade/pg_upgrade.h             | 14 +++++-----
 contrib/pg_upgrade/util.c                   |  2 +-
 contrib/pg_xlogdump/pg_xlogdump.c           |  2 +-
 contrib/pgcrypto/px.h                       |  2 +-
 contrib/seg/segscan.l                       |  2 +-
 src/backend/access/transam/xlogreader.c     |  2 +-
 src/backend/postmaster/autovacuum.c         |  4 +--
 src/backend/postmaster/pgarch.c             |  2 +-
 src/backend/postmaster/pgstat.c             |  2 +-
 src/backend/postmaster/postmaster.c         |  4 +--
 src/backend/postmaster/syslogger.c          |  2 +-
 src/backend/replication/repl_scanner.l      |  2 +-
 src/backend/replication/walsender.c         |  2 +-
 src/backend/utils/error/elog.c              |  2 +-
 src/backend/utils/misc/guc.c                |  2 +-
 src/bin/pg_ctl/pg_ctl.c                     |  2 +-
 src/bin/pg_dump/parallel.c                  |  2 +-
 src/bin/pg_dump/pg_backup.h                 |  2 +-
 src/bin/pg_dump/pg_backup_archiver.h        |  6 ++--
 src/bin/pg_dump/pg_backup_tar.c             |  2 +-
 src/bin/pg_dump/pg_backup_utils.h           |  8 +++---
 src/bin/psql/common.h                       |  2 +-
 src/bin/psql/large_obj.c                    |  2 +-
 src/include/bootstrap/bootstrap.h           |  4 +--
 src/include/c.h                             | 43 ++++++++++++++++++++++++++---
 src/include/common/fe_memutils.h            |  4 +--
 src/include/lib/stringinfo.h                |  4 +--
 src/include/mb/pg_wchar.h                   |  4 +--
 src/include/parser/parse_relation.h         |  4 +--
 src/include/parser/scanner.h                |  2 +-
 src/include/pgstat.h                        |  2 +-
 src/include/port.h                          |  8 +++---
 src/include/port/atomics/generic-gcc.h      |  2 +-
 src/include/port/atomics/generic-sunpro.h   |  2 +-
 src/include/port/atomics/generic-xlc.h      |  2 +-
 src/include/postgres.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/walwriter.h          |  2 +-
 src/include/replication/walreceiver.h       |  2 +-
 src/include/storage/ipc.h                   |  2 +-
 src/include/storage/itemptr.h               |  2 +-
 src/include/storage/lock.h                  |  2 +-
 src/include/tcop/tcopprot.h                 |  6 ++--
 src/include/utils/datetime.h                |  2 +-
 src/include/utils/elog.h                    | 38 ++++++++++++-------------
 src/include/utils/help_config.h             |  2 +-
 src/include/utils/palloc.h                  |  4 +--
 src/interfaces/ecpg/ecpglib/extern.h        |  2 +-
 src/interfaces/ecpg/include/ecpglib.h       |  2 +-
 src/interfaces/ecpg/preproc/ecpg.header     |  2 +-
 src/interfaces/ecpg/preproc/extern.h        |  4 +--
 src/interfaces/libpq/libpq-int.h            |  6 ++--
 src/interfaces/libpq/pqexpbuffer.c          |  2 +-
 src/interfaces/libpq/pqexpbuffer.h          |  4 +--
 src/interfaces/libpq/win32.c                |  2 +-
 src/pl/plperl/plperl.h                      |  4 +--
 src/pl/plpgsql/src/pl_scanner.c             |  2 +-
 src/pl/plpython/plpy_elog.h                 |  8 +++---
 src/test/modules/test_shm_mq/test_shm_mq.h  |  2 +-
 src/test/modules/worker_spi/worker_spi.c    |  2 +-
 src/test/regress/pg_regress.c               |  6 ++--
 68 files changed, 160 insertions(+), 127 deletions(-)

diff --git a/contrib/cube/cubescan.l b/contrib/cube/cubescan.l
index e383b59..1c2522a 100644
--- a/contrib/cube/cubescan.l
+++ b/contrib/cube/cubescan.l
@@ -60,7 +60,7 @@ float        ({integer}|{real})([eE]{integer})?
 
 %%
 
-void __attribute__((noreturn))
+void pg_attribute_noreturn
 yyerror(NDBOX **result, const char *message)
 {
 	if (*yytext == YY_END_OF_BUFFER_CHAR)
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
index 19d59f5..9b873ad 100644
--- a/contrib/pg_upgrade/pg_upgrade.h
+++ b/contrib/pg_upgrade/pg_upgrade.h
@@ -359,7 +359,7 @@ void		optionally_create_toast_tables(void);
 bool
 exec_prog(const char *log_file, const char *opt_log_file,
 		  bool throw_error, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5)));
+pg_attribute_printf(4, 5);
 void		verify_directories(void);
 bool		pid_lock_file_exists(const char *datadir);
 
@@ -445,7 +445,7 @@ void		init_tablespaces(void);
 PGconn	   *connectToServer(ClusterInfo *cluster, const char *db_name);
 PGresult *
 executeQueryOrDie(PGconn *conn, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 char	   *cluster_conn_opts(ClusterInfo *cluster);
 
@@ -462,17 +462,17 @@ int			get_user_info(char **user_name_p);
 void		check_ok(void);
 void
 report_status(eLogType type, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 void
 pg_log(eLogType type, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 void
 pg_fatal(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2), noreturn));
+pg_attribute_printf(1, 2) pg_attribute_noreturn;
 void		end_progress_output(void);
 void
 prep_status(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 void		check_ok(void);
 const char *getErrorText(int errNum);
 unsigned int str2uint(const char *str);
@@ -489,7 +489,7 @@ void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster);
 void
 parallel_exec_prog(const char *log_file, const char *opt_log_file,
 				   const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+pg_attribute_printf(3, 4);
 void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr,
 							  char *old_pgdata, char *new_pgdata,
 							  char *old_tablespace);
diff --git a/contrib/pg_upgrade/util.c b/contrib/pg_upgrade/util.c
index ec18526..ce17aa0 100644
--- a/contrib/pg_upgrade/util.c
+++ b/contrib/pg_upgrade/util.c
@@ -82,7 +82,7 @@ prep_status(const char *fmt,...)
 
 
 static
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)))
+pg_attribute_printf(2, 0)
 void
 pg_log_v(eLogType type, const char *fmt, va_list ap)
 {
diff --git a/contrib/pg_xlogdump/pg_xlogdump.c b/contrib/pg_xlogdump/pg_xlogdump.c
index c1bfbc2..6720f2e 100644
--- a/contrib/pg_xlogdump/pg_xlogdump.c
+++ b/contrib/pg_xlogdump/pg_xlogdump.c
@@ -69,7 +69,7 @@ typedef struct XLogDumpStats
 
 static void
 fatal_error(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 /*
  * Big red button to push when things go horribly wrong.
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index a01a58e..297747c 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -208,7 +208,7 @@ void		px_memset(void *ptr, int c, size_t len);
 #ifdef PX_DEBUG
 void
 px_debug(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 #else
 #define px_debug(...)
 #endif
diff --git a/contrib/seg/segscan.l b/contrib/seg/segscan.l
index a3e6854..5fe4a2c 100644
--- a/contrib/seg/segscan.l
+++ b/contrib/seg/segscan.l
@@ -59,7 +59,7 @@ float        ({integer}|{real})([eE]{integer})?
 
 %%
 
-void __attribute__((noreturn))
+void pg_attribute_noreturn
 yyerror(SEG *result, const char *message)
 {
 	if (*yytext == YY_END_OF_BUFFER_CHAR)
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 60470b5..0166f56 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -35,7 +35,7 @@ static void
 report_invalid_record(XLogReaderState *state, const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 static void ResetDecoder(XLogReaderState *state);
 
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 77158c1..ee556f3 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -286,8 +286,8 @@ int			AutovacuumLauncherPid = 0;
 static pid_t avlauncher_forkexec(void);
 static pid_t avworker_forkexec(void);
 #endif
-NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]) __attribute__((noreturn));
-NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]) __attribute__((noreturn));
+NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn;
+NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn;
 
 static Oid	do_start_worker(void);
 static void launcher_determine_sleep(bool canlaunch, bool recursing,
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 9b689af..800ae93 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -86,7 +86,7 @@ static volatile sig_atomic_t ready_to_stop = false;
 static pid_t pgarch_forkexec(void);
 #endif
 
-NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) __attribute__((noreturn));
+NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) pg_attribute_noreturn;
 static void pgarch_exit(SIGNAL_ARGS);
 static void ArchSigHupHandler(SIGNAL_ARGS);
 static void ArchSigTermHandler(SIGNAL_ARGS);
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 268bcd5..ca0ca1ff 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -247,7 +247,7 @@ static instr_time total_func_time;
 static pid_t pgstat_forkexec(void);
 #endif
 
-NON_EXEC_STATIC void PgstatCollectorMain(int argc, char *argv[]) __attribute__((noreturn));
+NON_EXEC_STATIC void PgstatCollectorMain(int argc, char *argv[]) pg_attribute_noreturn;
 static void pgstat_exit(SIGNAL_ARGS);
 static void pgstat_beshutdown_hook(int code, Datum arg);
 static void pgstat_sighup_handler(SIGNAL_ARGS);
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index ac431e5..9b2e7f3 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -380,8 +380,8 @@ static void LogChildExit(int lev, const char *procname,
 			 int pid, int exitstatus);
 static void PostmasterStateMachine(void);
 static void BackendInitialize(Port *port);
-static void BackendRun(Port *port) __attribute__((noreturn));
-static void ExitPostmaster(int status) __attribute__((noreturn));
+static void BackendRun(Port *port) pg_attribute_noreturn;
+static void ExitPostmaster(int status) pg_attribute_noreturn;
 static int	ServerLoop(void);
 static int	BackendStartup(Port *port);
 static int	ProcessStartupPacket(Port *port, bool SSLdone);
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index 41b8dbb..9144eb6 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -130,7 +130,7 @@ static volatile sig_atomic_t rotation_requested = false;
 static pid_t syslogger_forkexec(void);
 static void syslogger_parseArgs(int argc, char *argv[]);
 #endif
-NON_EXEC_STATIC void SysLoggerMain(int argc, char *argv[]) __attribute__((noreturn));
+NON_EXEC_STATIC void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn;
 static void process_pipe_input(char *logbuffer, int *bytes_in_logbuffer);
 static void flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer);
 static void open_csvlogfile(void);
diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l
index 449c127..9abe475 100644
--- a/src/backend/replication/repl_scanner.l
+++ b/src/backend/replication/repl_scanner.l
@@ -205,7 +205,7 @@ addlitchar(unsigned char ychar)
 	appendStringInfoChar(&litbuf, ychar);
 }
 
-void __attribute__((noreturn))
+void pg_attribute_noreturn
 yyerror(const char *message)
 {
 	ereport(ERROR,
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index af5c1cc..2956119 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -193,7 +193,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) __attribute__((noreturn));
+static void WalSndShutdown(void) pg_attribute_noreturn;
 static void XLogSendPhysical(void);
 static void XLogSendLogical(void);
 static void WalSndDone(WalSndSendDataCallback send_data);
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 4e0cc30..b952c7c 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -86,7 +86,7 @@ static const char *
 err_gettext(const char *str)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format_arg(1)));
+pg_attribute_format_arg(1);
 static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str);
 
 /* Global variables */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9572777..f37600b 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -146,7 +146,7 @@ char	   *GUC_check_errhint_string;
 static void
 do_serialize(char **destptr, Size *maxbytes, const char *fmt,...)
 /* This lets gcc check the format string for consistency. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+pg_attribute_printf(3, 4);
 
 static void set_config_sourcefile(const char *name, char *sourcefile,
 					  int sourceline);
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 789fe8f..052caff 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -120,7 +120,7 @@ static void
 write_stderr(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 static void do_advice(void);
 static void do_help(void);
 static void set_mode(char *modeopt);
diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c
index 1bf7611..f58f96b 100644
--- a/src/bin/pg_dump/parallel.c
+++ b/src/bin/pg_dump/parallel.c
@@ -81,7 +81,7 @@ static ParallelSlot *GetMyPSlot(ParallelState *pstate);
 static void
 parallel_msg_master(ParallelSlot *slot, const char *modulename,
 					const char *fmt, va_list ap)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
+pg_attribute_printf(3, 0);
 static void archive_close_connection(int code, void *arg);
 static void ShutdownWorkersHard(ParallelState *pstate);
 static void WaitForTerminatingWorkers(ParallelState *pstate);
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index a936ff8..d484236 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -280,7 +280,7 @@ extern void archputs(const char *s, Archive *AH);
 extern int
 archprintf(Archive *AH, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 #define appendStringLiteralAH(buf,str,AH) \
 	appendStringLiteral(buf, str, (AH)->encoding, (AH)->std_strings)
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 144027c..620ada5 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -378,7 +378,7 @@ struct _tocEntry
 extern int	parallel_restore(struct ParallelArgs *args);
 extern void on_exit_close_archive(Archive *AHX);
 
-extern void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+extern void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) pg_attribute_printf(3, 4);
 
 extern void WriteTOC(ArchiveHandle *AH);
 extern void ReadTOC(ArchiveHandle *AH);
@@ -429,8 +429,8 @@ extern int	ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *
 extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid);
 
 void		ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH);
-int			ahprintf(ArchiveHandle *AH, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+int			ahprintf(ArchiveHandle *AH, const char *fmt,...) pg_attribute_printf(2, 3);
 
-void		ahlog(ArchiveHandle *AH, int level, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+void		ahlog(ArchiveHandle *AH, int level, const char *fmt,...) pg_attribute_printf(3, 4);
 
 #endif
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index f48d369..309b4b5 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -115,7 +115,7 @@ static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH);
 #ifdef __NOT_USED__
 static char *tarGets(char *buf, size_t len, TAR_MEMBER *th);
 #endif
-static int	tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+static int	tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) pg_attribute_printf(3, 4);
 
 static void _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th);
 static TAR_MEMBER *_tarPositionTo(ArchiveHandle *AH, const char *filename);
diff --git a/src/bin/pg_dump/pg_backup_utils.h b/src/bin/pg_dump/pg_backup_utils.h
index 1bcc1a7..2e9a69a 100644
--- a/src/bin/pg_dump/pg_backup_utils.h
+++ b/src/bin/pg_dump/pg_backup_utils.h
@@ -30,15 +30,15 @@ extern const char *progname;
 extern void set_dump_section(const char *arg, int *dumpSections);
 extern void
 write_msg(const char *modulename, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 extern void
 vwrite_msg(const char *modulename, const char *fmt, va_list ap)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+pg_attribute_printf(2, 0);
 extern void on_exit_nicely(on_exit_nicely_callback function, void *arg);
-extern void exit_nicely(int code) __attribute__((noreturn));
+extern void exit_nicely(int code) pg_attribute_noreturn;
 
 extern void
 exit_horribly(const char *modulename, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
+pg_attribute_printf(2, 3) pg_attribute_noreturn;
 
 #endif   /* PG_BACKUP_UTILS_H */
diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h
index eb14d1c..54266c1 100644
--- a/src/bin/psql/common.h
+++ b/src/bin/psql/common.h
@@ -21,7 +21,7 @@ extern bool setQFout(const char *fname);
 extern void
 psql_error(const char *fmt,...)
 /* This lets gcc check the format string for consistency. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern void NoticeProcessor(void *arg, const char *message);
 
diff --git a/src/bin/psql/large_obj.c b/src/bin/psql/large_obj.c
index 709869e..48d2d77 100644
--- a/src/bin/psql/large_obj.c
+++ b/src/bin/psql/large_obj.c
@@ -14,7 +14,7 @@
 
 static void
 print_lo_result(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 static void
 print_lo_result(const char *fmt,...)
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index be4430a..0966b73 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -28,7 +28,7 @@ extern Form_pg_attribute attrtypes[MAXATTR];
 extern int	numattr;
 
 
-extern void AuxiliaryProcessMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void AuxiliaryProcessMain(int argc, char *argv[]) pg_attribute_noreturn;
 
 extern void err_out(void);
 
@@ -57,6 +57,6 @@ extern void boot_get_type_io_data(Oid typid,
 extern int	boot_yyparse(void);
 
 extern int	boot_yylex(void);
-extern void boot_yyerror(const char *str) __attribute__((noreturn));
+extern void boot_yyerror(const char *str) pg_attribute_noreturn;
 
 #endif   /* BOOTSTRAP_H */
diff --git a/src/include/c.h b/src/include/c.h
index b187520..3c257e8 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -156,8 +156,43 @@
 #define dummyret	char
 #endif
 
-#ifndef __GNUC__
-#define __attribute__(_arg_)
+/*
+ * Attribute macros
+ * GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
+ * GCC: https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
+ * Sunpro: https://docs.oracle.com/cd/E18659_01/html/821-1384/gjzke.html
+ * XLC: http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/function_attributes.html
+ * XLC: http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/type_attrib.html
+ */
+
+/* GCC supports unused attribute */
+#ifdef __GNUC__
+#define pg_attribute_unused __attribute__((unused))
+#else
+#define pg_attribute_unused
+#endif
+
+/* GCC and XLC support format attributes */
+#if defined(__GNUC__) || defined(__IBMC__)
+#define pg_attribute_format_arg(a) __attribute__((format_arg(a)))
+#define pg_attribute_printf(f,a) __attribute__((format(PG_PRINTF_ATTRIBUTE, f, a)))
+#else
+#define pg_attribute_format_arg(a)
+#define pg_attribute_printf(f,a)
+#endif
+
+/* GCC, Sunpro and XLC support aligned, packed and noreturn */
+#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__)
+#define pg_attribute_aligned(a) __attribute__((aligned(a)))
+#define pg_attribute_noreturn __attribute__((noreturn))
+#define pg_attribute_packed __attribute__((packed))
+#else
+/*
+ * Note: aligned and packed are not defined as empty as they affect code
+ * functionality; they must be implemented by the compiler if they are to
+ * be used.
+ */
+#define pg_attribute_noreturn
 #endif
 
 /* ----------------------------------------------------------------
@@ -906,7 +941,7 @@ typedef NameData *Name;
 #ifdef USE_ASSERT_CHECKING
 #define PG_USED_FOR_ASSERTS_ONLY
 #else
-#define PG_USED_FOR_ASSERTS_ONLY __attribute__((unused))
+#define PG_USED_FOR_ASSERTS_ONLY pg_attribute_unused
 #endif
 
 
@@ -973,7 +1008,7 @@ typedef NameData *Name;
 extern int
 snprintf(char *str, size_t count, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+pg_attribute_printf(3, 4);
 #endif
 
 #if !HAVE_DECL_VSNPRINTF
diff --git a/src/include/common/fe_memutils.h b/src/include/common/fe_memutils.h
index f7114c2..33123cb 100644
--- a/src/include/common/fe_memutils.h
+++ b/src/include/common/fe_memutils.h
@@ -26,9 +26,9 @@ extern void pfree(void *pointer);
 /* sprintf into a palloc'd buffer --- these are in psprintf.c */
 extern char *
 psprintf(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 extern size_t
 pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
+pg_attribute_printf(3, 0);
 
 #endif   /* FE_MEMUTILS_H */
diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h
index 63d39e5..fdb8285 100644
--- a/src/include/lib/stringinfo.h
+++ b/src/include/lib/stringinfo.h
@@ -95,7 +95,7 @@ extern void resetStringInfo(StringInfo str);
 extern void
 appendStringInfo(StringInfo str, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 /*------------------------
  * appendStringInfoVA
@@ -108,7 +108,7 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
  */
 extern int
 appendStringInfoVA(StringInfo str, const char *fmt, va_list args)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+pg_attribute_printf(2, 0);
 
 /*------------------------
  * appendStringInfoString
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 231003f..0a2234d 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -514,9 +514,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) __attribute__((noreturn));
+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) __attribute__((noreturn));
+					   const char *mbstr, int len) pg_attribute_noreturn;
 
 extern void pg_ascii2mic(const unsigned char *l, unsigned char *p, int len);
 extern void pg_mic2ascii(const unsigned char *mic, unsigned char *p, int len);
diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h
index c886335..fc0a257 100644
--- a/src/include/parser/parse_relation.h
+++ b/src/include/parser/parse_relation.h
@@ -85,9 +85,9 @@ extern bool isLockedRefname(ParseState *pstate, const char *refname);
 extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
 			  bool addToJoinList,
 			  bool addToRelNameSpace, bool addToVarNameSpace);
-extern void errorMissingRTE(ParseState *pstate, RangeVar *relation) __attribute__((noreturn));
+extern void errorMissingRTE(ParseState *pstate, RangeVar *relation) pg_attribute_noreturn;
 extern void errorMissingColumn(ParseState *pstate,
-	   char *relname, char *colname, int location) __attribute__((noreturn));
+	   char *relname, char *colname, int location) pg_attribute_noreturn;
 extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
 		  int location, bool include_dropped,
 		  List **colnames, List **colvars);
diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h
index e6724bc..7edb4a4 100644
--- a/src/include/parser/scanner.h
+++ b/src/include/parser/scanner.h
@@ -124,6 +124,6 @@ extern void scanner_finish(core_yyscan_t yyscanner);
 extern int core_yylex(core_YYSTYPE *lvalp, YYLTYPE *llocp,
 		   core_yyscan_t yyscanner);
 extern int	scanner_errposition(int location, core_yyscan_t yyscanner);
-extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner) __attribute__((noreturn));
+extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner) pg_attribute_noreturn;
 
 #endif   /* SCANNER_H */
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 416769a..ac1512d 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -870,7 +870,7 @@ extern void pgstat_reset_all(void);
 extern void allow_immediate_pgstat_restart(void);
 
 #ifdef EXEC_BACKEND
-extern void PgstatCollectorMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void PgstatCollectorMain(int argc, char *argv[]) pg_attribute_noreturn;
 #endif
 
 
diff --git a/src/include/port.h b/src/include/port.h
index 26d7fcd..8b67c35 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -156,20 +156,20 @@ extern int	pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
 extern int
 pg_snprintf(char *str, size_t count, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
+pg_attribute_printf(3, 4);
 extern int
 pg_sprintf(char *str, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 extern int	pg_vfprintf(FILE *stream, const char *fmt, va_list args);
 extern int
 pg_fprintf(FILE *stream, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 extern int
 pg_printf(const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 /*
  *	The GCC-specific code below prevents the __attribute__(... 'printf')
diff --git a/src/include/port/atomics/generic-gcc.h b/src/include/port/atomics/generic-gcc.h
index fea1cb5..c9fc87b 100644
--- a/src/include/port/atomics/generic-gcc.h
+++ b/src/include/port/atomics/generic-gcc.h
@@ -98,7 +98,7 @@ typedef struct pg_atomic_uint32
 
 typedef struct pg_atomic_uint64
 {
-	volatile uint64 value __attribute__((aligned(8)));
+	volatile uint64 value pg_attribute_aligned(8);
 } pg_atomic_uint64;
 
 #endif /* defined(HAVE_GCC__ATOMIC_INT64_CAS) || defined(HAVE_GCC__SYNC_INT64_CAS) */
diff --git a/src/include/port/atomics/generic-sunpro.h b/src/include/port/atomics/generic-sunpro.h
index 7a3028e..d369207 100644
--- a/src/include/port/atomics/generic-sunpro.h
+++ b/src/include/port/atomics/generic-sunpro.h
@@ -61,7 +61,7 @@ typedef struct pg_atomic_uint64
 	 * it proves to be a problem, we'll have to add more version checks for 64
 	 * bit support.
 	 */
-	volatile uint64 value __attribute__((__aligned__(8)));
+	volatile uint64 value pg_attribute_aligned(8);
 } pg_atomic_uint64;
 
 #endif /* HAVE_ATOMIC_H */
diff --git a/src/include/port/atomics/generic-xlc.h b/src/include/port/atomics/generic-xlc.h
index 7a4c12a..1c743f2 100644
--- a/src/include/port/atomics/generic-xlc.h
+++ b/src/include/port/atomics/generic-xlc.h
@@ -32,7 +32,7 @@ typedef struct pg_atomic_uint32
 #define PG_HAVE_ATOMIC_U64_SUPPORT
 typedef struct pg_atomic_uint64
 {
-	volatile uint64 value __attribute__((__aligned__(8)));
+	volatile uint64 value pg_attribute_aligned(8);
 } pg_atomic_uint64;
 
 #endif /* __64BIT__ */
diff --git a/src/include/postgres.h b/src/include/postgres.h
index 082c75b..46b5b06 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -687,6 +687,6 @@ extern Datum Float8GetDatum(float8 X);
  */
 extern void ExceptionalCondition(const char *conditionName,
 					 const char *errorType,
-			 const char *fileName, int lineNumber) __attribute__((noreturn));
+			 const char *fileName, int lineNumber) pg_attribute_noreturn;
 
 #endif   /* POSTGRES_H */
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index 121f107..0bd5044 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -54,8 +54,8 @@ extern void AutoVacWorkerFailed(void);
 extern void AutoVacuumUpdateDelay(void);
 
 #ifdef EXEC_BACKEND
-extern void AutoVacLauncherMain(int argc, char *argv[]) __attribute__((noreturn));
-extern void AutoVacWorkerMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn;
+extern void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn;
 extern void AutovacuumWorkerIAm(void);
 extern void AutovacuumLauncherIAm(void);
 #endif
diff --git a/src/include/postmaster/bgworker_internals.h b/src/include/postmaster/bgworker_internals.h
index 81c03e4..fe7c328 100644
--- a/src/include/postmaster/bgworker_internals.h
+++ b/src/include/postmaster/bgworker_internals.h
@@ -46,7 +46,7 @@ extern void BackgroundWorkerStopNotifications(pid_t pid);
 extern void ResetBackgroundWorkerCrashTimes(void);
 
 /* Function to start a background worker, called from postmaster.c */
-extern void StartBackgroundWorker(void) __attribute__((noreturn));
+extern void StartBackgroundWorker(void) pg_attribute_noreturn;
 
 #ifdef EXEC_BACKEND
 extern BackgroundWorker *BackgroundWorkerEntry(int slotno);
diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h
index ce12619..f584d85 100644
--- a/src/include/postmaster/bgwriter.h
+++ b/src/include/postmaster/bgwriter.h
@@ -25,8 +25,8 @@ extern int	CheckPointTimeout;
 extern int	CheckPointWarning;
 extern double CheckPointCompletionTarget;
 
-extern void BackgroundWriterMain(void) __attribute__((noreturn));
-extern void CheckpointerMain(void) __attribute__((noreturn));
+extern void BackgroundWriterMain(void) pg_attribute_noreturn;
+extern void CheckpointerMain(void) pg_attribute_noreturn;
 
 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 a585e67..60e4f50 100644
--- a/src/include/postmaster/pgarch.h
+++ b/src/include/postmaster/pgarch.h
@@ -33,7 +33,7 @@
 extern int	pgarch_start(void);
 
 #ifdef EXEC_BACKEND
-extern void PgArchiverMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void PgArchiverMain(int argc, char *argv[]) pg_attribute_noreturn;
 #endif
 
 #endif   /* _PGARCH_H */
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
index 91723f7..d41761f 100644
--- a/src/include/postmaster/postmaster.h
+++ b/src/include/postmaster/postmaster.h
@@ -46,7 +46,7 @@ extern int	postmaster_alive_fds[2];
 
 extern const char *progname;
 
-extern void PostmasterMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void PostmasterMain(int argc, char *argv[]) pg_attribute_noreturn;
 extern void ClosePostmasterPorts(bool am_syslogger);
 
 extern int	MaxLivePostmasterChildren(void);
@@ -56,7 +56,7 @@ extern bool PostmasterMarkPIDForWorkerNotify(int);
 
 #ifdef EXEC_BACKEND
 extern pid_t postmaster_forkexec(int argc, char *argv[]);
-extern void SubPostmasterMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void SubPostmasterMain(int argc, char *argv[]) pg_attribute_noreturn;
 
 extern Size ShmemBackendArraySize(void);
 extern void ShmemBackendArrayAllocation(void);
diff --git a/src/include/postmaster/startup.h b/src/include/postmaster/startup.h
index da1f6e9..9a2092e 100644
--- a/src/include/postmaster/startup.h
+++ b/src/include/postmaster/startup.h
@@ -13,7 +13,7 @@
 #define _STARTUP_H
 
 extern void HandleStartupProcInterrupts(void);
-extern void StartupProcessMain(void) __attribute__((noreturn));
+extern void StartupProcessMain(void) pg_attribute_noreturn;
 extern void PreRestoreCommand(void);
 extern void PostRestoreCommand(void);
 extern bool IsPromoteTriggered(void);
diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h
index 602b13c..c6a48dc 100644
--- a/src/include/postmaster/syslogger.h
+++ b/src/include/postmaster/syslogger.h
@@ -84,7 +84,7 @@ extern int	SysLogger_Start(void);
 extern void write_syslogger_file(const char *buffer, int count, int dest);
 
 #ifdef EXEC_BACKEND
-extern void SysLoggerMain(int argc, char *argv[]) __attribute__((noreturn));
+extern void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn;
 #endif
 
 #endif   /* _SYSLOGGER_H */
diff --git a/src/include/postmaster/walwriter.h b/src/include/postmaster/walwriter.h
index de45a01..55de6c7 100644
--- a/src/include/postmaster/walwriter.h
+++ b/src/include/postmaster/walwriter.h
@@ -15,6 +15,6 @@
 /* GUC options */
 extern int	WalWriterDelay;
 
-extern void WalWriterMain(void) __attribute__((noreturn));
+extern void WalWriterMain(void) pg_attribute_noreturn;
 
 #endif   /* _WALWRITER_H */
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index defe8f9..4afdf91 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -147,7 +147,7 @@ typedef void (*walrcv_disconnect_type) (void);
 extern PGDLLIMPORT walrcv_disconnect_type walrcv_disconnect;
 
 /* prototypes for functions in walreceiver.c */
-extern void WalReceiverMain(void) __attribute__((noreturn));
+extern void WalReceiverMain(void) pg_attribute_noreturn;
 
 /* prototypes for functions in walreceiverfuncs.c */
 extern Size WalRcvShmemSize(void);
diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h
index 54fa2ba..7da434e 100644
--- a/src/include/storage/ipc.h
+++ b/src/include/storage/ipc.h
@@ -64,7 +64,7 @@ typedef void (*shmem_startup_hook_type) (void);
 /* ipc.c */
 extern PGDLLIMPORT bool proc_exit_inprogress;
 
-extern void proc_exit(int code) __attribute__((noreturn));
+extern void proc_exit(int code) pg_attribute_noreturn;
 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/itemptr.h b/src/include/storage/itemptr.h
index 944812c..1f0ea7d 100644
--- a/src/include/storage/itemptr.h
+++ b/src/include/storage/itemptr.h
@@ -41,7 +41,7 @@ typedef struct ItemPointerData
 }
 
 #ifdef __arm__
-__attribute__((packed))			/* Appropriate whack upside the head for ARM */
+pg_attribute_packed			/* Appropriate whack upside the head for ARM */
 #endif
 ItemPointerData;
 
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 1100923..1477a6f 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -547,7 +547,7 @@ extern void lock_twophase_standby_recover(TransactionId xid, uint16 info,
 
 extern DeadLockState DeadLockCheck(PGPROC *proc);
 extern PGPROC *GetBlockingAutoVacuumPgproc(void);
-extern void DeadLockReport(void) __attribute__((noreturn));
+extern void DeadLockReport(void) pg_attribute_noreturn;
 extern void RememberSimpleDeadLock(PGPROC *proc1,
 					   LOCKMODE lockmode,
 					   LOCK *lock,
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 3e17770..b3c705f 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -62,9 +62,9 @@ extern bool check_max_stack_depth(int *newval, void **extra, GucSource source);
 extern void assign_max_stack_depth(int newval, void *extra);
 
 extern void die(SIGNAL_ARGS);
-extern void quickdie(SIGNAL_ARGS) __attribute__((noreturn));
+extern void quickdie(SIGNAL_ARGS) pg_attribute_noreturn;
 extern void StatementCancelHandler(SIGNAL_ARGS);
-extern void FloatExceptionHandler(SIGNAL_ARGS) __attribute__((noreturn));
+extern void FloatExceptionHandler(SIGNAL_ARGS) pg_attribute_noreturn;
 extern void RecoveryConflictInterrupt(ProcSignalReason reason); /* called from SIGUSR1
 																 * handler */
 extern void ProcessClientReadInterrupt(bool blocked);
@@ -74,7 +74,7 @@ extern void process_postgres_switches(int argc, char *argv[],
 						  GucContext ctx, const char **dbname);
 extern void PostgresMain(int argc, char *argv[],
 			 const char *dbname,
-			 const char *username) __attribute__((noreturn));
+			 const char *username) pg_attribute_noreturn;
 extern long get_stack_depth_rlimit(void);
 extern void ResetUsage(void);
 extern void ShowUsage(const char *title);
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 8912ba5..a403374 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -315,7 +315,7 @@ extern int DecodeISO8601Interval(char *str,
 					  int *dtype, struct pg_tm * tm, fsec_t *fsec);
 
 extern void DateTimeParseError(int dterr, const char *str,
-				   const char *datatype) __attribute__((noreturn));
+				   const char *datatype) pg_attribute_noreturn;
 
 extern int	DetermineTimeZoneOffset(struct pg_tm * tm, pg_tz *tzp);
 extern int	DetermineTimeZoneAbbrevOffset(struct pg_tm * tm, const char *abbr, pg_tz *tzp);
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index b5cfc9c..a82063a 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -147,61 +147,61 @@ extern int
 errmsg(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errmsg_internal(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errmsg_plural(const char *fmt_singular, const char *fmt_plural,
 			  unsigned long n,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4)))
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4)));
+pg_attribute_printf(1, 4)
+pg_attribute_printf(2, 4);
 
 extern int
 errdetail(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errdetail_internal(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errdetail_log(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int
 errdetail_log_plural(const char *fmt_singular, const char *fmt_plural,
 					 unsigned long n,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4)))
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4)));
+pg_attribute_printf(1, 4)
+pg_attribute_printf(2, 4);
 
 extern int
 errdetail_plural(const char *fmt_singular, const char *fmt_plural,
 				 unsigned long n,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4)))
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4)));
+pg_attribute_printf(1, 4)
+pg_attribute_printf(2, 4);
 
 extern int
 errhint(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 /*
  * errcontext() is typically called in error context callback functions, not
@@ -218,7 +218,7 @@ extern int
 errcontext_msg(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 extern int	errhidestmt(bool hide_stmt);
 extern int	errhidecontext(bool hide_ctx);
@@ -278,7 +278,7 @@ extern void
 elog_finish(int elevel, const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 
 /* Support for constructing error strings separately from ereport() calls */
@@ -288,7 +288,7 @@ extern char *
 format_elog_string(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 
 /* Support for attaching context information to error reports */
@@ -364,7 +364,7 @@ extern PGDLLIMPORT ErrorContextCallback *error_context_stack;
 	} while (0)
 
 /*
- * gcc understands __attribute__((noreturn)); for other compilers, insert
+ * gcc understands pg_attribute_noreturn; for other compilers, insert
  * pg_unreachable() so that the compiler gets the point.
  */
 #ifdef __GNUC__
@@ -423,9 +423,9 @@ extern void EmitErrorReport(void);
 extern ErrorData *CopyErrorData(void);
 extern void FreeErrorData(ErrorData *edata);
 extern void FlushErrorState(void);
-extern void ReThrowError(ErrorData *edata) __attribute__((noreturn));
+extern void ReThrowError(ErrorData *edata) pg_attribute_noreturn;
 extern void ThrowErrorData(ErrorData *edata);
-extern void pg_re_throw(void) __attribute__((noreturn));
+extern void pg_re_throw(void) pg_attribute_noreturn;
 
 extern char *GetErrorContextStack(void);
 
@@ -472,6 +472,6 @@ extern void
 write_stderr(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 
 #endif   /* ELOG_H */
diff --git a/src/include/utils/help_config.h b/src/include/utils/help_config.h
index 481687f..af52996 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) __attribute__((noreturn));
+extern void GucInfoMain(void) pg_attribute_noreturn;
 
 #endif
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index f586fd5..2ecf935 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -118,9 +118,9 @@ extern char *pnstrdup(const char *in, Size len);
 /* sprintf into a palloc'd buffer --- these are in psprintf.c */
 extern char *
 psprintf(const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 extern size_t
 pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
+pg_attribute_printf(3, 0);
 
 #endif   /* PALLOC_H */
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 2b670e0..7bd3018 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -185,7 +185,7 @@ void		ecpg_raise(int line, int code, const char *sqlstate, const char *str);
 void		ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat);
 char	   *ecpg_prepared(const char *, struct connection *);
 bool		ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection * conn);
-void		ecpg_log(const char *format,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+void		ecpg_log(const char *format,...) pg_attribute_printf(1, 2);
 bool		ecpg_auto_prepare(int, const char *, const int, char **, const char *);
 void		ecpg_init_sqlca(struct sqlca_t * sqlca);
 
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 3b8ed4c..5efe593 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -15,7 +15,7 @@
 #ifdef ENABLE_NLS
 extern char *
 ecpg_gettext(const char *msgid)
-__attribute__((format_arg(1)));
+pg_attribute_format_arg(1);
 #else
 #define ecpg_gettext(x) (x)
 #endif
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index a2be29c..e23407e 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -64,7 +64,7 @@ static struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NUL
 /*
  * Handle parsing errors and warnings
  */
-static void __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)))
+static void pg_attribute_printf(3, 0)
 vmmerror(int error_code, enum errortype type, const char *error, va_list ap)
 {
 	/* localize the error message string */
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index dfc75bc..1ce25eb 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -77,8 +77,8 @@ extern int	base_yylex(void);
 extern void base_yyerror(const char *);
 extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
 extern char *mm_strdup(const char *);
-extern void mmerror(int errorcode, enum errortype type, const char *error,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
-extern void mmfatal(int errorcode, const char *error,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
+extern void mmerror(int errorcode, enum errortype type, const char *error,...) pg_attribute_printf(3, 4);
+extern void mmfatal(int errorcode, const char *error,...) pg_attribute_printf(2, 3) pg_attribute_noreturn;
 extern void output_get_descr_header(char *);
 extern void output_get_descr(char *, char *);
 extern void output_set_descr_header(char *);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 008fd67..68e1ac2 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -548,7 +548,7 @@ extern PGresult *pqPrepareAsyncResult(PGconn *conn);
 extern void
 pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
 /* This lets gcc check the format string for consistency. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 extern void pqSaveMessageField(PGresult *res, char code,
 				   const char *value);
 extern void pqSaveParameterStatus(PGconn *conn, const char *name,
@@ -653,10 +653,10 @@ extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
 #ifdef ENABLE_NLS
 extern char *
 libpq_gettext(const char *msgid)
-__attribute__((format_arg(1)));
+pg_attribute_format_arg(1);
 extern char *
 libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n)
-__attribute__((format_arg(1))) __attribute__((format_arg(2)));
+pg_attribute_format_arg(1) pg_attribute_format_arg(2);
 #else
 #define libpq_gettext(x) (x)
 #define libpq_ngettext(s, p, n) ((n) == 1 ? (s) : (p))
diff --git a/src/interfaces/libpq/pqexpbuffer.c b/src/interfaces/libpq/pqexpbuffer.c
index 15117a3..43df56a 100644
--- a/src/interfaces/libpq/pqexpbuffer.c
+++ b/src/interfaces/libpq/pqexpbuffer.c
@@ -39,7 +39,7 @@ static const char oom_buffer[1] = "";
 
 static bool
 appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+pg_attribute_printf(2, 0);
 
 
 /*
diff --git a/src/interfaces/libpq/pqexpbuffer.h b/src/interfaces/libpq/pqexpbuffer.h
index 3598271..345d203 100644
--- a/src/interfaces/libpq/pqexpbuffer.h
+++ b/src/interfaces/libpq/pqexpbuffer.h
@@ -149,7 +149,7 @@ extern int	enlargePQExpBuffer(PQExpBuffer str, size_t needed);
 extern void
 printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 /*------------------------
  * appendPQExpBuffer
@@ -161,7 +161,7 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
 extern void
 appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
 /* This extension allows gcc to check the format string */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 /*------------------------
  * appendPQExpBufferStr
diff --git a/src/interfaces/libpq/win32.c b/src/interfaces/libpq/win32.c
index 4d2497a..04c5ed4 100644
--- a/src/interfaces/libpq/win32.c
+++ b/src/interfaces/libpq/win32.c
@@ -36,7 +36,7 @@
 #ifdef ENABLE_NLS
 extern char *
 libpq_gettext(const char *msgid)
-__attribute__((format_arg(1)));
+pg_attribute_format_arg(1);
 #else
 #define libpq_gettext(x) (x)
 #endif
diff --git a/src/pl/plperl/plperl.h b/src/pl/plperl/plperl.h
index 89bbd7c..aadb888 100644
--- a/src/pl/plperl/plperl.h
+++ b/src/pl/plperl/plperl.h
@@ -30,9 +30,7 @@
  * Supply a value of PERL_UNUSED_DECL that will satisfy gcc - the one
  * perl itself supplies doesn't seem to.
  */
-#if defined(__GNUC__)
-#define PERL_UNUSED_DECL __attribute__ ((unused))
-#endif
+#define PERL_UNUSED_DECL pg_attribute_unused
 
 /*
  * Sometimes perl carefully scribbles on our *printf macros.
diff --git a/src/pl/plpgsql/src/pl_scanner.c b/src/pl/plpgsql/src/pl_scanner.c
index ec08b02..f932377 100644
--- a/src/pl/plpgsql/src/pl_scanner.c
+++ b/src/pl/plpgsql/src/pl_scanner.c
@@ -608,7 +608,7 @@ plpgsql_scanner_errposition(int location)
  * be misleading!
  */
 void
-__attribute__((noreturn))
+pg_attribute_noreturn
 plpgsql_yyerror(const char *message)
 {
 	char	   *yytext = core_yy.scanbuf + plpgsql_yylloc;
diff --git a/src/pl/plpython/plpy_elog.h b/src/pl/plpython/plpy_elog.h
index 6b8d485..e4e4dfb 100644
--- a/src/pl/plpython/plpy_elog.h
+++ b/src/pl/plpython/plpy_elog.h
@@ -12,16 +12,16 @@ extern PyObject *PLy_exc_spi_error;
 
 extern void
 PLy_elog(int elevel, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 extern void
 PLy_exception_set(PyObject *exc, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 extern void
 PLy_exception_set_plural(PyObject *exc, const char *fmt_singular, const char *fmt_plural,
 						 unsigned long n,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 5)))
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 5)));
+pg_attribute_printf(2, 5)
+pg_attribute_printf(3, 5);
 
 #endif   /* PLPY_ELOG_H */
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 144345b..94d2880 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 void test_shm_mq_main(Datum) __attribute__((noreturn));
+extern void test_shm_mq_main(Datum) pg_attribute_noreturn;
 
 #endif
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index 94d3857..4149c94 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -46,7 +46,7 @@ PG_MODULE_MAGIC;
 PG_FUNCTION_INFO_V1(worker_spi_launch);
 
 void		_PG_init(void);
-void		worker_spi_main(Datum) __attribute__((noreturn));
+void		worker_spi_main(Datum) pg_attribute_noreturn;
 
 /* flags set by signal handlers */
 static volatile sig_atomic_t got_sighup = false;
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 3af0e57..9d4fb9a 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -135,17 +135,17 @@ static void
 header(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 static void
 status(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+pg_attribute_printf(1, 2);
 static void
 psql_command(const char *database, const char *query,...)
 /* This extension allows gcc to check the format string for consistency with
    the supplied arguments. */
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+pg_attribute_printf(2, 3);
 
 #ifdef WIN32
 typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
-- 
2.1.0

#9Andres Freund
andres@2ndquadrant.com
In reply to: Oskari Saarenmaa (#8)
Re: __attribute__ for non-gcc compilers

On 2015-02-17 15:41:45 +0200, Oskari Saarenmaa wrote:

15.01.2015, 21:58, Robert Haas kirjoitti:

On Wed, Jan 14, 2015 at 5:54 PM, Andres Freund <andres@2ndquadrant.com> wrote:

I think I'd for now simply not define pg_attribute_aligned() on
platforms where it's not supported, instead of defining it empty. If we
need a softer variant we can name it pg_attribute_aligned_if_possible or
something.

Sounds sane?

Yes, that sounds like a much better plan.

Attached an updated patch rebased on today's git master that never
defines aligned or packed empty.

Cool, that looks good. Besides allowing other compilers to use the
__attribute__ stuff, it also seems like a readability win to
me. Especially the various printf stuff looks much better to me this
way.

I guess you've tested this on solaris and x86 linux?

Greetings,

Andres Freund

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

In reply to: Andres Freund (#9)
Re: __attribute__ for non-gcc compilers

17.02.2015, 15:46, Andres Freund kirjoitti:

On 2015-02-17 15:41:45 +0200, Oskari Saarenmaa wrote:

15.01.2015, 21:58, Robert Haas kirjoitti:

On Wed, Jan 14, 2015 at 5:54 PM, Andres Freund <andres@2ndquadrant.com> wrote:

I think I'd for now simply not define pg_attribute_aligned() on
platforms where it's not supported, instead of defining it empty. If we
need a softer variant we can name it pg_attribute_aligned_if_possible or
something.

Sounds sane?

Yes, that sounds like a much better plan.

Attached an updated patch rebased on today's git master that never
defines aligned or packed empty.

Cool, that looks good. Besides allowing other compilers to use the
__attribute__ stuff, it also seems like a readability win to
me. Especially the various printf stuff looks much better to me this
way.

I guess you've tested this on solaris and x86 linux?

Yeah, tested on x86-64 Linux using gcc version 4.9.2 20150212 (Red Hat
4.9.2-6) and on Solaris 10 using Sun C 5.12 SunOS_sparc.

/ Oskari

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Robert Haas
robertmhaas@gmail.com
In reply to: Oskari Saarenmaa (#8)
Re: __attribute__ for non-gcc compilers

On Tue, Feb 17, 2015 at 8:41 AM, Oskari Saarenmaa <os@ohmu.fi> wrote:

15.01.2015, 21:58, Robert Haas kirjoitti:

On Wed, Jan 14, 2015 at 5:54 PM, Andres Freund <andres@2ndquadrant.com> wrote:

I think I'd for now simply not define pg_attribute_aligned() on
platforms where it's not supported, instead of defining it empty. If we
need a softer variant we can name it pg_attribute_aligned_if_possible or
something.

Sounds sane?

Yes, that sounds like a much better plan.

Attached an updated patch rebased on today's git master that never
defines aligned or packed empty.

This is also included in the current commitfest,
https://commitfest.postgresql.org/4/115/

Is this going to play nicely with pgindent?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

In reply to: Robert Haas (#11)
Re: __attribute__ for non-gcc compilers

23.02.2015, 04:31, Robert Haas kirjoitti:

On Tue, Feb 17, 2015 at 8:41 AM, Oskari Saarenmaa <os@ohmu.fi> wrote:

15.01.2015, 21:58, Robert Haas kirjoitti:

On Wed, Jan 14, 2015 at 5:54 PM, Andres Freund <andres@2ndquadrant.com> wrote:

I think I'd for now simply not define pg_attribute_aligned() on
platforms where it's not supported, instead of defining it empty. If we
need a softer variant we can name it pg_attribute_aligned_if_possible or
something.

Sounds sane?

Yes, that sounds like a much better plan.

Attached an updated patch rebased on today's git master that never
defines aligned or packed empty.

This is also included in the current commitfest,
https://commitfest.postgresql.org/4/115/

Is this going to play nicely with pgindent?

I ran pgindent on the tree with this patch applied (with a few changes,
pgindent modified atomics headers a bit) and the changes looked ok to
me, mostly pgindent just rewrapped lines like this:

-extern void quickdie(SIGNAL_ARGS) pg_attribute_noreturn;
+extern void
+quickdie(SIGNAL_ARGS) pg_attribute_noreturn;

but there were two cases where it produced a bit weird indentation:

 #ifdef __arm__
-pg_attribute_packed                    /* Appropriate whack upside the
head for ARM */
+                       pg_attribute_packed /* Appropriate whack upside
the head for ARM */
 #endif
 ItemPointerData;

and

 void
-pg_attribute_noreturn
+                       pg_attribute_noreturn
 plpgsql_yyerror(const char *message)
 {

/ Oskari

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Andres Freund
andres@2ndquadrant.com
In reply to: Oskari Saarenmaa (#8)
Re: __attribute__ for non-gcc compilers

Hi,

On 2015-02-17 15:41:45 +0200, Oskari Saarenmaa wrote:

Attached an updated patch rebased on today's git master that never
defines aligned or packed empty.

This is also included in the current commitfest,
https://commitfest.postgresql.org/4/115/

I pushed a slightly modified (mostly moved the new definitions up)
modified version. Sorry for taking so long, and thanks for the help.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers