I propose to add an equivalent to unconstify() for volatile.  When
working on this, I picked the name unvolatize() mostly as a joke, but it
appears it's a real word.  Other ideas?

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From e2275c87f644b30b92434020adc8e2f7892a8e9c Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Mon, 18 Feb 2019 16:08:41 +0100
Subject: [PATCH] Add macro to cast away volatile without allowing changes to
 underlying type

This adds unvolatize(), which works just like unconstify() but for volatile.
---
 contrib/dblink/dblink.c                   | 2 +-
 contrib/hstore_plpython/hstore_plpython.c | 6 +++---
 contrib/jsonb_plpython/jsonb_plpython.c   | 4 ++--
 src/backend/postmaster/pgstat.c           | 2 +-
 src/backend/storage/ipc/latch.c           | 2 +-
 src/backend/storage/ipc/pmsignal.c        | 2 +-
 src/include/c.h                           | 8 +++++++-
 7 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index d95e6bfa71..402a692191 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -988,7 +988,7 @@ materializeQueryResult(FunctionCallInfo fcinfo,
        Assert(rsinfo->returnMode == SFRM_Materialize);
 
        /* initialize storeInfo to empty */
-       memset((void *) &sinfo, 0, sizeof(sinfo));
+       memset(unvolatize(storeInfo *, &sinfo), 0, sizeof(sinfo));
        sinfo.fcinfo = fcinfo;
 
        PG_TRY();
diff --git a/contrib/hstore_plpython/hstore_plpython.c 
b/contrib/hstore_plpython/hstore_plpython.c
index 2f24090ff3..beb201f635 100644
--- a/contrib/hstore_plpython/hstore_plpython.c
+++ b/contrib/hstore_plpython/hstore_plpython.c
@@ -146,7 +146,7 @@ plpython_to_hstore(PG_FUNCTION_ARGS)
                int32           buflen;
                int32           i;
                Pairs      *pairs;
-               PyObject   *items = (PyObject *) items_v;
+               PyObject   *items = unvolatize(PyObject *, items_v);
 
                pairs = palloc(pcount * sizeof(*pairs));
 
@@ -177,14 +177,14 @@ plpython_to_hstore(PG_FUNCTION_ARGS)
                                pairs[i].isnull = false;
                        }
                }
-               Py_DECREF(items_v);
+               Py_DECREF(items);
 
                pcount = hstoreUniquePairs(pairs, pcount, &buflen);
                out = hstorePairs(pairs, pcount, buflen);
        }
        PG_CATCH();
        {
-               Py_DECREF(items_v);
+               Py_DECREF(unvolatize(PyObject *, items_v));
                PG_RE_THROW();
        }
        PG_END_TRY();
diff --git a/contrib/jsonb_plpython/jsonb_plpython.c 
b/contrib/jsonb_plpython/jsonb_plpython.c
index f44d364c97..f860e7bc76 100644
--- a/contrib/jsonb_plpython/jsonb_plpython.c
+++ b/contrib/jsonb_plpython/jsonb_plpython.c
@@ -247,7 +247,7 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState 
**jsonb_state)
                Py_ssize_t      i;
                PyObject   *items;
 
-               items = (PyObject *) items_v;
+               items = unvolatize(PyObject *, items_v);
 
                pushJsonbValue(jsonb_state, WJB_BEGIN_OBJECT, NULL);
 
@@ -279,7 +279,7 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState 
**jsonb_state)
        }
        PG_CATCH();
        {
-               Py_DECREF(items_v);
+               Py_DECREF(unvolatize(PyObject *, items_v));
                PG_RE_THROW();
        }
        PG_END_TRY();
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 81c6499251..84ebe03284 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3275,7 +3275,7 @@ pgstat_read_current_status(void)
                        localentry->backendStatus.st_procpid = 
beentry->st_procpid;
                        if (localentry->backendStatus.st_procpid > 0)
                        {
-                               memcpy(&localentry->backendStatus, (char *) 
beentry, sizeof(PgBackendStatus));
+                               memcpy(&localentry->backendStatus, 
unvolatize(PgBackendStatus *, beentry), sizeof(PgBackendStatus));
 
                                /*
                                 * strcpy is safe even if the string is 
modified concurrently,
diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
index 7da337d11f..fa7d72ef76 100644
--- a/src/backend/storage/ipc/latch.c
+++ b/src/backend/storage/ipc/latch.c
@@ -381,7 +381,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, 
pgsocket sock,
 
        if (wakeEvents & WL_LATCH_SET)
                AddWaitEventToSet(set, WL_LATCH_SET, PGINVALID_SOCKET,
-                                                 (Latch *) latch, NULL);
+                                                 unvolatize(Latch *, latch), 
NULL);
 
        /* Postmaster-managed callers must handle postmaster death somehow. */
        Assert(!IsUnderPostmaster ||
diff --git a/src/backend/storage/ipc/pmsignal.c 
b/src/backend/storage/ipc/pmsignal.c
index d707993bf6..48f4311464 100644
--- a/src/backend/storage/ipc/pmsignal.c
+++ b/src/backend/storage/ipc/pmsignal.c
@@ -134,7 +134,7 @@ PMSignalShmemInit(void)
 
        if (!found)
        {
-               MemSet(PMSignalState, 0, PMSignalShmemSize());
+               MemSet(unvolatize(PMSignalData *, PMSignalState), 0, 
PMSignalShmemSize());
                PMSignalState->num_child_flags = MaxLivePostmasterChildren();
        }
 }
diff --git a/src/include/c.h b/src/include/c.h
index 3ea748ff58..a2f3c961d4 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1122,7 +1122,7 @@ typedef union PGAlignedXLogBlock
 #endif
 
 /*
- * Macro that allows to cast constness away from an expression, but doesn't
+ * Macro that allows to cast constness and volatile away from an expression, 
but doesn't
  * allow changing the underlying type.  Enforcement of the latter
  * currently only works for gcc like compilers.
  *
@@ -1141,9 +1141,15 @@ typedef union PGAlignedXLogBlock
        (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), const 
underlying_type), \
                                          "wrong cast"), \
         (underlying_type) (expr))
+#define unvolatize(underlying_type, expr) \
+       (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), volatile 
underlying_type), \
+                                         "wrong cast"), \
+        (underlying_type) (expr))
 #else
 #define unconstify(underlying_type, expr) \
        ((underlying_type) (expr))
+#define unvolatize(underlying_type, expr) \
+       ((underlying_type) (expr))
 #endif
 
 /* ----------------------------------------------------------------
-- 
2.20.1

Reply via email to