Tell Clang's static analysis that SDL_assert() is an assertion handler.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 07 Feb 2014 11:52:35 -0500
changeset 8189 ab1045579b92
parent 8188 47b9ab82bebf
child 8190 e63a3fe7e835
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
--- a/include/SDL_assert.h	Fri Feb 07 09:35:33 2014 -0500
+++ b/include/SDL_assert.h	Fri Feb 07 11:52:35 2014 -0500
@@ -120,7 +120,14 @@
 /* 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();