From de77775a7b5031a2eddd9fa758e2139c08ae68ec 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/common/compression.c | 2 +- src/interfaces/ecpg/pgtypeslib/datetime.c | 4 ++-- src/interfaces/ecpg/preproc/ecpg.trailer | 2 +- src/interfaces/ecpg/preproc/variable.c | 2 +- src/port/chklocale.c | 2 +- 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 +- 17 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index b36f81afb9d..bf15c603a82 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -950,7 +950,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 0b9ac2e1179..b58afdce166 100644 --- a/src/backend/tsearch/spell.c +++ b/src/backend/tsearch/spell.c @@ -2313,7 +2313,7 @@ CheckCompoundAffixes(CMPDAffix **ptr, const char *word, int len, bool CheckInPla } 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 0a168fb9ea8..9c01ce8a7b9 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -1038,8 +1038,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 fc5b842de29..cb1744f4d69 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -982,7 +982,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 1da3964ca6f..79d9ab29fea 100644 --- a/src/backend/utils/adt/xid8funcs.c +++ b/src/backend/utils/adt/xid8funcs.c @@ -193,7 +193,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 51fb76efc48..a3c0368f196 100644 --- a/src/bin/pg_waldump/pg_waldump.c +++ b/src/bin/pg_waldump/pg_waldump.c @@ -160,7 +160,7 @@ create_fullpage_directory(char *path) 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 3f7faf79b23..f4dd8c0b474 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -6241,7 +6241,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/common/compression.c b/src/common/compression.c index 4c3c9fd7b50..eb434542fbd 100644 --- a/src/common/compression.c +++ b/src/common/compression.c @@ -425,7 +425,7 @@ validate_compress_specification(pg_compress_specification *spec) void parse_compress_options(const char *option, char **algorithm, char **detail) { - char *sep; + const char *sep; char *endp; long result; 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/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 6f94b832a03..390e7713bfb 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -1975,7 +1975,7 @@ civarind: cvariable indicator char_civar: char_variable { - char *ptr = strstr(@1, ".arr"); + char *ptr = (char *) strstr(@1, ".arr"); if (ptr) /* varchar, we need the struct name here, not * the struct element */ diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c index 2c67e33e92e..9179b4fb5cf 100644 --- a/src/interfaces/ecpg/preproc/variable.c +++ b/src/interfaces/ecpg/preproc/variable.c @@ -197,7 +197,7 @@ find_variable(const char *name) struct variable *p; int count; - next = strpbrk(name, ".[-"); + next = (char *) strpbrk(name, ".[-"); if (next) { if (*next == '[') diff --git a/src/port/chklocale.c b/src/port/chklocale.c index 034939f7fd2..023a7435c9b 100644 --- a/src/port/chklocale.c +++ b/src/port/chklocale.c @@ -202,7 +202,7 @@ static char * win32_get_codeset(const char *ctype) { char *r = NULL; - char *codepage; + const char *codepage; uint32 cp; WCHAR wctype[LOCALE_NAME_MAX_LENGTH]; diff --git a/src/port/getopt.c b/src/port/getopt.c index 655fef3b0c7..2cca5a0673a 100644 --- a/src/port/getopt.c +++ b/src/port/getopt.c @@ -72,7 +72,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 f83de0dff97..20953db9db1 100644 --- a/src/port/getopt_long.c +++ b/src/port/getopt_long.c @@ -62,7 +62,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 */ static int nonopt_start = -1; static bool force_nonopt = false; diff --git a/src/port/win32setlocale.c b/src/port/win32setlocale.c index 7c0982439db..6e084946132 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 5d85dcc62f0..7862bb2277a 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -693,7 +693,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 3b70b888180..38fff344394 100644 --- a/src/timezone/zic.c +++ b/src/timezone/zic.c @@ -2631,7 +2631,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;