From: | Andres Freund <andres(at)anarazel(dot)de> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
Subject: | Re: gcc 15 "array subscript 0" warning at level -O3 |
Date: | 2025-04-25 19:58:29 |
Message-ID: | 3prdb6hkep3duglhsujrn52bkvnlkvhc54fzvph2emrsm4vodl@77yy6j4hkemb |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi,
On 2025-04-25 13:37:15 -0400, Tom Lane wrote:
> Whilst poking at Erik Rijkers' nearby report, I found that
> Fedora 42's gcc 15.0.1 will produce this complaint if you
> select optimization level -O3:
>
> In file included from ../../../../src/include/access/htup_details.h:22,
> from pl_exec.c:21:
> In function 'assign_simple_var',
> inlined from 'exec_set_found' at pl_exec.c:8609:2:
> ../../../../src/include/varatt.h:230:36: warning: array subscript 0 is outside array bounds of 'char[0]' [-Warray-bounds=]
> 230 | (((varattrib_1b_e *) (PTR))->va_tag)
> | ^
> ../../../../src/include/varatt.h:94:12: note: in definition of macro 'VARTAG_IS_EXPANDED'
> 94 | (((tag) & ~1) == VARTAG_EXPANDED_RO)
> | ^~~
> ../../../../src/include/varatt.h:284:57: note: in expansion of macro 'VARTAG_1B_E'
> 284 | #define VARTAG_EXTERNAL(PTR) VARTAG_1B_E(PTR)
> | ^~~~~~~~~~~
> ../../../../src/include/varatt.h:301:57: note: in expansion of macro 'VARTAG_EXTERNAL'
> 301 | (VARATT_IS_EXTERNAL(PTR) && !VARTAG_IS_EXPANDED(VARTAG_EXTERNAL(PTR)))
> | ^~~~~~~~~~~~~~~
> pl_exec.c:8797:17: note: in expansion of macro 'VARATT_IS_EXTERNAL_NON_EXPANDED'
> 8797 | VARATT_IS_EXTERNAL_NON_EXPANDED(DatumGetPointer(newvalue)))
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> In function 'exec_set_found':
> cc1: note: source object is likely at address zero
FWIW, I've seen this even before GCC 15.
> Buildfarm member serinus has been producing the identical warning for
> some time. I'd been ignoring that because it runs "experimental gcc",
> but I guess the experiment has leaked out to production distros.
>
> What seems to be happening here is that after inlining
> assign_simple_var into exec_set_found, the compiler decides that
> "newvalue" might be zero (since it's a BoolGetDatum result),
> and then it warns -- in a rather strange way -- about the
> potential null dereference.
I don't think it actually is complaining about a null dereference - it thinks
we're interpreting a boolean as a pointer (for which it obviously is not wide
enough)
> The dereference is not reachable
> because of the preceding "var->datatype->typlen == -1" check,
> but that's not stopping the optimizer from bitching.
> I experimented with modifying exec_set_found thus:
>
> var = (PLpgSQL_var *) (estate->datums[estate->found_varno]);
> + Assert(var->datatype->typlen == 1);
> assign_simple_var(estate, var, BoolGetDatum(state), false, false);
>
> which should be OK since we're expecting the "found" variable to
> be boolean. That does silence the warning, but of course only
> in --enable-cassert builds.
One way to address this is outlined here:
https://postgr.es/m/20230316172818.x6375uvheom3ibt2%40awork3.anarazel.de
https://postgr.es/m/20240207203138.sknifhlppdtgtxnk%40awork3.anarazel.de
I've been wondering about adding wrapping something like that in a
pg_assume(expr) or such.
Greetings,
Andres Freund
From | Date | Subject | |
---|---|---|---|
Next Message | Jacob Champion | 2025-04-25 20:31:16 | Re: [PoC] Federated Authn/z with OAUTHBEARER |
Previous Message | Andres Freund | 2025-04-25 19:35:06 | Re: Back-patch of: avoid multiple hard links to same WAL file after a crash |