From 409a6db3492e8d5e81f5e248e9e9abe100506ff5 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 14 May 2013 08:49:55 +0200 Subject: [PATCH] Mark up warnings/critical functions for clang analyzer The clang code analyzer needs to know that functions like g_error g_critical an g_return_if_fail should be seen by the analyzer in the same way as g_assert(). That is the analyzer should think they are fatal. https://bugzilla.gnome.org/show_bug.cgi?id=700268 --- glib/gmacros.h | 13 +++++++++++++ glib/gmessages.h | 13 +++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/glib/gmacros.h b/glib/gmacros.h index b37b08ecb..f3f542bd9 100644 --- a/glib/gmacros.h +++ b/glib/gmacros.h @@ -158,6 +158,19 @@ #endif /* !__GNUC__ */ #endif /* !G_DISABLE_DEPRECATED */ +/* Clang feature detection: http://clang.llvm.org/docs/LanguageExtensions.html */ +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +#if __has_feature(attribute_analyzer_noreturn) +#define G_ANALYZER_ANALYZING 1 +#define G_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) +#else +#define G_ANALYZER_ANALYZING 0 +#define G_ANALYZER_NORETURN +#endif + #define G_STRINGIFY(macro_or_string) G_STRINGIFY_ARG (macro_or_string) #define G_STRINGIFY_ARG(contents) #contents diff --git a/glib/gmessages.h b/glib/gmessages.h index 8092078b9..e979266ea 100644 --- a/glib/gmessages.h +++ b/glib/gmessages.h @@ -125,13 +125,13 @@ void _g_log_fallback_handler (const gchar *log_domain, GLIB_AVAILABLE_IN_ALL void g_return_if_fail_warning (const char *log_domain, const char *pretty_function, - const char *expression); + const char *expression) G_ANALYZER_NORETURN; GLIB_AVAILABLE_IN_ALL void g_warn_message (const char *domain, const char *file, int line, const char *func, - const char *warnexpr); + const char *warnexpr) G_ANALYZER_NORETURN; GLIB_DEPRECATED void g_assert_warning (const char *log_domain, const char *file, @@ -143,7 +143,8 @@ void g_assert_warning (const char *log_domain, #ifndef G_LOG_DOMAIN #define G_LOG_DOMAIN ((gchar*) 0) #endif /* G_LOG_DOMAIN */ -#ifdef G_HAVE_ISO_VARARGS + +#if defined(G_HAVE_ISO_VARARGS) && !G_ANALYZER_ANALYZING /* for(;;) ; so that GCC knows that control doesn't go past g_error(). * Put space before ending semicolon to avoid C++ build warnings. */ @@ -166,7 +167,7 @@ void g_assert_warning (const char *log_domain, #define g_debug(...) g_log (G_LOG_DOMAIN, \ G_LOG_LEVEL_DEBUG, \ __VA_ARGS__) -#elif defined(G_HAVE_GNUC_VARARGS) +#elif defined(G_HAVE_GNUC_VARARGS) && !G_ANALYZER_ANALYZING #define g_error(format...) G_STMT_START { \ g_log (G_LOG_DOMAIN, \ G_LOG_LEVEL_ERROR, \ @@ -189,7 +190,7 @@ void g_assert_warning (const char *log_domain, #else /* no varargs macros */ static void g_error (const gchar *format, - ...) + ...) G_ANALYZER_NORETURN { va_list args; va_start (args, format); @@ -209,7 +210,7 @@ g_message (const gchar *format, } static void g_critical (const gchar *format, - ...) + ...) G_ANALYZER_NORETURN { va_list args; va_start (args, format);