Hi,

On Tue, Jan 20, 2026 at 08:54:18AM +0100, Peter Eisentraut wrote:
> This patch fixes cases where a qualifier (const, in all cases here) was
> dropped by a cast, but the cast was otherwise necessary or desirable, so the
> straightforward fix is to add the qualifier into the cast.
> 
> This was checked with gcc -Wcast-qual, but it doesn't fix all such warnings,
> only the trivially fixable ones.

diff --git a/src/include/varatt.h b/src/include/varatt.h
index eccd3ca04d6..03e9d1869aa 100644
--- a/src/include/varatt.h
+++ b/src/include/varatt.h

It looks like those changes produce:

../../../src/include/varatt.h: In function ‘VARDATA’:
../../../src/include/varatt.h:261:33: warning: return discards ‘const’ 
qualifier from pointer target type [-Wdiscarded-qualifiers]
  261 | #define VARDATA_4B(PTR)         (((const varattrib_4b *) 
(PTR))->va_4byte.va_data)
      |                                 ^
../../../src/include/varatt.h:307:16: note: in expansion of macro ‘VARDATA_4B’
  307 |         return VARDATA_4B(PTR);
      |                ^~~~~~~~~~
../../../src/include/varatt.h: In function ‘VARDATA_SHORT’:
../../../src/include/varatt.h:263:33: warning: return discards ‘const’ 
qualifier from pointer target type [-Wdiscarded-qualifiers]
  263 | #define VARDATA_1B(PTR)         (((const varattrib_1b *) 
(PTR))->va_data)
      |                                 ^
../../../src/include/varatt.h:321:16: note: in expansion of macro ‘VARDATA_1B’
  321 |         return VARDATA_1B(PTR);
      |                ^~~~~~~~~~
../../../src/include/varatt.h: In function ‘VARDATA_EXTERNAL’:
../../../src/include/varatt.h:264:33: warning: return discards ‘const’ 
qualifier from pointer target type [-Wdiscarded-qualifiers]
  264 | #define VARDATA_1B_E(PTR)       (((const varattrib_1b_e *) 
(PTR))->va_data)
      |                                 ^
../../../src/include/varatt.h:342:16: note: in expansion of macro ‘VARDATA_1B_E’
  342 |         return VARDATA_1B_E(PTR);
      |                ^~~~~~~~~~~~
../../../src/include/varatt.h: In function ‘VARDATA_ANY’:
../../../src/include/varatt.h:488:52: warning: return discards ‘const’ 
qualifier from pointer target type [-Wdiscarded-qualifiers]
  488 |         return VARATT_IS_1B(PTR) ? VARDATA_1B(PTR) : VARDATA_4B(PTR);

as they are still used by functions that return non const:

"
static inline char *
VARDATA(const void *PTR)
{
    return VARDATA_4B(PTR);
}
"

> -     RangeType  *r1 = *(RangeType **) key1;
> -     RangeType  *r2 = *(RangeType **) key2;
> +     RangeType  *r1 = *(RangeType *const *) key1;
> +     RangeType  *r2 = *(RangeType *const *) key2;

That's correct. My improved cocci script [1] would incorrectly produce:

-       RangeType  *r1 = *(RangeType **) key1;
-       RangeType  *r2 = *(RangeType **) key2;
+       RangeType  *r1 = *(const RangeType **)key1;
+       RangeType  *r2 = *(const RangeType **)key2;

Same for:

> -     file_entry_t *fa = *((file_entry_t **) a);
> -     file_entry_t *fb = *((file_entry_t **) b);
> +     file_entry_t *fa = *((file_entry_t *const *) a);
> +     file_entry_t *fb = *((file_entry_t *const *) b);
>  
>  

Same for:

> -     Step       *stepa = *((Step **) a);
> -     Step       *stepb = *((Step **) b);
> +     Step       *stepa = *((Step *const *) a);
> +     Step       *stepb = *((Step *const *) b);
>  
> -     Step       *step = *((Step **) b);
> +     Step       *step = *((Step *const *) b);
>  
> diff --git a/src/test/modules/libpq_pipeline/libpq_pipeline.c 
> b/src/test/modules/libpq_pipeline/libpq_pipeline.c
> index 03371721460..4a9bb65b9bb 100644
> --- a/src/test/modules/libpq_pipeline/libpq_pipeline.c
> +++ b/src/test/modules/libpq_pipeline/libpq_pipeline.c
> @@ -1576,7 +1576,7 @@ test_singlerowmode(PGconn *conn)
>                                                         "SELECT 
> generate_series(42, $1)",
>                                                         1,
>                                                         NULL,
> -                                                       (const char **) param,
> +                                                       (const char *const *) 
> param,
>                                                         NULL,
>                                                         NULL,
>                                                         0) != 1)

Correct, also according to:

"
int
PQsendQueryParams(PGconn *conn,
                  const char *command,
                  int nParams,
                  const Oid *paramTypes,
                  const char *const *paramValues,
                  const int *paramLengths,
                  const int *paramFormats,
                  int resultFormat)
{
"

Also [1], detected a few more trivially fixable ones (see attached).

[1]: 
https://github.com/bdrouvot/coccinelle_on_pg/blob/main/misc/search_const_away.cocci

Regards,

-- 
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
>From 9712e7530997e3927b1d27a9b2f981f1c1b23499 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <[email protected]>
Date: Tue, 20 Jan 2026 10:57:27 +0000
Subject: [PATCH v1] More Fix accidentally cast away qualifiers

---
 src/backend/access/spgist/spgquadtreeproc.c | 8 ++++----
 src/common/unicode/case_test.c              | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)
  66.9% src/backend/access/spgist/
  33.0% src/common/unicode/

diff --git a/src/backend/access/spgist/spgquadtreeproc.c 
b/src/backend/access/spgist/spgquadtreeproc.c
index 1b907d9186b..430e802cf80 100644
--- a/src/backend/access/spgist/spgquadtreeproc.c
+++ b/src/backend/access/spgist/spgquadtreeproc.c
@@ -145,8 +145,8 @@ spg_quad_choose(PG_FUNCTION_ARGS)
 static int
 x_cmp(const void *a, const void *b, void *arg)
 {
-       Point      *pa = *(Point **) a;
-       Point      *pb = *(Point **) b;
+       Point      *pa = *(Point *const *) a;
+       Point      *pb = *(Point *const *) b;
 
        if (pa->x == pb->x)
                return 0;
@@ -156,8 +156,8 @@ x_cmp(const void *a, const void *b, void *arg)
 static int
 y_cmp(const void *a, const void *b, void *arg)
 {
-       Point      *pa = *(Point **) a;
-       Point      *pb = *(Point **) b;
+       Point      *pa = *(Point *const *) a;
+       Point      *pb = *(Point *const *) b;
 
        if (pa->y == pb->y)
                return 0;
diff --git a/src/common/unicode/case_test.c b/src/common/unicode/case_test.c
index 2144219e178..fb159c1c27c 100644
--- a/src/common/unicode/case_test.c
+++ b/src/common/unicode/case_test.c
@@ -55,7 +55,7 @@ initcap_wbnext(void *state)
        while (wbstate->offset < wbstate->len &&
                   wbstate->str[wbstate->offset] != '\0')
        {
-               char32_t        u = utf8_to_unicode((unsigned char *) 
wbstate->str +
+               char32_t        u = utf8_to_unicode((const unsigned char *) 
wbstate->str +
                                                                                
wbstate->offset);
                bool            curr_alnum = pg_u_isalnum(u, wbstate->posix);
 
-- 
2.34.1

Reply via email to