Skip to content

Commit de447bb

Browse files
committed
Suppress warning about stack_base_ptr with late-model GCC.
GCC 12 complains that set_stack_base is storing the address of a local variable in a long-lived pointer. This is an entirely reasonable warning (indeed, it just helped us find a bug); but that behavior is intentional here. We can work around it by using __builtin_frame_address(0) instead of a specific local variable; that produces an address a dozen or so bytes different, in my testing, but we don't care about such a small difference. Maybe someday a compiler lacking that function will start to issue a similar warning, but we'll worry about that when it happens. Patch by me, per a suggestion from Andres Freund. Back-patch to v12, which is as far back as the patch will go without some pain. (Recently-established project policy would permit a back-patch as far as 9.2, but I'm disinclined to expend the work until GCC 12 is much more widespread.) Discussion: https://postgr.es/m/[email protected]
1 parent f927a6e commit de447bb

File tree

8 files changed

+89
-13
lines changed

8 files changed

+89
-13
lines changed

config/c-compiler.m4

+22
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,28 @@ fi])# PGAC_CHECK_BUILTIN_FUNC
381381

382382

383383

384+
# PGAC_CHECK_BUILTIN_FUNC_PTR
385+
# -----------------------
386+
# Like PGAC_CHECK_BUILTIN_FUNC, except that the function is assumed to
387+
# return a pointer type, and the argument(s) should be given literally.
388+
# This handles some cases that PGAC_CHECK_BUILTIN_FUNC doesn't.
389+
AC_DEFUN([PGAC_CHECK_BUILTIN_FUNC_PTR],
390+
[AC_CACHE_CHECK(for $1, pgac_cv$1,
391+
[AC_LINK_IFELSE([AC_LANG_PROGRAM([
392+
void *
393+
call$1(void)
394+
{
395+
return $1($2);
396+
}], [])],
397+
[pgac_cv$1=yes],
398+
[pgac_cv$1=no])])
399+
if test x"${pgac_cv$1}" = xyes ; then
400+
AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE$1]), 1,
401+
[Define to 1 if your compiler understands $1.])
402+
fi])# PGAC_CHECK_BUILTIN_FUNC_PTR
403+
404+
405+
384406
# PGAC_PROG_VARCC_VARFLAGS_OPT
385407
# ----------------------------
386408
# Given a compiler, variable name and a string, check if the compiler

configure

+40
Original file line numberDiff line numberDiff line change
@@ -15944,6 +15944,46 @@ cat >>confdefs.h <<_ACEOF
1594415944
#define HAVE__BUILTIN_POPCOUNT 1
1594515945
_ACEOF
1594615946

15947+
fi
15948+
# __builtin_frame_address may draw a diagnostic for non-constant argument,
15949+
# so it needs a different test function.
15950+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_frame_address" >&5
15951+
$as_echo_n "checking for __builtin_frame_address... " >&6; }
15952+
if ${pgac_cv__builtin_frame_address+:} false; then :
15953+
$as_echo_n "(cached) " >&6
15954+
else
15955+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
15956+
/* end confdefs.h. */
15957+
15958+
void *
15959+
call__builtin_frame_address(void)
15960+
{
15961+
return __builtin_frame_address(0);
15962+
}
15963+
int
15964+
main ()
15965+
{
15966+
15967+
;
15968+
return 0;
15969+
}
15970+
_ACEOF
15971+
if ac_fn_c_try_link "$LINENO"; then :
15972+
pgac_cv__builtin_frame_address=yes
15973+
else
15974+
pgac_cv__builtin_frame_address=no
15975+
fi
15976+
rm -f core conftest.err conftest.$ac_objext \
15977+
conftest$ac_exeext conftest.$ac_ext
15978+
fi
15979+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_frame_address" >&5
15980+
$as_echo "$pgac_cv__builtin_frame_address" >&6; }
15981+
if test x"${pgac_cv__builtin_frame_address}" = xyes ; then
15982+
15983+
cat >>confdefs.h <<_ACEOF
15984+
#define HAVE__BUILTIN_FRAME_ADDRESS 1
15985+
_ACEOF
15986+
1594715987
fi
1594815988

1594915989
# We require 64-bit fseeko() to be available, but run this check anyway

configure.ac

+3
Original file line numberDiff line numberDiff line change
@@ -1776,6 +1776,9 @@ PGAC_CHECK_BUILTIN_FUNC([__builtin_bswap64], [long int x])
17761776
PGAC_CHECK_BUILTIN_FUNC([__builtin_clz], [unsigned int x])
17771777
PGAC_CHECK_BUILTIN_FUNC([__builtin_ctz], [unsigned int x])
17781778
PGAC_CHECK_BUILTIN_FUNC([__builtin_popcount], [unsigned int x])
1779+
# __builtin_frame_address may draw a diagnostic for non-constant argument,
1780+
# so it needs a different test function.
1781+
PGAC_CHECK_BUILTIN_FUNC_PTR([__builtin_frame_address], [0])
17791782

