Use C99 restrict via pg_restrict, rather than restrict directly.

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 36b4b91ba0.

Author: Andres Freund
Discussion: https://postgr.es/m/2656.1507830907@sss.pgh.pa.us
This commit is contained in:
Andres Freund 2017-10-12 15:25:38 -07:00
parent 1c497fa72d
commit 91d5f1a4a3
5 changed files with 101 additions and 71 deletions

107
configure vendored
View File

@ -11545,52 +11545,6 @@ _ACEOF
;; ;;
esac 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 "$as_me:${as_lineno-$LINENO}: checking for printf format archetype" >&5
$as_echo_n "checking for printf format archetype... " >&6; } $as_echo_n "checking for printf format archetype... " >&6; }
if ${pgac_cv_printf_archetype+:} false; then : if ${pgac_cv_printf_archetype+:} false; then :
@ -12508,6 +12462,67 @@ $as_echo "#define LOCALE_T_IN_XLOCALE 1" >>confdefs.h
fi 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> ac_fn_c_check_type "$LINENO" "struct cmsgcred" "ac_cv_type_struct_cmsgcred" "#include <sys/socket.h>
#include <sys/param.h> #include <sys/param.h>
#ifdef HAVE_SYS_UCRED_H #ifdef HAVE_SYS_UCRED_H

View File

@ -1299,7 +1299,6 @@ fi
m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that. m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that.
AC_C_BIGENDIAN AC_C_BIGENDIAN
AC_C_INLINE AC_C_INLINE
AC_C_RESTRICT
PGAC_PRINTF_ARCHETYPE PGAC_PRINTF_ARCHETYPE
AC_C_FLEXIBLE_ARRAY_MEMBER AC_C_FLEXIBLE_ARRAY_MEMBER
PGAC_C_SIGNED PGAC_C_SIGNED
@ -1326,6 +1325,20 @@ AC_TYPE_LONG_LONG_INT
PGAC_TYPE_LOCALE_T 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], [], [], AC_CHECK_TYPES([struct cmsgcred], [], [],
[#include <sys/socket.h> [#include <sys/socket.h>
#include <sys/param.h> #include <sys/param.h>

View 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 * Append a int8 to a StringInfo buffer, which already has enough space
* preallocated. * preallocated.
* *
* The use of restrict allows the compiler to optimize the code based on the * The use of pg_restrict allows the compiler to optimize the code based on
* assumption that buf, buf->len, buf->data and *buf->data don't * 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 * overlap. Without the annotation buf->len etc cannot be kept in a register
* over subsequent pq_writeint* calls. * 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. * overly picky and demanding a * before a restrict.
*/ */
static inline void static inline void
pq_writeint8(StringInfoData * restrict buf, int8 i) pq_writeint8(StringInfoData *pg_restrict buf, int8 i)
{ {
int8 ni = i; int8 ni = i;
Assert(buf->len + sizeof(i) <= buf->maxlen); 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); buf->len += sizeof(i);
} }
@ -61,12 +61,12 @@ pq_writeint8(StringInfoData * restrict buf, int8 i)
* preallocated. * preallocated.
*/ */
static inline void static inline void
pq_writeint16(StringInfoData * restrict buf, int16 i) pq_writeint16(StringInfoData *pg_restrict buf, int16 i)
{ {
int16 ni = pg_hton16(i); int16 ni = pg_hton16(i);
Assert(buf->len + sizeof(ni) <= buf->maxlen); 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); buf->len += sizeof(i);
} }
@ -75,12 +75,12 @@ pq_writeint16(StringInfoData * restrict buf, int16 i)
* preallocated. * preallocated.
*/ */
static inline void static inline void
pq_writeint32(StringInfoData * restrict buf, int32 i) pq_writeint32(StringInfoData *pg_restrict buf, int32 i)
{ {
int32 ni = pg_hton32(i); int32 ni = pg_hton32(i);
Assert(buf->len + sizeof(i) <= buf->maxlen); 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); buf->len += sizeof(i);
} }
@ -89,12 +89,12 @@ pq_writeint32(StringInfoData * restrict buf, int32 i)
* preallocated. * preallocated.
*/ */
static inline void static inline void
pq_writeint64(StringInfoData * restrict buf, int64 i) pq_writeint64(StringInfoData *pg_restrict buf, int64 i)
{ {
int64 ni = pg_hton64(i); int64 ni = pg_hton64(i);
Assert(buf->len + sizeof(i) <= buf->maxlen); 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); buf->len += sizeof(i);
} }
@ -109,7 +109,7 @@ pq_writeint64(StringInfoData * restrict buf, int64 i)
* sent to the frontend. * sent to the frontend.
*/ */
static inline void 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); int slen = strlen(str);
char *p; char *p;
@ -120,7 +120,7 @@ pq_writestring(StringInfoData * restrict buf, const char *restrict str)
Assert(buf->len + slen + 1 <= buf->maxlen); 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; buf->len += slen + 1;
if (p != str) if (p != str)

View File

@ -923,6 +923,10 @@
if such a type exists, and if the system does not define it. */ if such a type exists, and if the system does not define it. */
#undef intptr_t #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 /* Define to the equivalent of the C99 'restrict' keyword, or to
nothing if this is not supported. Do not define if restrict is nothing if this is not supported. Do not define if restrict is
supported directly. */ supported directly. */

View File

@ -681,21 +681,19 @@
#define inline __inline #define inline __inline
#endif #endif
/* 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)
#define pg_restrict __restrict
#else
#define pg_restrict
#endif
/* Define to the equivalent of the C99 'restrict' keyword, or to /* Define to the equivalent of the C99 'restrict' keyword, or to
nothing if this is not supported. Do not define if restrict is nothing if this is not supported. Do not define if restrict is
supported directly. */ supported directly. */
/* Visual Studio 2008 and upwards */ /* not defined, because it'd conflict with __declspec(restrict) */
#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
#else
#define restrict
#endif
/* Define to empty if the C compiler does not understand signed types. */ /* Define to empty if the C compiler does not understand signed types. */
/* #undef signed */ /* #undef signed */