[tz] [PROPOSED 1/7] Avoid undefined behavior if no Link lines

Steve Summit scs at eskimo.com
Wed Oct 26 14:09:57 UTC 2022


Paul Eggert wrote:
> It's not just an academic point. Without the patch, 'zic /dev/null' 
> dumps core on Fedora 36 x86-64...
> The core dump occurred because GCC translates this:
>    qsort(links, nlinks, sizeof *links, qsort_linkcmp);
> as if it were this:
>
>    if (nlinks == 0)
>      __builtin_trap();
>    qsort(links, nlinks, sizeof *links, qsort_linkcmp);

This is an astonishing result.  It's hard to imagine it's
worthwhile for gcc to perform this "optimization".

There are some decent resident language lawyers over on Stack
Overflow these days.  I asked this question there, and several
posters have cited language from C17 which seems (like the Posix
language others have mentioned here) to directly contraindicate
gcc's behavior:

	These utilities [qsort, bsearch] make use of a comparison
	function to search or sort arrays of unspecified type.
	Where an argument declared as size_t nmemb specifies the
	length of the array for a function, nmemb can have the
	value zero on a call to that function; the comparison
	function is not called, a search finds no matching
	element, and sorting performs no rearrangement.  Pointer
	arguments on such a call shall still have valid values,
	as described in 7.1.4.

	[C17 Sec. 7.22.5]

	https://stackoverflow.com/questions/74207802/qsort-with-size-0

THe only explanation I can think of is that gcc somehow knows
that it is calling a recursive `qsort` implementation where the
caller is responsible for terminating the recursion -- but even
then, surely the behavior on n == 0 should be to do nothing (that
is, as if void qsort() had returned immediately) rathern than to
gratuitiously abort!

Paul, which version of gcc is this, and what is
$(GCC_DEBUG_FLAGS) expanding to?


More information about the tz mailing list