Use C99 restrict via pg_restrict, rather than restrict directly.
authorAndres Freund <andres@anarazel.de>
Thu, 12 Oct 2017 22:25:38 +0000 (15:25 -0700)
committerAndres Freund <andres@anarazel.de>
Thu, 12 Oct 2017 23:17:35 +0000 (16:17 -0700)
Unfortunately using 'restrict' plainly causes problems with MSVC,
which supports restrict only as '__restrict'. Defining 'restrict' to
'__restrict' unfortunately causes a conflict with MSVC's usage of
__declspec(restrict) in headers.

Therefore define pg_restrict to the appropriate keyword instead, and
replace existing usages.

This replaces the temporary workaround introduced in 36b4b91ba078.

Author: Andres Freund
Discussion: https://postgr.es/m/2656.1507830907@sss.pgh.pa.us

configure
configure.in
src/include/libpq/pqformat.h
src/include/pg_config.h.in
src/include/pg_config.h.win32

index 910f0fc3736992697485358c651241c3c4742091..cdcb3ceb0c80e888941785491c44369b56dc911b 100755 (executable)
--- a/configure
+++ b/configure
@@ -11545,52 +11545,6 @@ _ACEOF
     ;;
 esac
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
-$as_echo_n "checking for C/C++ restrict keyword... " >&6; }
-if ${ac_cv_c_restrict+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_c_restrict=no
-   # The order here caters to the fact that C++ does not require restrict.
-   for ac_kw in __restrict __restrict__ _Restrict restrict; do
-     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-typedef int * int_ptr;
-       int foo (int_ptr $ac_kw ip) {
-       return ip[0];
-       }
-int
-main ()
-{
-int s[1];
-       int * $ac_kw t = s;
-       t[0] = 0;
-       return foo(t)
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_c_restrict=$ac_kw
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-     test "$ac_cv_c_restrict" != no && break
-   done
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5
-$as_echo "$ac_cv_c_restrict" >&6; }
-
- case $ac_cv_c_restrict in
-   restrict) ;;
-   no) $as_echo "#define restrict /**/" >>confdefs.h
- ;;
-   *)  cat >>confdefs.h <<_ACEOF
-#define restrict $ac_cv_c_restrict
-_ACEOF
- ;;
- esac
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf format archetype" >&5
 $as_echo_n "checking for printf format archetype... " >&6; }
 if ${pgac_cv_printf_archetype+:} false; then :
@@ -12508,6 +12462,67 @@ $as_echo "#define LOCALE_T_IN_XLOCALE 1" >>confdefs.h
 
 fi
 
+# MSVC doesn't cope well with defining restrict to __restrict, the
+# spelling it understands, because it conflicts with
+# __declspec(restrict). Therefore we define pg_restrict to the
+# appropriate definition, which presumably won't conflict.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
+$as_echo_n "checking for C/C++ restrict keyword... " >&6; }
+if ${ac_cv_c_restrict+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_restrict=no
+   # The order here caters to the fact that C++ does not require restrict.
+   for ac_kw in __restrict __restrict__ _Restrict restrict; do
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+typedef int * int_ptr;
+       int foo (int_ptr $ac_kw ip) {
+       return ip[0];
+       }
+int
+main ()
+{
+int s[1];
+       int * $ac_kw t = s;
+       t[0] = 0;
+       return foo(t)
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_restrict=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+     test "$ac_cv_c_restrict" != no && break
+   done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5
+$as_echo "$ac_cv_c_restrict" >&6; }
+
+ case $ac_cv_c_restrict in
+   restrict) ;;
+   no) $as_echo "#define restrict /**/" >>confdefs.h
+ ;;
+   *)  cat >>confdefs.h <<_ACEOF
+#define restrict $ac_cv_c_restrict
+_ACEOF
+ ;;
+ esac
+
+if test "$ac_cv_c_restrict" = "no" ; then
+  pg_restrict=""
+else
+  pg_restrict="$ac_cv_c_restrict"
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define pg_restrict $pg_restrict
+_ACEOF
+
+
 ac_fn_c_check_type "$LINENO" "struct cmsgcred" "ac_cv_type_struct_cmsgcred" "#include <sys/socket.h>
 #include <sys/param.h>
 #ifdef HAVE_SYS_UCRED_H
index ab990d69f4cb5fc134265ec34fc9e0fa79bbd5e3..32bb7bf940d2792f2e6a82da760196cae2ed95f8 100644 (file)
@@ -1299,7 +1299,6 @@ fi
 m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that.
 AC_C_BIGENDIAN
 AC_C_INLINE
-AC_C_RESTRICT
 PGAC_PRINTF_ARCHETYPE
 AC_C_FLEXIBLE_ARRAY_MEMBER
 PGAC_C_SIGNED
@@ -1326,6 +1325,20 @@ AC_TYPE_LONG_LONG_INT
 
 PGAC_TYPE_LOCALE_T
 
