aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/c-compiler.m440
-rwxr-xr-xconfigure119
-rw-r--r--configure.in2
-rw-r--r--src/include/c.h41
-rw-r--r--src/include/pg_config.h.in6
-rw-r--r--src/include/pg_config.h.win326
6 files changed, 214 insertions, 0 deletions
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 9398ca6c477..069b468daac 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -121,6 +121,46 @@ fi])# PGAC_C_FUNCNAME_SUPPORT
+# PGAC_C_STATIC_ASSERT
+# -----------------------
+# Check if the C compiler understands _Static_assert(),
+# and define HAVE__STATIC_ASSERT if so.
+#
+# We actually check the syntax ({ _Static_assert(...) }), because we need
+# gcc-style compound expressions to be able to wrap the thing into macros.
+AC_DEFUN([PGAC_C_STATIC_ASSERT],
+[AC_CACHE_CHECK(for _Static_assert, pgac_cv__static_assert,
+[AC_TRY_LINK([],
+[({ _Static_assert(1, "foo"); })],
+[pgac_cv__static_assert=yes],
+[pgac_cv__static_assert=no])])
+if test x"$pgac_cv__static_assert" = xyes ; then
+AC_DEFINE(HAVE__STATIC_ASSERT, 1,
+ [Define to 1 if your compiler understands _Static_assert.])
+fi])# PGAC_C_STATIC_ASSERT
+
+
+
+# PGAC_C_TYPES_COMPATIBLE
+# -----------------------
+# Check if the C compiler understands __builtin_types_compatible_p,
+# and define HAVE__BUILTIN_TYPES_COMPATIBLE_P if so.
+#
+# We check usage with __typeof__, though it's unlikely any compiler would
+# have the former and not the latter.
+AC_DEFUN([PGAC_C_TYPES_COMPATIBLE],
+[AC_CACHE_CHECK(for __builtin_types_compatible_p, pgac_cv__types_compatible,
+[AC_TRY_COMPILE([],
+[ int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)]; ],
+[pgac_cv__types_compatible=yes],
+[pgac_cv__types_compatible=no])])
+if test x"$pgac_cv__types_compatible" = xyes ; then
+AC_DEFINE(HAVE__BUILTIN_TYPES_COMPATIBLE_P, 1,
+ [Define to 1 if your compiler understands __builtin_types_compatible_p.])
+fi])# PGAC_C_TYPES_COMPATIBLE
+
+
+
# PGAC_PROG_CC_CFLAGS_OPT
# -----------------------
# Given a string, check if the compiler supports the string as a
diff --git a/configure b/configure
index 56da7cdc73f..c6dcc8bfaaf 100755
--- a/configure
+++ b/configure
@@ -15525,6 +15525,125 @@ _ACEOF
fi
fi
+{ $as_echo "$as_me:$LINENO: checking for _Static_assert" >&5
+$as_echo_n "checking for _Static_assert... " >&6; }
+if test "${pgac_cv__static_assert+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+({ _Static_assert(1, "foo"); })
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ pgac_cv__static_assert=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ pgac_cv__static_assert=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $pgac_cv__static_assert" >&5
+$as_echo "$pgac_cv__static_assert" >&6; }
+if test x"$pgac_cv__static_assert" = xyes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE__STATIC_ASSERT 1
+_ACEOF
+
+fi
+{ $as_echo "$as_me:$LINENO: checking for __builtin_types_compatible_p" >&5
+$as_echo_n "checking for __builtin_types_compatible_p... " >&6; }
+if test "${pgac_cv__types_compatible+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+ int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)];
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ pgac_cv__types_compatible=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ pgac_cv__types_compatible=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $pgac_cv__types_compatible" >&5
+$as_echo "$pgac_cv__types_compatible" >&6; }
+if test x"$pgac_cv__types_compatible" = xyes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE__BUILTIN_TYPES_COMPATIBLE_P 1
+_ACEOF
+
+fi
{ $as_echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
if test "${ac_cv_struct_tm+set}" = set; then
diff --git a/configure.in b/configure.in
index 8d02abb4cca..fef8e7f013a 100644
--- a/configure.in
+++ b/configure.in
@@ -1104,6 +1104,8 @@ AC_C_FLEXIBLE_ARRAY_MEMBER
PGAC_C_SIGNED
AC_C_VOLATILE
PGAC_C_FUNCNAME_SUPPORT
+PGAC_C_STATIC_ASSERT
+PGAC_C_TYPES_COMPATIBLE
PGAC_STRUCT_TIMEZONE
PGAC_UNION_SEMUN
PGAC_STRUCT_SOCKADDR_UN
diff --git a/src/include/c.h b/src/include/c.h
index 50e1ecfde4d..06f689d3593 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -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
* ----------------------------------------------------------------
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 1ffb032835f..58cd5907dd4 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -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
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index b7b7c641d3a..4d9cc55c699 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -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"