Thread: Re: PG 17.2 compilation fails with -std=c11 on mac

Re: PG 17.2 compilation fails with -std=c11 on mac

From
Tom Lane
Date:
Lakshmi Narayana Velayudam <dev.narayana.v@gmail.com> writes:
> When I trying to compiling postgres 17.2 with -std=c11 I am getting the
> below error on mac

> explicit_bzero.c:22:9: error: call to undeclared function 'memset_s'; ISO
> C99 and later do not support implicit function declarations
> [-Wimplicit-function-declaration]

Yeah, I can reproduce that.  After some digging, I see that
the problem is explained by "man memset_s":

SYNOPSIS

     #define __STDC_WANT_LIB_EXT1__ 1

     #include <string.h>

     errno_t
     memset_s(void *s, rsize_t smax, int c, rsize_t n);

We lack that #define, which results in <string.h> not supplying
the declaration.  AFAICT the requirement for this is in the C11
standard, this is not just Apple doing something weird.

(I did not figure out how come the code compiles without -std=c11.)

Aside from this compilation error, we're probably failing to use
memset_s on some platforms where it's available, for lack of
the #define in our configure/meson probes.  I know how to fix
that in configure, but I'm less clear on how nonstandard probes
work in meson --- any help there?

            regards, tom lane



Re: PG 17.2 compilation fails with -std=c11 on mac

From
Tom Lane
Date:
I wrote:
> We lack that #define, which results in <string.h> not supplying
> the declaration.  AFAICT the requirement for this is in the C11
> standard, this is not just Apple doing something weird.
> Aside from this compilation error, we're probably failing to use
> memset_s on some platforms where it's available, for lack of
> the #define in our configure/meson probes.  I know how to fix
> that in configure, but I'm less clear on how nonstandard probes
> work in meson --- any help there?

Here's a lightly-tested fix for that (against HEAD, but it likely
works on v17 too).

            regards, tom lane

diff --git a/configure b/configure
index 275c67ee67c..4f15347cc95 100755
--- a/configure
+++ b/configure
@@ -15616,7 +15616,7 @@ fi
 LIBS_including_readline="$LIBS"
 LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`

-for ac_func in backtrace_symbols copyfile copy_file_range elf_aux_info getauxval getifaddrs getpeerucred inet_pton
kqueuelocaleconv_l mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast
strsignalsyncfs sync_file_range uselocale wcstombs_l 
+for ac_func in backtrace_symbols copyfile copy_file_range elf_aux_info getauxval getifaddrs getpeerucred inet_pton
kqueuelocaleconv_l mbstowcs_l posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strsignal
syncfssync_file_range uselocale wcstombs_l 
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -16192,6 +16192,19 @@ cat >>confdefs.h <<_ACEOF
 #define HAVE_DECL_STRCHRNUL $ac_have_decl
 _ACEOF

+ac_fn_c_check_decl "$LINENO" "memset_s" "ac_cv_have_decl_memset_s" "#define __STDC_WANT_LIB_EXT1__ 1
+#include <string.h>
+"
+if test "x$ac_cv_have_decl_memset_s" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_MEMSET_S $ac_have_decl
+_ACEOF
+

 # This is probably only present on macOS, but may as well check always
 ac_fn_c_check_decl "$LINENO" "F_FULLFSYNC" "ac_cv_have_decl_F_FULLFSYNC" "#include <fcntl.h>
diff --git a/configure.ac b/configure.ac
index 7ea91d56adb..4b8335dc613 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1792,7 +1792,6 @@ AC_CHECK_FUNCS(m4_normalize([
     kqueue
     localeconv_l
     mbstowcs_l
-    memset_s
     posix_fallocate
     ppoll
     pthread_is_threaded_np
@@ -1838,6 +1837,8 @@ AC_CHECK_DECLS([strlcat, strlcpy, strnlen, strsep, timingsafe_bcmp])
 AC_CHECK_DECLS([preadv], [], [], [#include <sys/uio.h>])
 AC_CHECK_DECLS([pwritev], [], [], [#include <sys/uio.h>])
 AC_CHECK_DECLS([strchrnul], [], [], [#include <string.h>])
+AC_CHECK_DECLS([memset_s], [], [], [#define __STDC_WANT_LIB_EXT1__ 1
+#include <string.h>])

 # This is probably only present on macOS, but may as well check always
 AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
diff --git a/meson.build b/meson.build
index 12de5e80c31..d142e3e408b 100644
--- a/meson.build
+++ b/meson.build
@@ -2654,6 +2654,7 @@ decl_checks += [
   ['preadv', 'sys/uio.h'],
   ['pwritev', 'sys/uio.h'],
   ['strchrnul', 'string.h'],
+  ['memset_s', 'string.h', '#define __STDC_WANT_LIB_EXT1__ 1'],
 ]

 # Check presence of some optional LLVM functions.
@@ -2667,21 +2668,23 @@ endif
 foreach c : decl_checks
   func = c.get(0)
   header = c.get(1)
-  args = c.get(2, {})
+  prologue = c.get(2, '')
+  args = c.get(3, {})
   varname = 'HAVE_DECL_' + func.underscorify().to_upper()

   found = cc.compiles('''
-#include <@0@>
+@0@
+#include <@1@>

 int main()
 {
-#ifndef @1@
-    (void) @1@;
+#ifndef @2@
+    (void) @2@;
 #endif

 return 0;
 }
-'''.format(header, func),
+'''.format(prologue, header, func),
     name: 'test whether @0@ is declared'.format(func),
     # need to add cflags_warn to get at least
     # -Werror=unguarded-availability-new if applicable
@@ -2880,7 +2883,6 @@ func_checks = [
   ['kqueue'],
   ['localeconv_l'],
   ['mbstowcs_l'],
-  ['memset_s'],
   ['mkdtemp'],
   ['posix_fadvise'],
   ['posix_fallocate'],
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index c3cc9fa856d..726a7c1be1f 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -91,6 +91,10 @@
    `LLVMCreatePerfJITEventListener', and to 0 if you don't. */
 #undef HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER

