Bug 997145 - Add a attribute in order to silent a Clang static analyzer check r=nfroyd
authorSylvestre Ledru <sledru@mozilla.com>
Tue, 06 May 2014 16:23:08 +0200
changeset 181773 31bf4de12ff1270b80e22a27258c2b393da6062f
parent 181772 e436a3c3dcb3414a0d1d4d5cdce06a788453d211
child 181774 4094a0e89ed3b80f21958dc82e1eaacd5073a944
push id26731
push userryanvm@gmail.com
push dateTue, 06 May 2014 20:24:50 +0000
treeherdermozilla-central@df540d726c01 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnfroyd
bugs997145
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 997145 - Add a attribute in order to silent a Clang static analyzer check r=nfroyd
mfbt/Assertions.h
mfbt/Attributes.h
--- a/mfbt/Assertions.h
+++ b/mfbt/Assertions.h
@@ -127,32 +127,32 @@ extern "C" {
  * Prints |s| as an assertion failure (using file and ln as the location of the
  * assertion) to the standard debug-output channel.
  *
  * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method.  This
  * method is primarily for internal use in this header, and only secondarily
  * for use in implementing release-build assertions.
  */
 static MOZ_ALWAYS_INLINE void
-MOZ_ReportAssertionFailure(const char* s, const char* file, int ln)
+MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
 {
 #ifdef ANDROID
   __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert",
                       "Assertion failure: %s, at %s:%d\n", s, file, ln);
 #else
   fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
 #ifdef MOZ_DUMP_ASSERTION_STACK
   nsTraceRefcnt::WalkTheStack(stderr);
 #endif
   fflush(stderr);
 #endif
 }
 
 static MOZ_ALWAYS_INLINE void
-MOZ_ReportCrash(const char* s, const char* file, int ln)
+MOZ_ReportCrash(const char* s, const char* file, int ln) MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
 {
 #ifdef ANDROID
     __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH",
                         "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln);
 #else
   fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln);
 #ifdef MOZ_DUMP_ASSERTION_STACK
   nsTraceRefcnt::WalkTheStack(stderr);
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -107,16 +107,26 @@
 #  define MOZ_HAVE_CXX11_OVERRIDE
 #  define MOZ_HAVE_NEVER_INLINE          __declspec(noinline)
 #  define MOZ_HAVE_NORETURN              __declspec(noreturn)
 // Staying away from explicit conversion operators in MSVC for now, see
 // http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug
 #endif
 
 /*
+ * When built with clang analyzer (a.k.a scan-build), define MOZ_HAVE_NORETURN
+ * to mark some false positives
+ */
+#ifdef __clang_analyzer__
+#  if __has_extension(attribute_analyzer_noreturn)
+#    define MOZ_HAVE_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
+#  endif
+#endif
+
+/*
  * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a
  * function at compile time. A constexpr function cannot examine any values
  * except its arguments and can have no side effects except its return value.
  * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's
  * value may be computed at compile time.  It should be prefered to just
  * marking variables as MOZ_CONSTEXPR because if the compiler does not support
  * constexpr it will fall back to making the variable const, and some compilers
  * do not accept variables being marked both const and constexpr.
@@ -181,16 +191,37 @@
  */
 #if defined(MOZ_HAVE_NORETURN)
 #  define MOZ_NORETURN          MOZ_HAVE_NORETURN
 #else
 #  define MOZ_NORETURN          /* no support */
 #endif
 
 /*
+ * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS, specified at the end of a function
+ * declaration, indicates that for the purposes of static analysis, this
+ * function does not return.  (The function definition does not need to be
+ * annotated.)
+ *
+ * MOZ_ReportCrash(const char* s, const char* file, int ln) MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
+ *
+ * Some static analyzers, like scan-build from clang, can use this information
+ * to eliminate false positives.  From the upstream documentation of scan-build:
+ * "This attribute is useful for annotating assertion handlers that actually
+ * can return, but for the purpose of using the analyzer we want to pretend
+ * that such functions do not return."
+ *
+ */
+#if defined(MOZ_HAVE_ANALYZER_NORETURN)
+#  define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS          MOZ_HAVE_ANALYZER_NORETURN
+#else
+#  define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS          /* no support */
+#endif
+
+/*
  * MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
  * instrumentation shipped with Clang and GCC) to not instrument the annotated
  * function. Furthermore, it will prevent the compiler from inlining the
  * function because inlining currently breaks the blacklisting mechanism of
  * AddressSanitizer.
  */
 #if defined(__has_feature)
 #  if __has_feature(address_sanitizer)