+# MSVC doesn't cope well with defining restrict to __restrict, the
+# spelling it understands, because it conflicts with
+# __declspec(restrict). Therefore we define pg_restrict to the
+# appropriate definition, which presumably won't conflict.
+AC_C_RESTRICT
+if test "$ac_cv_c_restrict" = "no" ; then
+  pg_restrict=""
+else
+  pg_restrict="$ac_cv_c_restrict"
+fi
+AC_DEFINE_UNQUOTED([pg_restrict], [$pg_restrict],
+[Define to keyword to use for C99 restrict support, or to nothing if not
+supported])
+
 AC_CHECK_TYPES([struct cmsgcred], [], [],
 [#include <sys/socket.h>
 #include <sys/param.h>
index 2329669b085c281c138667fc202e8dac52919717..35cdee7b76fe76b4e5303922cf3199e31a8c22aa 100644 (file)
@@ -38,8 +38,8 @@ extern void pq_sendfloat8(StringInfo buf, float8 f);
  * Append a int8 to a StringInfo buffer, which already has enough space
  * preallocated.
  *
- * The use of restrict allows the compiler to optimize the code based on the
- * assumption that buf, buf->len, buf->data and *buf->data don't
+ * The use of pg_restrict allows the compiler to optimize the code based on
+ * the assumption that buf, buf->len, buf->data and *buf->data don't
  * overlap. Without the annotation buf->len etc cannot be kept in a register
  * over subsequent pq_writeint* calls.
  *
@@ -47,12 +47,12 @@ extern void pq_sendfloat8(StringInfo buf, float8 f);
  * overly picky and demanding a * before a restrict.
  */
 static inline void
-pq_writeint8(StringInfoData * restrict buf, int8 i)
+pq_writeint8(StringInfoData *pg_restrict buf, int8 i)
 {
        int8            ni = i;
 
        Assert(buf->len + sizeof(i) <= buf->maxlen);
-       memcpy((char *restrict) (buf->data + buf->len), &ni, sizeof(ni));
+       memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(ni));
        buf->len += sizeof(i);
 }
 
@@ -61,12 +61,12 @@ pq_writeint8(StringInfoData * restrict buf, int8 i)
  * preallocated.
  */
 static inline void
-pq_writeint16(StringInfoData * restrict buf, int16 i)
+pq_writeint16(StringInfoData *pg_restrict buf, int16 i)
 {
        int16           ni = pg_hton16(i);
 
        Assert(buf->len + sizeof(ni) <= buf->maxlen);
-       memcpy((char *restrict) (buf->data + buf->len), &ni, sizeof(i));
+       memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(i));
        buf->len += sizeof(i);
 }
 
@@ -75,12 +75,12 @@ pq_writeint16(StringInfoData * restrict buf, int16 i)
  * preallocated.
  */
 static inline void
-pq_writeint32(StringInfoData * restrict buf, int32 i)
+pq_writeint32(StringInfoData *pg_restrict buf, int32 i)
 {
        int32           ni = pg_hton32(i);
 
        Assert(buf->len + sizeof(i) <= buf->maxlen);
-       memcpy((char *restrict) (buf->data + buf->len), &ni, sizeof(i));
+       memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(i));
        buf->len += sizeof(i);
 }
 
@@ -89,12 +89,12 @@ pq_writeint32(StringInfoData * restrict buf, int32 i)
  * preallocated.
  */
 static inline void
-pq_writeint64(StringInfoData * restrict buf, int64 i)
+pq_writeint64(StringInfoData *pg_restrict buf, int64 i)
 {
        int64           ni = pg_hton64(i);
 
        Assert(buf->len + sizeof(i) <= buf->maxlen);
-       memcpy((char *restrict) (buf->data + buf->len), &ni, sizeof(i));
+       memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(i));
        buf->len += sizeof(i);
 }
 
@@ -109,7 +109,7 @@ pq_writeint64(StringInfoData * restrict buf, int64 i)
  * sent to the frontend.
  */
 static inline void
-pq_writestring(StringInfoData * restrict buf, const char *restrict str)
+pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str)
 {
        int                     slen = strlen(str);
        char       *p;
@@ -120,7 +120,7 @@ pq_writestring(StringInfoData * restrict buf, const char *restrict str)
 
        Assert(buf->len + slen + 1 <= buf->maxlen);
 
-       memcpy(((char *restrict) buf->data + buf->len), p, slen + 1);
+       memcpy(((char *pg_restrict) buf->data + buf->len), p, slen + 1);
        buf->len += slen + 1;
 
        if (p != str)
index 80ee37dd622636fa6ed45a7d422278c83c65a963..cfdcc5ac62fc4ee4f56d07218b8fdb9ff1793cab 100644 (file)
    if such a type exists, and if the system does not define it. */
 #undef intptr_t
 
+/* Define to keyword to use for C99 restrict support, or to nothing if not
+   supported */
+#undef pg_restrict
+
 /* Define to the equivalent of the C99 'restrict' keyword, or to
    nothing if this is not supported.  Do not define if restrict is
    supported directly.  */
index 81604de7f92469c07db648b765a35ec180b82539..ab9b941e89df5d0a427ca450a5f22c0211a2a86f 100644 (file)
 #define inline __inline
 #endif
 
-/* Define to the equivalent of the C99 'restrict' keyword, or to
-   nothing if this is not supported.  Do not define if restrict is
-   supported directly.  */
-/* Visual Studio 2008 and upwards */
+/* Define to keyword to use for C99 restrict support, or to nothing if this is
+   not supported */
+/* Works for C and C++ in Visual Studio 2008 and upwards */
 #if (_MSC_VER >= 1500)
-/* works for C and C++ in msvc */
-/*
- * Temporary attempt at a workaround for stdlib.h's use of
- * declspec(restrict), conflicting with below define.
- */
-#include <stdlib.h>
-#define restrict __restrict
+#define pg_restrict __restrict
 #else
-#define restrict
+#define pg_restrict
 #endif
 
+/* Define to the equivalent of the C99 'restrict' keyword, or to
+   nothing if this is not supported.  Do not define if restrict is
+   supported directly.  */
+/* not defined, because it'd conflict with __declspec(restrict) */
+
 /* Define to empty if the C compiler does not understand signed types. */
 /* #undef signed */