1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Add infrastructure for compile-time assertions about variable types.

Currently, the macros only work with fairly recent gcc versions, but there
is room to expand them to other compilers that have comparable features.

Heavily revised and autoconfiscated version of a patch by Andres Freund.
This commit is contained in:
Tom Lane
2012-09-30 14:38:31 -04:00
parent 26fd82ddf1
commit ea473fb2de
6 changed files with 214 additions and 0 deletions

View File

@ -689,6 +689,47 @@ typedef NameData *Name;
} while (0)
/*
* Macros to support compile-time assertion checks, if the compiler has them.
*
* If the "condition" (a compile-time-constant expression) evaluates to false,
* throw a compile error using the "errmessage" (a string literal).
*
* gcc 4.6 and up supports _Static_assert(), but it has bizarre syntactic
* placement restrictions. These macros make it safe to use as a statement
* or in an expression, respectively.
*/
#ifdef HAVE__STATIC_ASSERT
#define StaticAssertStmt(condition, errmessage) \
do { _Static_assert(condition, errmessage); } while(0)
#define StaticAssertExpr(condition, errmessage) \
({ StaticAssertStmt(condition, errmessage); true; })
#else /* !HAVE__STATIC_ASSERT */
#define StaticAssertStmt(condition, errmessage)
#define StaticAssertExpr(condition, errmessage) ((void) true)
#endif /* HAVE__STATIC_ASSERT */
/*
* Compile-time checks that a variable (or expression) has the specified type.
*
* AssertVariableIsOfType() can be used as a statement.
* AssertVariableIsOfTypeMacro() is intended for use in macros, eg
* #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x))
*/
#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P
#define AssertVariableIsOfType(varname, typename) \
StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \
CppAsString(varname) " does not have type " CppAsString(typename))
#define AssertVariableIsOfTypeMacro(varname, typename) \
StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
CppAsString(varname) " does not have type " CppAsString(typename))
#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */
#define AssertVariableIsOfType(varname, typename)
#define AssertVariableIsOfTypeMacro(varname, typename) ((void) true)
#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */
/* ----------------------------------------------------------------
* Section 7: random stuff
* ----------------------------------------------------------------

View File

@ -635,6 +635,12 @@
/* Define to 1 if you have the <winldap.h> header file. */
#undef HAVE_WINLDAP_H
/* Define to 1 if your compiler understands __builtin_types_compatible_p. */
#undef HAVE__BUILTIN_TYPES_COMPATIBLE_P
/* Define to 1 if your compiler understands _Static_assert. */
#undef HAVE__STATIC_ASSERT
/* Define to the appropriate snprintf format for 64-bit ints. */
#undef INT64_FORMAT

View File

@ -526,6 +526,12 @@
/* Define to 1 if you have the <winldap.h> header file. */
/* #undef HAVE_WINLDAP_H */
/* Define to 1 if your compiler understands __builtin_types_compatible_p. */
/* #undef HAVE__BUILTIN_TYPES_COMPATIBLE_P */
/* Define to 1 if your compiler understands _Static_assert. */
/* #undef HAVE__STATIC_ASSERT */
/* Define to the appropriate snprintf format for 64-bit ints, if any. */
#define INT64_FORMAT "%lld"