Hi Hackers,

The functions in bitmapset.h that return a Bitmapset * either build a
new set or recycle their input, so ignoring the return value is always a
bug.

Commit c617aea6acd introduced the macro pg_nodiscard, which generates a
compiler warning when the result of a function call is ignored. The List
functions in pg_list.h have the same requirement, and commit a378ba49a5c
added pg_nodiscard to most of them.

However, bitmapset.h was never adjusted. The attached patch adds
pg_nodiscard to all functions there that return a Bitmapset *.

This patch does not make REALLOCATE_BITMAPSETS redundant.
REALLOCATE_BITMAPSETS reallocates the set on every modification, so a
stale pointer to the old set is likely to be noticed. However, only at
runtime and only in builds that enable it. pg_nodiscard catches the
simpler case of dropping the return value entirely at compile time.

Best regards
   Jan
-- 
Jan Nidzwetzki
PlanetScale Postgres Core Team
From 23681fa646ad2c51c71fa0a2178acf159122e07d Mon Sep 17 00:00:00 2001
From: Jan Nidzwetzki <[email protected]>
Date: Tue, 8 Sep 2026 15:15:27 +0200
Subject: [PATCH] Add pg_nodiscard decorations to Bitmapset functions

The functions in bitmapset.h that return a Bitmapset * either build a
new set or recycle their input, so ignoring the result is always a bug.

Decorate these functions with pg_nodiscard so that the compiler catches
ignored return values. Same modification as commit a378ba49a5c did for
pg_list.
---
 src/include/nodes/bitmapset.h | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/include/nodes/bitmapset.h b/src/include/nodes/bitmapset.h
index 997f8a1cd96..7d8014513dc 100644
--- a/src/include/nodes/bitmapset.h
+++ b/src/include/nodes/bitmapset.h
@@ -91,16 +91,19 @@ typedef enum
  * function prototypes in nodes/bitmapset.c
  */
 
-extern Bitmapset *bms_copy(const Bitmapset *a);
+pg_nodiscard extern Bitmapset *bms_copy(const Bitmapset *a);
 extern bool bms_equal(const Bitmapset *a, const Bitmapset *b);
 extern int     bms_compare(const Bitmapset *a, const Bitmapset *b);
-extern Bitmapset *bms_make_singleton(int x);
+pg_nodiscard extern Bitmapset *bms_make_singleton(int x);
 extern void bms_free(Bitmapset *a);
 
-extern Bitmapset *bms_union(const Bitmapset *a, const Bitmapset *b);
-extern Bitmapset *bms_intersect(const Bitmapset *a, const Bitmapset *b);
-extern Bitmapset *bms_difference(const Bitmapset *a, const Bitmapset *b);
-extern Bitmapset *bms_offset_members(const Bitmapset *a, int offset);
+pg_nodiscard extern Bitmapset *bms_union(const Bitmapset *a, const Bitmapset 
*b);
+pg_nodiscard extern Bitmapset *bms_intersect(const Bitmapset *a,
+                                                                               
         const Bitmapset *b);
+pg_nodiscard extern Bitmapset *bms_difference(const Bitmapset *a,
+                                                                               
          const Bitmapset *b);
+pg_nodiscard extern Bitmapset *bms_offset_members(const Bitmapset *a,
+                                                                               
                  int offset);
 extern bool bms_is_subset(const Bitmapset *a, const Bitmapset *b);
 extern BMS_Comparison bms_subset_compare(const Bitmapset *a, const Bitmapset 
*b);
 extern bool bms_is_member(int x, const Bitmapset *a);
@@ -120,14 +123,15 @@ extern BMS_Membership bms_membership(const Bitmapset *a);
 
 /* these routines recycle (modify or free) their non-const inputs: */
 
-extern Bitmapset *bms_add_member(Bitmapset *a, int x);
-extern Bitmapset *bms_del_member(Bitmapset *a, int x);
-extern Bitmapset *bms_add_members(Bitmapset *a, const Bitmapset *b);
-extern Bitmapset *bms_replace_members(Bitmapset *a, const Bitmapset *b);
-extern Bitmapset *bms_add_range(Bitmapset *a, int lower, int upper);
-extern Bitmapset *bms_int_members(Bitmapset *a, const Bitmapset *b);
-extern Bitmapset *bms_del_members(Bitmapset *a, const Bitmapset *b);
-extern Bitmapset *bms_join(Bitmapset *a, Bitmapset *b);
+pg_nodiscard extern Bitmapset *bms_add_member(Bitmapset *a, int x);
+pg_nodiscard extern Bitmapset *bms_del_member(Bitmapset *a, int x);
+pg_nodiscard extern Bitmapset *bms_add_members(Bitmapset *a, const Bitmapset 
*b);
+pg_nodiscard extern Bitmapset *bms_replace_members(Bitmapset *a,
+                                                                               
                   const Bitmapset *b);
+pg_nodiscard extern Bitmapset *bms_add_range(Bitmapset *a, int lower, int 
upper);
+pg_nodiscard extern Bitmapset *bms_int_members(Bitmapset *a, const Bitmapset 
*b);
+pg_nodiscard extern Bitmapset *bms_del_members(Bitmapset *a, const Bitmapset 
*b);
+pg_nodiscard extern Bitmapset *bms_join(Bitmapset *a, Bitmapset *b);
 
 /* support for iterating through the integer elements of a set: */
 extern int     bms_next_member(const Bitmapset *a, int prevbit);
-- 
2.47.3

Reply via email to