summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/c.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/include/c.h b/src/include/c.h
index 86fbb630d4a..4a757bc8ea1 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1121,6 +1121,30 @@ typedef union PGAlignedXLogBlock
#define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION)
#endif
+/*
+ * Macro that allows to cast constness away from a variable, but doesn't
+ * allow changing the underlying type. Enforcement of the latter
+ * currently only works for gcc like compilers.
+ *
+ * Please note IT IS NOT SAFE to cast constness away if the variable will ever
+ * be modified (it would be undefined behaviour). Doing so anyway can cause
+ * compiler misoptimizations or runtime crashes (modifying readonly memory).
+ * It is only safe to use when the the variable will not be modified, but API
+ * design or language restrictions prevent you from declaring that
+ * (e.g. because a function returns both const and non-const variables).
+ *
+ * Note that this only works in function scope, not for global variables (it'd
+ * be nice, but not trivial, to improve that).
+ */
+#if defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P)
+#define unconstify(underlying_type, var) \
+ (StaticAssertExpr(__builtin_types_compatible_p(__typeof(var), const underlying_type), \
+ "wrong cast"), \
+ (underlying_type) (var))
+#else
+#define unconstify(underlying_type, var) \
+ ((underlying_type) (var))
+#endif
/* ----------------------------------------------------------------
* Section 9: system-specific hacks