Improve pg_list.h's linitial(), lsecond() and co macros
authorDavid Rowley <drowley@postgresql.org>
Mon, 28 Sep 2020 01:47:19 +0000 (14:47 +1300)
committerDavid Rowley <drowley@postgresql.org>
Mon, 28 Sep 2020 01:47:19 +0000 (14:47 +1300)
commitcc99baa43e0ed83ac18fcbde31f2ab7274eb26cf
tree801c12a74453416439ca082174d2252261c4e3b7
parent4d29e6dbd0bb6d8c3a48d0f3c7d65dc1def1b07e
Improve pg_list.h's linitial(), lsecond() and co macros

Prior to this commit, the linitial(), lsecond(), lthird(), lfourth()
macros and their int and Oid list cousins would call their corresponding
inlined function to fetch the cell of interest.  Those inline functions
were kind enough to return NULL if the particular cell did not exist.
Unfortunately, the care that these functions took was of no relevance to
the calling macros as they proceeded to directly dereference the returned
value without any regard to whether that value was NULL or not.  If it had
been, we'd have segfaulted.

Of course, the fact that we would have segfaulted on misuse of these
macros just goes to prove that nobody is relying on the empty or list too
small checks.  So here we just get rid of those checks completely.

The existing inline functions have been left alone as someone may be using
those directly.  We just replace the call within each macro to use
list_nth_cell().

For the llast*() case we require a new list_last_cell() inline function to
get away from the multiple evaluation hazard that we'd get if we fetched
->length on the macro's parameter.

Author: David Rowley
Reviewed-by: Tom Lane
Discussion: https://postgr.es/m/CAApHDvpo1zj9KhEpU2cCRZfSM3Q6XGdhzuAS2v79PH7WJBkYVA@mail.gmail.com
src/include/nodes/pg_list.h