summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2018-05-19 02:42:10 +0000
committerTom Lane2018-05-19 02:42:10 +0000
commite9f475f991fb87afb39930a0aeee51fcfeeea042 (patch)
treeede6e5cd0078be4c926c4b6933bd54a8670bab18
parentd73857d5719e10bc7ed8aabdf66daf03b1db7ddd (diff)
Arrange to supply declarations for strtoll/strtoull if needed.
Buildfarm member dromedary is still unhappy about the recently-added ecpg "long long" tests. The reason turns out to be that it includes "-ansi" in its CFLAGS, and in their infinite wisdom Apple have decided to hide the declarations of strtoll/strtoull in C89-compliant builds. (I find it pretty curious that they hide those function declarations when you can nonetheless declare a "long long" variable, but anyway that is their behavior, both on dromedary's obsolete macOS version and the newest and shiniest.) As a result, gcc assumes these functions return "int", leading naturally to wrong results. (Looking at dromedary's past build results, it's evident that this problem also breaks pg_strtouint64() on 32-bit platforms; but we evidently have no regression tests that exercise that function with values above 32 bits.) To fix, supply declarations for these functions when the platform provides the functions but not the declarations, using the same type of mechanism as we use for some other similar cases. Discussion: https://postgr.es/m/[email protected]
-rwxr-xr-xconfigure137
-rw-r--r--configure.in2
-rw-r--r--src/include/c.h8
-rw-r--r--src/include/pg_config.h.in8
-rw-r--r--src/include/pg_config.h.win328
5 files changed, 163 insertions, 0 deletions
diff --git a/configure b/configure
index 69a3c1c0db..48440ea3b5 100755
--- a/configure
+++ b/configure
@@ -23423,6 +23423,143 @@ _ACEOF
fi
done
+# strto[u]ll may exist but not be declared
+{ $as_echo "$as_me:$LINENO: checking whether strtoll is declared" >&5
+$as_echo_n "checking whether strtoll is declared... " >&6; }
+if test "${ac_cv_have_decl_strtoll+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. */
+$ac_includes_default
+int
+main ()
+{
+#ifndef strtoll
+ (void) strtoll;
+#endif
+
+ ;
+ 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
+ ac_cv_have_decl_strtoll=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_have_decl_strtoll=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl_strtoll" >&5
+$as_echo "$ac_cv_have_decl_strtoll" >&6; }
+if test "x$ac_cv_have_decl_strtoll" = x""yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOLL 1
+_ACEOF
+
+
+else
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOLL 0
+_ACEOF
+
+
+fi
+{ $as_echo "$as_me:$LINENO: checking whether strtoull is declared" >&5
+$as_echo_n "checking whether strtoull is declared... " >&6; }
+if test "${ac_cv_have_decl_strtoull+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. */
+$ac_includes_default
+int
+main ()
+{
+#ifndef strtoull
+ (void) strtoull;
+#endif
+
+ ;
+ 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
+ ac_cv_have_decl_strtoull=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_have_decl_strtoull=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl_strtoull" >&5
+$as_echo "$ac_cv_have_decl_strtoull" >&6; }
+if test "x$ac_cv_have_decl_strtoull" = x""yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOULL 1
+_ACEOF
+
+
+else
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOULL 0
+_ACEOF
+
+
+fi
+
+
{ $as_echo "$as_me:$LINENO: checking for builtin locking functions" >&5
$as_echo_n "checking for builtin locking functions... " >&6; }
diff --git a/configure.in b/configure.in
index 6c4b56667b..7f11500e4f 100644
--- a/configure.in
+++ b/configure.in
@@ -1509,6 +1509,8 @@ fi
AC_CHECK_FUNCS([strtoll strtoq], [break])
AC_CHECK_FUNCS([strtoull strtouq], [break])
+# strto[u]ll may exist but not be declared
+AC_CHECK_DECLS([strtoll, strtoull])
AC_CACHE_CHECK([for builtin locking functions], pgac_cv_gcc_int_atomics,
[AC_TRY_LINK([],
diff --git a/src/include/c.h b/src/include/c.h
index 2d1576016a..6dd2581f11 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -951,6 +951,14 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
extern int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
#endif
+#if defined(HAVE_LONG_LONG_INT) && defined(HAVE_STRTOLL) && !HAVE_DECL_STRTOLL
+extern long long strtoll(const char *str, char **endptr, int base);
+#endif
+
+#if defined(HAVE_LONG_LONG_INT) && defined(HAVE_STRTOULL) && !HAVE_DECL_STRTOULL
+extern unsigned long long strtoull(const char *str, char **endptr, int base);
+#endif
+
#if !defined(HAVE_MEMMOVE) && !defined(memmove)
#define memmove(d, s, c) bcopy(s, d, c)
#endif
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index c1b7e299b9..c5885df543 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -135,6 +135,14 @@
don't. */
#undef HAVE_DECL_STRLCPY
+/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
+ don't. */
+#undef HAVE_DECL_STRTOLL
+
+/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
+ don't. */
+#undef HAVE_DECL_STRTOULL
+
/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
don't. */
#undef HAVE_DECL_SYS_SIGLIST
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 60a5413d20..a678d5a5b0 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -96,6 +96,14 @@
don't. */
#define HAVE_DECL_SNPRINTF 1
+/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRTOLL 1
+
+/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRTOULL 1
+
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
don't. */
#define HAVE_DECL_VSNPRINTF 1