libcheck / check

A unit testing framework for C
GNU Lesser General Public License v2.1
1.07k stars 210 forks source link

No NORETURN on _ck_assert_failed without HAVE_FORK #291

Open heftig opened 4 years ago

heftig commented 4 years ago

Is this check still needed? The GCC documentation mentions that returning using longjmp from functions marked noreturn is valid behavior.

nirbheek commented 4 years ago

Specifically, without this, fail() will cause a warning in many cases on mingw-gcc. See, f.ex.: https://gitlab.freedesktop.org/gstreamer/gst-plugins-ugly/-/merge_requests/59#note_576422

nirbheek commented 4 years ago

Actually, that comment is almost certainly wrong because _ck_assert_failed() uses longjmp() even on UNIX when CK_FORK=0 is set in the env, and gcc does not warn about the longjmp() else case violating the noreturn attribute.

brarcher commented 4 years ago

The commit which added the comment about longjmp() and noreturn mentions the following:

When fork() is not used, longjmp() is called, which is a type of return. Marking it as noreturn allows the compiler (gcc) to make assumptions which are not true. Using longjmp causes the unit testing program to segfault.

I'm not sure if that is still true today. However, back then using longjmp and noreturn together caused issues.

nirbheek commented 4 years ago

Since C11, longjmp is specified by the spec to be noreturn.

The default c_std in GCC has been gnu11 since GCC 5, which was released in 2015. I suspect that even before that, GCC had started applying noreturn to longjmp.

The current code is already assuming C11 since it's unconditionally applying noreturn to _ck_assert_failed() even though it is conditional on the CK_FORK env var.