summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2019-03-11 09:49:05 -0700
committerJan Vorlicek <janvorli@microsoft.com>2019-03-11 18:21:43 +0100
commitc4ca1ddb2413a354e8f49fff4680f175a02e7d8e (patch)
tree37c5608dec218af85dd0f597ad59fff1893d8239
parent98cd595b35ced3adb6efe0c667f5160f21067e0b (diff)
downloadcoreclr-c4ca1ddb2413a354e8f49fff4680f175a02e7d8e.tar.gz
coreclr-c4ca1ddb2413a354e8f49fff4680f175a02e7d8e.tar.bz2
coreclr-c4ca1ddb2413a354e8f49fff4680f175a02e7d8e.zip
Fix no-return false positives in static analyzer build
There were about 800 false positive issues in the clang status analyzer build caused by the fact that various forms of asserts were not considered by the analyzer as not returning. This change adds __attribute__((analyzer_noreturn)) (wrapped in a macro) to those assertion functions.
-rw-r--r--src/inc/check.h4
-rw-r--r--src/inc/debugmacros.h2
-rw-r--r--src/inc/palclr.h2
-rw-r--r--src/jit/error.h2
-rw-r--r--src/jit/host.h1
-rw-r--r--src/pal/inc/pal.h6
-rw-r--r--src/pal/src/include/pal/dbgmsg.h14
7 files changed, 25 insertions, 6 deletions
diff --git a/src/inc/check.h b/src/inc/check.h
index b1fdba9211..b401a2590e 100644
--- a/src/inc/check.h
+++ b/src/inc/check.h
@@ -473,7 +473,7 @@ CHECK CheckValue(TYPENAME &val)
// in a free build they are passed through to the compiler to use in optimization.
//--------------------------------------------------------------------------------
-#if defined(_PREFAST_) || defined(_PREFIX_)
+#if defined(_PREFAST_) || defined(_PREFIX_) || defined(__clang_analyzer__)
#define COMPILER_ASSUME_MSG(_condition, _message) if (!(_condition)) __UNREACHABLE();
#define COMPILER_ASSUME_MSGF(_condition, args) if (!(_condition)) __UNREACHABLE();
#else
@@ -561,7 +561,7 @@ CHECK CheckValue(TYPENAME &val)
# define __UNREACHABLE() __assume(0)
#endif
#else
-#define __UNREACHABLE() do { } while(true)
+#define __UNREACHABLE() __builtin_unreachable()
#endif
#ifdef _DEBUG_IMPL
diff --git a/src/inc/debugmacros.h b/src/inc/debugmacros.h
index ef809cb69d..655fba5e5e 100644
--- a/src/inc/debugmacros.h
+++ b/src/inc/debugmacros.h
@@ -13,6 +13,7 @@
#include "stacktrace.h"
#include "debugmacrosext.h"
+#include "palclr.h"
#undef _ASSERTE
#undef VERIFY
@@ -29,6 +30,7 @@ bool GetStackTraceAtContext(SString & s, struct _CONTEXT * pContext);
void _cdecl DbgWriteEx(LPCTSTR szFmt, ...);
bool _DbgBreakCheck(LPCSTR szFile, int iLine, LPCSTR szExpr, BOOL fConstrained = FALSE);
+ANALYZER_NORETURN
extern VOID DbgAssertDialog(const char *szFile, int iLine, const char *szExpr);
#define TRACE_BUFF_SIZE (cchMaxAssertStackLevelStringLen * cfrMaxAssertStackLevels + cchMaxAssertExprLen + 1)
diff --git a/src/inc/palclr.h b/src/inc/palclr.h
index 60b97305eb..3b42ac5dae 100644
--- a/src/inc/palclr.h
+++ b/src/inc/palclr.h
@@ -53,6 +53,8 @@
#endif // !_MSC_VER
#endif // !NOINLINE
+#define ANALYZER_NORETURN
+
//
// CPP_ASSERT() can be used within a class definition, to perform a
// compile-time assertion involving private names within the class.
diff --git a/src/jit/error.h b/src/jit/error.h
index 944eaca263..2a3b60fcde 100644
--- a/src/jit/error.h
+++ b/src/jit/error.h
@@ -73,11 +73,13 @@ extern void DECLSPEC_NORETURN noWayAssertBody(const char* cond, const char* file
// Conditionally invoke the noway assert body. The conditional predicate is evaluated using a method on the tlsCompiler.
// If a noway_assert is hit, we ask the Compiler whether to raise an exception (i.e., conditionally raise exception.)
// To have backward compatibility between v4.5 and v4.0, in min-opts we take a shot at codegen rather than rethrow.
+ANALYZER_NORETURN
extern void noWayAssertBodyConditional(
#ifdef FEATURE_TRACELOGGING
const char* file, unsigned line
#endif
);
+ANALYZER_NORETURN
extern void noWayAssertBodyConditional(const char* cond, const char* file, unsigned line);
// Define MEASURE_NOWAY to 1 to enable code to count and rank individual noway_assert calls by occurrence.
diff --git a/src/jit/host.h b/src/jit/host.h
index f7cbdcfb00..1b090a194f 100644
--- a/src/jit/host.h
+++ b/src/jit/host.h
@@ -35,6 +35,7 @@ void gcDump_logf(const char* fmt, ...);
void logf(unsigned level, const char* fmt, ...);
+ANALYZER_NORETURN
extern "C" void __cdecl assertAbort(const char* why, const char* file, unsigned line);
#undef assert
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index cdb376068e..26c9e3f6d8 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -168,6 +168,12 @@ typedef PVOID NATIVE_LIBRARY_HANDLE;
#define DECLSPEC_NORETURN PAL_NORETURN
+#ifdef __clang_analyzer__
+#define ANALYZER_NORETURN __attribute((analyzer_noreturn))
+#else
+#define ANALYZER_NORETURN
+#endif
+
#if !defined(_MSC_VER) || defined(SOURCE_FORMATTING)
#define __assume(x) (void)0
#define __annotation(x)
diff --git a/src/pal/src/include/pal/dbgmsg.h b/src/pal/src/include/pal/dbgmsg.h
index 641de90a60..ad3dd540cd 100644
--- a/src/pal/src/include/pal/dbgmsg.h
+++ b/src/pal/src/include/pal/dbgmsg.h
@@ -355,6 +355,15 @@ bool DBG_ShouldCheckStackAlignment();
#else /* defined(_DEBUG) */
+ANALYZER_NORETURN
+inline void AssertBreak()
+{
+ if(g_Dbg_asserts_enabled)
+ {
+ DebugBreak();
+ }
+}
+
#define ASSERT(...) \
{ \
__ASSERT_ENTER(); \
@@ -362,10 +371,7 @@ bool DBG_ShouldCheckStackAlignment();
{ \
DBG_printf(defdbgchan,DLI_ASSERT,TRUE,__FUNCTION__,__FILE__,__LINE__,__VA_ARGS__); \
} \
- if(g_Dbg_asserts_enabled) \
- { \
- DebugBreak(); \
- } \
+ AssertBreak(); \
}
#define _ASSERT(expr) do { if (!(expr)) { ASSERT(""); } } while(0)