From 129456fe2e9cc1b77e0f52784a0e73030ee8cf1b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 7 Feb 2014 11:52:35 -0500 Subject: [PATCH] Tell Clang's static analysis that SDL_assert() is an assertion handler. This lets it know, for example, that when you do this... SDL_assert(ptr != NULL); ...that (ptr) is definitely not NULL at this point in the program, for the sake of static analysis. While a buggy program could definitely trigger this assertion, Clang assumes your assertion check is covering it and won't report possible NULL dereferences after this point. Since SDL_assert might continue if the user clicks "ignore", without this change Clang would notice you checked for NULL (meaning that NULL is a real possibility here) and still wrote code outside of that test branch that dereferences the pointer, and thus would always trigger false positives. Static analysis is fun! --- include/SDL_assert.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/SDL_assert.h b/include/SDL_assert.h index 4441dbfef..57a4f8647 100644 --- a/include/SDL_assert.h +++ b/include/SDL_assert.h @@ -120,7 +120,14 @@ typedef struct SDL_assert_data /* Never call this directly. Use the SDL_assert* macros. */ extern DECLSPEC SDL_assert_state SDLCALL SDL_ReportAssertion(SDL_assert_data *, const char *, - const char *, int); + const char *, int) +#if defined(__clang__) && __has_feature(attribute_analyzer_noreturn) +/* this tells Clang's static analysis that we're a custom assert function, + and that the analyzer should assume the condition was always true past this + SDL_assert test. */ + __attribute__((analyzer_noreturn)) +#endif +; /* the do {} while(0) avoids dangling else problems: if (x) SDL_assert(y); else blah();