Add conditional support for noreturn functions.

This adds support for tagging functions with the noreturn attribute.
If DO_CRASH is enabled then ast_do_crash never returns.  If AST_DEVMODE
and DO_CRASH are enabled then failed assertions never return.  This can
resolve a large number of false positives with static analyzers.

ASTERISK-26220 #close

Change-Id: Icfb61e5fe54574eced4c3e88b317244f467ec753
This commit is contained in:
Corey Farrell
2016-07-18 23:46:19 -04:00
parent 5f24874ebb
commit 7fdf7c3d4c
6 changed files with 92 additions and 9 deletions

78
configure vendored
View File

@@ -13987,7 +13987,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807, We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */ incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1) && LARGE_OFF_T % 2147483647 == 1)
? 1 : -1]; ? 1 : -1];
@@ -14033,7 +14033,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807, We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */ incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1) && LARGE_OFF_T % 2147483647 == 1)
? 1 : -1]; ? 1 : -1];
@@ -14057,7 +14057,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
We can't simply define LARGE_OFF_T to be 9223372036854775807, We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */ incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1) && LARGE_OFF_T % 2147483647 == 1)
? 1 : -1]; ? 1 : -1];
@@ -14102,7 +14102,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807, We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */ incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1) && LARGE_OFF_T % 2147483647 == 1)
? 1 : -1]; ? 1 : -1];
@@ -14126,7 +14126,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
We can't simply define LARGE_OFF_T to be 9223372036854775807, We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */ incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1) && LARGE_OFF_T % 2147483647 == 1)
? 1 : -1]; ? 1 : -1];
@@ -17863,6 +17863,74 @@ CFLAGS="$saved_CFLAGS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for compiler 'attribute noreturn' support" >&5
$as_echo_n "checking for compiler 'attribute noreturn' support... " >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wall -Wno-unused -Werror"
if test "xnoreturn" = "x"
then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void __attribute__((noreturn)) *test(void *muffin, ...) {return (void *) 0;}
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_noreturn 1
_ACEOF
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void __attribute__((noreturn)) *test(void *muffin, ...) ;
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_noreturn 1
_ACEOF
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fsanitize=address support" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fsanitize=address support" >&5
$as_echo_n "checking for -fsanitize=address support... " >&6; } $as_echo_n "checking for -fsanitize=address support... " >&6; }
saved_sanitize_CFLAGS="${CFLAGS}" saved_sanitize_CFLAGS="${CFLAGS}"

View File

@@ -1072,6 +1072,7 @@ AST_GCC_ATTRIBUTE(warn_unused_result)
AST_GCC_ATTRIBUTE(may_alias) AST_GCC_ATTRIBUTE(may_alias)
AST_GCC_ATTRIBUTE(constructor) AST_GCC_ATTRIBUTE(constructor)
AST_GCC_ATTRIBUTE(destructor) AST_GCC_ATTRIBUTE(destructor)
AST_GCC_ATTRIBUTE(noreturn,noreturn)
AC_MSG_CHECKING(for -fsanitize=address support) AC_MSG_CHECKING(for -fsanitize=address support)
saved_sanitize_CFLAGS="${CFLAGS}" saved_sanitize_CFLAGS="${CFLAGS}"

View File

@@ -103,6 +103,9 @@
/* Define to 1 if your GCC C compiler supports the 'may_alias' attribute. */ /* Define to 1 if your GCC C compiler supports the 'may_alias' attribute. */
#undef HAVE_ATTRIBUTE_may_alias #undef HAVE_ATTRIBUTE_may_alias
/* Define to 1 if your GCC C compiler supports the 'noreturn' attribute. */
#undef HAVE_ATTRIBUTE_noreturn
/* Define to 1 if your GCC C compiler supports the 'pure' attribute. */ /* Define to 1 if your GCC C compiler supports the 'pure' attribute. */
#undef HAVE_ATTRIBUTE_pure #undef HAVE_ATTRIBUTE_pure

View File

@@ -77,6 +77,12 @@
#define attribute_may_alias #define attribute_may_alias
#endif #endif
#ifdef HAVE_ATTRIBUTE_noreturn
#define attribute_noreturn __attribute__((noreturn))
#else
#define attribute_noreturn
#endif
/* Some older version of GNU gcc (3.3.5 on OpenBSD 4.3 for example) dont like 'NULL' as sentinel */ /* Some older version of GNU gcc (3.3.5 on OpenBSD 4.3 for example) dont like 'NULL' as sentinel */
#define SENTINEL ((char *)NULL) #define SENTINEL ((char *)NULL)

View File

@@ -843,9 +843,14 @@ struct ast_http_digest {
*/ */
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic); int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic);
#ifdef DO_CRASH
#define DO_CRASH_NORETURN attribute_noreturn
#else
#define DO_CRASH_NORETURN
#endif
#ifdef AST_DEVMODE #ifdef AST_DEVMODE
void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function); void DO_CRASH_NORETURN __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function);
#define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
static void force_inline _ast_assert(int condition, const char *condition_str, const char *file, int line, const char *function) static void force_inline _ast_assert(int condition, const char *condition_str, const char *file, int line, const char *function)
{ {
@@ -864,7 +869,7 @@ static void force_inline _ast_assert(int condition, const char *condition_str, c
* *
* \return Nothing * \return Nothing
*/ */
void ast_do_crash(void); void DO_CRASH_NORETURN ast_do_crash(void);
#include "asterisk/strings.h" #include "asterisk/strings.h"

View File

@@ -2425,7 +2425,7 @@ char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
return NULL; return NULL;
} }
void ast_do_crash(void) void DO_CRASH_NORETURN ast_do_crash(void)
{ {
#if defined(DO_CRASH) #if defined(DO_CRASH)
abort(); abort();
@@ -2438,7 +2438,7 @@ void ast_do_crash(void)
} }
#if defined(AST_DEVMODE) #if defined(AST_DEVMODE)
void __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function) void DO_CRASH_NORETURN __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function)
{ {
/* /*
* Attempt to put it into the logger, but hope that at least * Attempt to put it into the logger, but hope that at least