]> granicus.if.org Git - check/commitdiff
check.h: only mark _ck_assert_failed as noreturn when using fork
authorbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Tue, 17 Dec 2013 03:28:26 +0000 (03:28 +0000)
committerbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Tue, 17 Dec 2013 03:28:26 +0000 (03:28 +0000)
When fork is used, _ck_assert_failed will call exit() when a
failure occurs. Marking it as noreturn makes sense in this case.

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.

For this reason, the function is only marked as noreturn when
using fork(). Any static source code analysis to catch issues
must be done on a system with fork() to avoid possible false
positives.

git-svn-id: svn+ssh://svn.code.sf.net/p/check/code/trunk@871 64e312b2-a51f-0410-8e61-82d0ca0eb02a

src/check.h.in

index d14056e40a867524092fe31536ce4d770bb130f3..f4a68de585245b3fd2e02e9388533c98a329ed2d 100644 (file)
@@ -265,8 +265,20 @@ static void __testname (int _i CK_ATTRIBUTE_UNUSED)\
 
 #define fail ck_abort_msg
 
-/* This is called whenever an assertion fails */
+/*
+ * This is called whenever an assertion fails.
+ * Note that it only has the noreturn modifier when
+ * using fork. If fork is unavailable, the function
+ * calls longjmp() when a test assertion fails. Marking
+ * the function as noreturn causes gcc to make assumptions
+ * which are not valid, as longjmp() is like a return.
+ */
+#if @HAVE_FORK@
 void CK_EXPORT _ck_assert_failed (const char *file, int line, const char *expr, ...) CK_ATTRIBUTE_NORETURN;
+#else
+void CK_EXPORT _ck_assert_failed (const char *file, int line, const char *expr, ...);
+#endif
+;
 
 /* New check fail API. */