diff --git a/configure b/configure index 31bc8fb374b..58fea907ea6 100755 --- a/configure +++ b/configure @@ -4123,6 +4123,66 @@ if test x"$pgac_cv_prog_cc_cflags__Wendif_labels" = x"yes"; then CFLAGS="$CFLAGS -Wendif-labels" fi + { $as_echo "$as_me:$LINENO: checking whether $CC supports -Wmissing-format-attribute" >&5 +$as_echo_n "checking whether $CC supports -Wmissing-format-attribute... " >&6; } +if test "${pgac_cv_prog_cc_cflags__Wmissing_format_attribute+set}" = set; then + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +CFLAGS="$pgac_save_CFLAGS -Wmissing-format-attribute" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + pgac_cv_prog_cc_cflags__Wmissing_format_attribute=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + pgac_cv_prog_cc_cflags__Wmissing_format_attribute=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +fi +{ $as_echo "$as_me:$LINENO: result: $pgac_cv_prog_cc_cflags__Wmissing_format_attribute" >&5 +$as_echo "$pgac_cv_prog_cc_cflags__Wmissing_format_attribute" >&6; } +if test x"$pgac_cv_prog_cc_cflags__Wmissing_format_attribute" = x"yes"; then + CFLAGS="$CFLAGS -Wmissing-format-attribute" +fi + # This was included in -Wall/-Wformat in older GCC versions { $as_echo "$as_me:$LINENO: checking whether $CC supports -Wformat-security" >&5 $as_echo_n "checking whether $CC supports -Wformat-security... " >&6; } diff --git a/configure.in b/configure.in index 05259cb8694..5dc669f545a 100644 --- a/configure.in +++ b/configure.in @@ -430,6 +430,7 @@ if test "$GCC" = yes -a "$ICC" = no; then # These work in some but not all gcc versions PGAC_PROG_CC_CFLAGS_OPT([-Wdeclaration-after-statement]) PGAC_PROG_CC_CFLAGS_OPT([-Wendif-labels]) + PGAC_PROG_CC_CFLAGS_OPT([-Wmissing-format-attribute]) # This was included in -Wall/-Wformat in older GCC versions PGAC_PROG_CC_CFLAGS_OPT([-Wformat-security]) # Disable strict-aliasing rules; needed for gcc 3.3+ diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c index 5606486ef36..e41ab2b1071 100644 --- a/contrib/pg_upgrade/info.c +++ b/contrib/pg_upgrade/info.c @@ -286,7 +286,7 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) (GET_MAJOR_VERSION(old_cluster.major_version) <= 804) ? "" : ", 'pg_largeobject_metadata', 'pg_largeobject_metadata_oid_index'"); - res = executeQueryOrDie(conn, query); + res = executeQueryOrDie(conn, "%s", query); ntups = PQntuples(res); diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h index 2abd91771f9..46aed74450d 100644 --- a/contrib/pg_upgrade/pg_upgrade.h +++ b/contrib/pg_upgrade/pg_upgrade.h @@ -292,8 +292,8 @@ void split_old_dump(void); /* exec.c */ -int exec_prog(bool throw_error, - const char *cmd,...); +int exec_prog(bool throw_error, const char *cmd, ...) + __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); void verify_directories(void); bool is_server_running(const char *datadir); void rename_old_pg_control(void); @@ -377,7 +377,8 @@ void init_tablespaces(void); /* server.c */ PGconn *connectToServer(ClusterInfo *cluster, const char *db_name); -PGresult *executeQueryOrDie(PGconn *conn, const char *fmt,...); +PGresult *executeQueryOrDie(PGconn *conn, const char *fmt, ...) + __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); void start_postmaster(ClusterInfo *cluster); void stop_postmaster(bool fast); @@ -390,9 +391,12 @@ void check_pghost_envvar(void); char *quote_identifier(const char *s); int get_user_info(char **user_name); void check_ok(void); -void report_status(eLogType type, const char *fmt,...); -void pg_log(eLogType type, char *fmt,...); -void prep_status(const char *fmt,...); +void report_status(eLogType type, const char *fmt, ...) + __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); +void pg_log(eLogType type, char *fmt, ...) + __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); +void prep_status(const char *fmt, ...) + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); void check_ok(void); char *pg_strdup(const char *s); void *pg_malloc(int size); diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c index 9354d92d36c..1aefd337f1f 100644 --- a/contrib/pg_upgrade/relfilenode.c +++ b/contrib/pg_upgrade/relfilenode.c @@ -71,7 +71,9 @@ transfer_all_new_dbs(DbInfoArr *old_db_arr, } } - prep_status(""); /* in case nothing printed */ + prep_status(" "); /* in case nothing printed; pass a space so gcc + * doesn't complain about empty format + * string */ check_ok(); return msg; diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h index 9709f9bdb60..610b7fad789 100644 --- a/contrib/pgcrypto/px.h +++ b/contrib/pgcrypto/px.h @@ -204,7 +204,8 @@ const char *px_resolve_alias(const PX_Alias *aliases, const char *name); void px_set_debug_handler(void (*handler) (const char *)); #ifdef PX_DEBUG -void px_debug(const char *fmt,...); +void px_debug(const char *fmt, ...) + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); #else #define px_debug(...) #endif diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 62206ecda4d..1611551638b 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -119,8 +119,8 @@ static int _discoverArchiveFormat(ArchiveHandle *AH); static int RestoringToDB(ArchiveHandle *AH); static void dump_lo_buf(ArchiveHandle *AH); -static void _write_msg(const char *modulename, const char *fmt, va_list ap); -static void _die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt, va_list ap); +static void _write_msg(const char *modulename, const char *fmt, va_list ap) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0))); +static void _die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt, va_list ap) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0))); static void dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim); static void SetOutput(ArchiveHandle *AH, char *filename, int compression); diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c index 041f9f9cbbb..45aab1e2364 100644 --- a/src/bin/pg_dump/pg_backup_tar.c +++ b/src/bin/pg_dump/pg_backup_tar.c @@ -112,7 +112,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,...); +static int tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt, ...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4))); static void _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th); static int _tarChecksum(char *th); diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h index 3657a685395..79b09d23b43 100644 --- a/src/include/lib/stringinfo.h +++ b/src/include/lib/stringinfo.h @@ -105,7 +105,8 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); * without modifying str. Typically the caller would enlarge str and retry * on false return --- see appendStringInfo for standard usage pattern. */ -extern bool appendStringInfoVA(StringInfo str, const char *fmt, va_list args); +extern bool appendStringInfoVA(StringInfo str, const char *fmt, va_list args) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0))); /*------------------------ * appendStringInfoString diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c index 5f56de03120..fb5aa9a185d 100644 --- a/src/interfaces/ecpg/ecpglib/descriptor.c +++ b/src/interfaces/ecpg/ecpglib/descriptor.c @@ -388,7 +388,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...) */ if (arrsize > 0 && ntuples > arrsize) { - ecpg_log("ECPGget_desc on line %d: incorrect number of matches; %d don't fit into array of %d\n", + ecpg_log("ECPGget_desc on line %d: incorrect number of matches; %d don't fit into array of %ld\n", lineno, ntuples, arrsize); ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL); return false; @@ -457,7 +457,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...) */ if (data_var.ind_arrsize > 0 && ntuples > data_var.ind_arrsize) { - ecpg_log("ECPGget_desc on line %d: incorrect number of matches (indicator); %d don't fit into array of %d\n", + ecpg_log("ECPGget_desc on line %d: incorrect number of matches (indicator); %d don't fit into array of %ld\n", lineno, ntuples, data_var.ind_arrsize); ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL); return false; diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c index 58024f47b0c..54fb6f94508 100644 --- a/src/interfaces/ecpg/ecpglib/error.c +++ b/src/interfaces/ecpg/ecpglib/error.c @@ -335,7 +335,7 @@ ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat) sqlca->sqlcode = ECPG_PGSQL; /* %.*s is safe here as long as sqlstate is all-ASCII */ - ecpg_log("raising sqlstate %.*s (sqlcode %d): %s\n", + ecpg_log("raising sqlstate %.*s (sqlcode %ld): %s\n", sizeof(sqlca->sqlstate), sqlca->sqlstate, sqlca->sqlcode, sqlca->sqlerrm.sqlerrmc); /* free all memory we have allocated for the user */ diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 2fb54392c9e..a288b3ff125 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -332,7 +332,7 @@ ecpg_store_result(const PGresult *results, int act_field, */ if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize)) { - ecpg_log("ecpg_store_result on line %d: incorrect number of matches; %d don't fit into array of %d\n", + ecpg_log("ecpg_store_result on line %d: incorrect number of matches; %d don't fit into array of %ld\n", stmt->lineno, ntuples, var->arrsize); ecpg_raise(stmt->lineno, INFORMIX_MODE(stmt->compat) ? ECPG_INFORMIX_SUBSELECT_NOT_ONE : ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL); return false; diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h index 0d55102d0da..96d49a4a6b7 100644 --- a/src/interfaces/ecpg/ecpglib/extern.h +++ b/src/interfaces/ecpg/ecpglib/extern.h @@ -161,7 +161,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,...); +void ecpg_log(const char *format, ...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); bool ecpg_auto_prepare(int, const char *, const int, char **, const char *); void ecpg_init_sqlca(struct sqlca_t * sqlca);