+/* Define to 1 if you have the declaration of `memset_s', and to 0 if you
+   don't. */
+#undef HAVE_DECL_MEMSET_S
+
 /* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you
    don't. */
 #undef HAVE_DECL_POSIX_FADVISE
@@ -291,9 +295,6 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H

-/* Define to 1 if you have the `memset_s' function. */
-#undef HAVE_MEMSET_S
-
 /* Define to 1 if you have the `mkdtemp' function. */
 #undef HAVE_MKDTEMP

diff --git a/src/port/explicit_bzero.c b/src/port/explicit_bzero.c
index 1d37b119bab..358a692f357 100644
--- a/src/port/explicit_bzero.c
+++ b/src/port/explicit_bzero.c
@@ -12,9 +12,11 @@
  *-------------------------------------------------------------------------
  */

+#define __STDC_WANT_LIB_EXT1__ 1        /* needed to access memset_s() */
+
 #include "c.h"

-#if defined(HAVE_MEMSET_S)
+#if HAVE_DECL_MEMSET_S

 void
 explicit_bzero(void *buf, size_t len)

Re: PG 17.2 compilation fails with -std=c11 on mac

From
Tom Lane
Date:
I wrote:
> Here's a lightly-tested fix for that (against HEAD, but it likely
> works on v17 too).

Pushed that.  It did require adjustments for the back branches.

For the archives' sake: I checked which buildfarm animals report
having memset_s().  They are

 anaconda      | 2025-05-18 08:22:35 | checking for memset_s... (cached) yes
 billbug       | 2025-05-18 15:00:02 | checking for memset_s... (cached) yes
 conchuela     | 2025-05-18 08:20:25 | checking for memset_s... (cached) yes
 dikkop        | 2025-05-18 09:05:01 | checking for memset_s... (cached) yes
 hake          | 2025-05-18 08:20:04 | checking for memset_s... (cached) yes
 indri         | 2025-05-18 08:24:31 | checking for memset_s... (cached) yes
 loach         | 2025-05-18 08:25:12 | checking for memset_s... (cached) yes
 longfin       | 2025-05-18 08:12:01 | checking for memset_s... (cached) yes
 margay        | 2025-05-18 16:00:03 | checking for memset_s... (cached) yes
 opaleye       | 2025-03-12 03:06:14 | checking for memset_s... (cached) yes
 pollock       | 2025-05-17 06:17:24 | checking for memset_s... (cached) yes
 sevengill     | 2025-04-29 03:51:04 | Checking for function "memset_s" : YES 
 sifaka        | 2025-05-18 08:11:57 | checking for memset_s... (cached) yes

These are all macOS, FreeBSD, Solaris, or derivatives.  However,
FreeBSD and Solaris also have explicit_bzero().  That means we don't
need to build explicit_bzero.c on those platforms, and thus macOS is
the only platform where we are attempting to use memset_s().  So we
don't actually have any evidence whether there's an issue on anything
besides macOS.  The FreeBSD man page for memset_s() does mention
__STDC_WANT_LIB_EXT1__ [1], so it's possible our code would have
failed there too, if we were reaching it.  I didn't check Solaris.

            regards, tom lane

[1] https://man.freebsd.org/cgi/man.cgi?query=memset_s&sektion=3