17801783
# We require 64-bit fseeko() to be available, but run this check anyway
17811784
# in case it finds that _LARGEFILE_SOURCE has to be #define'd for that.

src/backend/postmaster/postmaster.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ PostmasterMain(int argc, char *argv[])
10831083
/*
10841084
* Set reference point for stack-depth checking.
10851085
*/
1086-
set_stack_base();
1086+
(void) set_stack_base();
10871087

10881088
/*
10891089
* Initialize pipe (or process handle on Windows) that allows children to

src/backend/tcop/postgres.c

+14-6
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,15 @@ static long max_stack_depth_bytes = 100 * 1024L;
129129

130130
/*
131131
* Stack base pointer -- initialized by PostmasterMain and inherited by
132-
* subprocesses. This is not static because old versions of PL/Java modify
133-
* it directly. Newer versions use set_stack_base(), but we want to stay
134-
* binary-compatible for the time being.
132+
* subprocesses (but see also InitPostmasterChild).
135133
*/
136-
char *stack_base_ptr = NULL;
134+
static char *stack_base_ptr = NULL;
137135

138136
/*
139137
* On IA64 we also have to remember the register stack base.
140138
*/
141139
#if defined(__ia64__) || defined(__ia64)
142-
char *register_stack_base_ptr = NULL;
140+
static char *register_stack_base_ptr = NULL;
143141
#endif
144142

145143
/*
@@ -3416,7 +3414,9 @@ ia64_get_bsp(void)
34163414
pg_stack_base_t
34173415
set_stack_base(void)
34183416
{
3417+
#ifndef HAVE__BUILTIN_FRAME_ADDRESS
34193418
char stack_base;
3419+
#endif
34203420
pg_stack_base_t old;
34213421

34223422
#if defined(__ia64__) || defined(__ia64)
@@ -3426,8 +3426,16 @@ set_stack_base(void)
34263426
old = stack_base_ptr;
34273427
#endif
34283428

3429-
/* Set up reference point for stack depth checking */
3429+
/*
3430+
* Set up reference point for stack depth checking. On recent gcc we use
3431+
* __builtin_frame_address() to avoid a warning about storing a local
3432+
* variable's address in a long-lived variable.
3433+
*/
3434+
#ifdef HAVE__BUILTIN_FRAME_ADDRESS
3435+
stack_base_ptr = __builtin_frame_address(0);
3436+
#else
34303437
stack_base_ptr = &stack_base;
3438+
#endif
34313439
#if defined(__ia64__) || defined(__ia64)
34323440
register_stack_base_ptr = ia64_get_bsp();
34333441
#endif

src/backend/utils/init/miscinit.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,12 @@ InitPostmasterChild(void)
106106
#endif
107107

108108
/*
109-
* Set reference point for stack-depth checking. We re-do that even in the
110-
* !EXEC_BACKEND case, because there are some edge cases where processes
111-
* are started with an alternative stack (e.g. starting bgworkers when
112-
* running postgres using the rr debugger, as bgworkers are launched from
113-
* signal handlers).
109+
* Set reference point for stack-depth checking. This might seem
110+
* redundant in !EXEC_BACKEND builds; but it's not because the postmaster
111+
* launches its children from signal handlers, so we might be running on
112+
* an alternative stack.
114113
*/
115-
set_stack_base();
114+
(void) set_stack_base();
116115

117116
InitProcessGlobals();
118117

src/include/pg_config.h.in

+3
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,9 @@
739739
/* Define to 1 if your compiler understands __builtin_ctz. */
740740
#undef HAVE__BUILTIN_CTZ
741741

742+
/* Define to 1 if your compiler understands __builtin_frame_address. */
743+
#undef HAVE__BUILTIN_FRAME_ADDRESS
744+
742745
/* Define to 1 if your compiler understands __builtin_$op_overflow. */
743746
#undef HAVE__BUILTIN_OP_OVERFLOW
744747

src/tools/msvc/Solution.pm

+1
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ sub GenerateFiles
439439
HAVE__BUILTIN_CLZ => undef,
440440
HAVE__BUILTIN_CONSTANT_P => undef,
441441
HAVE__BUILTIN_CTZ => undef,
442+
HAVE__BUILTIN_FRAME_ADDRESS => undef,
442443
HAVE__BUILTIN_OP_OVERFLOW => undef,
443444
HAVE__BUILTIN_POPCOUNT => undef,
444445
HAVE__BUILTIN_TYPES_COMPATIBLE_P => undef,

0 commit comments

Comments
 (0)