From 244c047205bb770f877ea525ea8bd7cd3cdad076 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 25 Feb 2026 11:19:50 -0500 Subject: [PATCH] Fix some cases of indirectly casting away const. Newest versions of gcc+glibc are able to detect cases where code implicitly casts away const by assigning the result of strchr() or a similar function applied to a "const char *" value to a target variable that's just "char *". This of course creates a hazard of not getting a compiler warning about scribbling on a string one was not supposed to, so fixing up such cases is good. This patch fixes a dozen or so places where we were doing that. Most are trivial additions of "const" to the target variable, since no actually-hazardous change was occurring. Thanks to Bertrand Drouvot for finding a couple more spots than I had. This commit back-patches relevant portions of 8f1791c61 and 9f7565c6c into supported branches. However, there are two places in ecpg (in v18 only) where a proper fix is more complicated than seems appropriate for a back-patch. I opted to silence those two warnings by adding casts. Author: Tom Lane Reviewed-by: Bertrand Drouvot Discussion: https://postgr.es/m/1324889.1764886170@sss.pgh.pa.us Discussion: https://postgr.es/m/3988414.1771950285@sss.pgh.pa.us Backpatch-through: 14-18 --- src/backend/catalog/pg_type.c | 2 +- src/backend/tsearch/spell.c | 2 +- src/backend/utils/adt/formatting.c | 5 +++-- src/backend/utils/adt/pg_locale.c | 2 +- src/backend/utils/adt/xid8funcs.c | 2 +- src/bin/pg_waldump/pg_waldump.c | 2 +- src/bin/pgbench/pgbench.c | 2 +- src/interfaces/ecpg/pgtypeslib/datetime.c | 4 ++-- src/port/getopt.c | 2 +- src/port/getopt_long.c | 2 +- src/port/win32setlocale.c | 8 ++++---- src/test/regress/pg_regress.c | 2 +- src/timezone/zic.c | 2 +- 13 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index b37a8f034be..1e6b4670147 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -904,7 +904,7 @@ char * makeMultirangeTypeName(const char *rangeTypeName, Oid typeNamespace) { char *buf; - char *rangestr; + const char *rangestr; /* * If the range type name contains "range" then change that to diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c index f65c083c06f..09e7357b4d8 100644 --- a/src/backend/tsearch/spell.c +++ b/src/backend/tsearch/spell.c @@ -2327,7 +2327,7 @@ CheckCompoundAffixes(CMPDAffix **ptr, char *word, int len, bool CheckInPlace) } else { - char *affbegin; + const char *affbegin; while ((*ptr)->affix) { diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 5b617ff4619..a157c3c8764 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -1008,8 +1008,9 @@ typedef struct NUMProc char *number, /* string with number */ *number_p, /* pointer to current number position */ *inout, /* in / out buffer */ - *inout_p, /* pointer to current inout position */ - *last_relevant, /* last relevant number after decimal point */ + *inout_p; /* pointer to current inout position */ + + const char *last_relevant, /* last relevant number after decimal point */ *L_negative_sign, /* Locale */ *L_positive_sign, diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 8ae101cefc2..9d788233848 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1046,7 +1046,7 @@ get_iso_localename(const char *winlocname) wchar_t wc_locale_name[LOCALE_NAME_MAX_LENGTH]; wchar_t buffer[LOCALE_NAME_MAX_LENGTH]; static char iso_lc_messages[LOCALE_NAME_MAX_LENGTH]; - char *period; + const char *period; int len; int ret_val; diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c index bca4e674df1..09efc70e4f6 100644 --- a/src/backend/utils/adt/xid8funcs.c +++ b/src/backend/utils/adt/xid8funcs.c @@ -225,7 +225,7 @@ is_visible_fxid(FullTransactionId value, const pg_snapshot *snap) #ifdef USE_BSEARCH_IF_NXIP_GREATER else if (snap->nxip > USE_BSEARCH_IF_NXIP_GREATER) { - void *res; + const void *res; res = bsearch(&value, snap->xip, snap->nxip, sizeof(FullTransactionId), cmp_fxid); diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c index 2daed328e7d..cf8ef21bacd 100644 --- a/src/bin/pg_waldump/pg_waldump.c +++ b/src/bin/pg_waldump/pg_waldump.c @@ -107,7 +107,7 @@ verify_directory(const char *directory) static void split_path(const char *path, char **dir, char **fname) { - char *sep; + const char *sep; /* split filepath into directory & filename */ sep = strrchr(path, '/'); diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index fd70196a160..94d2e8e9bac 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -5483,7 +5483,7 @@ findBuiltin(const char *name) static int parseScriptWeight(const char *option, char **script) { - char *sep; + const char *sep; int weight; if ((sep = strrchr(option, WSEP))) diff --git a/src/interfaces/ecpg/pgtypeslib/datetime.c b/src/interfaces/ecpg/pgtypeslib/datetime.c index 1b253747fc4..f43343b4594 100644 --- a/src/interfaces/ecpg/pgtypeslib/datetime.c +++ b/src/interfaces/ecpg/pgtypeslib/datetime.c @@ -335,8 +335,8 @@ PGTYPESdate_defmt_asc(date * d, const char *fmt, const char *str) */ int token[3][2]; int token_values[3] = {-1, -1, -1}; - char *fmt_token_order; - char *fmt_ystart, + const char *fmt_token_order; + const char *fmt_ystart, *fmt_mstart, *fmt_dstart; unsigned int i; diff --git a/src/port/getopt.c b/src/port/getopt.c index 207c2836d35..3e101a7217e 100644 --- a/src/port/getopt.c +++ b/src/port/getopt.c @@ -71,7 +71,7 @@ int getopt(int nargc, char *const *nargv, const char *ostr) { static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ + const char *oli; /* option letter list index */ if (!*place) { /* update scanning pointer */ diff --git a/src/port/getopt_long.c b/src/port/getopt_long.c index c9892769883..70bb3147c0a 100644 --- a/src/port/getopt_long.c +++ b/src/port/getopt_long.c @@ -59,7 +59,7 @@ getopt_long(int argc, char *const argv[], const struct option *longopts, int *longindex) { static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ + const char *oli; /* option letter list index */ if (!*place) { /* update scanning pointer */ diff --git a/src/port/win32setlocale.c b/src/port/win32setlocale.c index 4edae05bb7c..f45f8dd95d3 100644 --- a/src/port/win32setlocale.c +++ b/src/port/win32setlocale.c @@ -119,9 +119,9 @@ map_locale(const struct locale_map *map, const char *locale) const char *needle_start = map[i].locale_name_start; const char *needle_end = map[i].locale_name_end; const char *replacement = map[i].replacement; - char *match; - char *match_start = NULL; - char *match_end = NULL; + const char *match; + const char *match_start = NULL; + const char *match_end = NULL; match = strstr(locale, needle_start); if (match) @@ -148,7 +148,7 @@ map_locale(const struct locale_map *map, const char *locale) /* Found a match. Replace the matched string. */ int matchpos = match_start - locale; int replacementlen = strlen(replacement); - char *rest = match_end; + const char *rest = match_end; int restlen = strlen(rest); /* check that the result fits in the static buffer */ diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index b23d9f3bf97..f6797e7e9fb 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -709,7 +709,7 @@ static const char * get_expectfile(const char *testname, const char *file) { - char *file_type; + const char *file_type; _resultmap *rm; /* diff --git a/src/timezone/zic.c b/src/timezone/zic.c index 0ea6ead2db3..6ccd739dcd8 100644 --- a/src/timezone/zic.c +++ b/src/timezone/zic.c @@ -2629,7 +2629,7 @@ doabbr(char *abbr, struct zone const *zp, char const *letters, bool isdst, zic_t save, bool doquotes) { char *cp; - char *slashp; + char const *slashp; size_t len; char const *format = zp->z_format;