summaryrefslogtreecommitdiff
path: root/src/include/c.h
diff options
context:
space:
mode:
authorPeter Eisentraut2025-03-13 11:25:14 +0000
committerPeter Eisentraut2025-03-13 11:37:26 +0000
commit3691edfab97187789b8a1cbb9dce4acf0ecd8f5a (patch)
treee7cfb60f9d50dd35686d21563113f7e6ecdb85d6 /src/include/c.h
parentcc5d98525d43c22b98f360ef0f2c8d7dc57f04dc (diff)
pg_noreturn to replace pg_attribute_noreturn()
We want to support a "noreturn" decoration on more compilers besides just GCC-compatible ones, but for that we need to move the decoration in front of the function declaration instead of either behind it or wherever, which is the current style afforded by GCC-style attributes. Also rename the macro to "pg_noreturn" to be similar to the C11 standard "noreturn". pg_noreturn is now supported on all compilers that support C11 (using _Noreturn), as well as GCC-compatible ones (using __attribute__, as before), as well as MSVC (using __declspec). (When PostgreSQL requires C11, the latter two variants can be dropped.) Now, all supported compilers effectively support pg_noreturn, so the extra code for !HAVE_PG_ATTRIBUTE_NORETURN can be dropped. This also fixes a possible problem if third-party code includes stdnoreturn.h, because then the current definition of #define pg_attribute_noreturn() __attribute__((noreturn)) would cause an error. Note that the C standard does not support a noreturn attribute on function pointer types. So we have to drop these here. There are only two instances at this time, so it's not a big loss. In one case, we can make up for it by adding the pg_noreturn to a wrapper function and adding a pg_unreachable(), in the other case, the latter was already done before. Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org> Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://www.postgresql.org/message-id/flat/pxr5b3z7jmkpenssra5zroxi7qzzp6eswuggokw64axmdixpnk@zbwxuq7gbbcw
Diffstat (limited to 'src/include/c.h')
-rw-r--r--src/include/c.h34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/include/c.h b/src/include/c.h
index a14c6315162..94971474154 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -146,6 +146,26 @@
#endif
/*
+ * pg_noreturn corresponds to the C11 noreturn/_Noreturn function specifier.
+ * We can't use the standard name "noreturn" because some third-party code
+ * uses __attribute__((noreturn)) in headers, which would get confused if
+ * "noreturn" is defined to "_Noreturn", as is done by <stdnoreturn.h>.
+ *
+ * In a declaration, function specifiers go before the function name. The
+ * common style is to put them before the return type. (The MSVC fallback has
+ * the same requirement. The GCC fallback is more flexible.)
+ */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#define pg_noreturn _Noreturn
+#elif defined(__GNUC__) || defined(__SUNPRO_C)
+#define pg_noreturn __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define pg_noreturn __declspec(noreturn)
+#else
+#define pg_noreturn
+#endif
+
+/*
* This macro will disable address safety instrumentation for a function
* when running with "-fsanitize=address". Think twice before using this!
*/
@@ -213,30 +233,24 @@
#define pg_attribute_printf(f,a)
#endif
-/* GCC and Sunpro support aligned, packed and noreturn */
+/* GCC and Sunpro support aligned and packed */
#if defined(__GNUC__) || defined(__SUNPRO_C)
#define pg_attribute_aligned(a) __attribute__((aligned(a)))
-#define pg_attribute_noreturn() __attribute__((noreturn))
#define pg_attribute_packed() __attribute__((packed))
-#define HAVE_PG_ATTRIBUTE_NORETURN 1
#elif defined(_MSC_VER)
/*
- * MSVC supports aligned. noreturn is also possible but in MSVC it is
- * declared before the definition while pg_attribute_noreturn() macro
- * is currently used after the definition.
+ * MSVC supports aligned.
*
* Packing is also possible but only by wrapping the entire struct definition
* which doesn't fit into our current macro declarations.
*/
#define pg_attribute_aligned(a) __declspec(align(a))
-#define pg_attribute_noreturn()
#else
/*
* NB: aligned and packed are not given default definitions because they
* affect code functionality; they *must* be implemented by the compiler
* if they are to be used.
*/
-#define pg_attribute_noreturn()
#endif
/*
@@ -858,8 +872,8 @@ typedef NameData *Name;
* we should declare it as long as !FRONTEND.
*/
#ifndef FRONTEND
-extern void ExceptionalCondition(const char *conditionName,
- const char *fileName, int lineNumber) pg_attribute_noreturn();
+pg_noreturn extern void ExceptionalCondition(const char *conditionName,
+ const char *fileName, int lineNumber);
#endif
/*