summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gröber <dxld@darkboxed.org>2021-02-15 04:07:23 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-07-29 13:12:47 -0400
commite6731578246b6e6959026d4a9da9971b097c83aa (patch)
treeb187c46fc1d10b17a1f7d2a5952582269921b73a
parent296ed7395c9a45352cf2e03ef9ff0b3b1f5a1a80 (diff)
downloadhaskell-e6731578246b6e6959026d4a9da9971b097c83aa.tar.gz
Add configure flag to enable ASSERTs in all ways
Running the test suite with asserts enabled is somewhat tricky at the moment as running it with a GHC compiled the DEBUG way has some hundred failures from the start. These seem to be unrelated to assertions though. So this provides a toggle to make it easier to debug failing assertions using the test suite.
-rw-r--r--compiler/cbits/genSym.c4
-rw-r--r--configure.ac12
-rw-r--r--includes/Cmm.h8
-rw-r--r--includes/Rts.h24
-rw-r--r--rts/posix/OSThreads.c2
-rw-r--r--rts/sm/CNF.c3
-rw-r--r--rts/sm/GC.c2
-rw-r--r--rts/sm/MarkWeak.c2
8 files changed, 42 insertions, 15 deletions
diff --git a/compiler/cbits/genSym.c b/compiler/cbits/genSym.c
index eed2b4f142..19697de25e 100644
--- a/compiler/cbits/genSym.c
+++ b/compiler/cbits/genSym.c
@@ -16,9 +16,7 @@ HsInt ghc_unique_inc = 1;
HsInt genSym(void) {
HsInt u = atomic_inc((StgWord *)&ghc_unique_counter, ghc_unique_inc) & UNIQUE_MASK;
-#if DEBUG
// Uh oh! We will overflow next time a unique is requested.
- assert(u != UNIQUE_MASK);
-#endif
+ ASSERT(u != UNIQUE_MASK);
return u;
}
diff --git a/configure.ac b/configure.ac
index 1b9ebd309f..7563ed5af9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -123,6 +123,17 @@ if test "$EnableDistroToolchain" = "YES"; then
TarballsAutodownload=NO
fi
+AC_ARG_ENABLE(asserts-all-ways,
+[AC_HELP_STRING([--enable-asserts-all-ways],
+ [Usually ASSERTs are only compiled in the DEBUG way,
+ this will enable them in all ways.])],
+ EnableAssertsAllWays=YES,
+ EnableAssertsAllWays=NO
+)
+if test "$enable_asserts_all_ways" = "yes" ; then
+ AC_DEFINE([USE_ASSERTS_ALL_WAYS], [1], [Compile-in ASSERTs in all ways.])
+fi
+
AC_ARG_ENABLE(native-io-manager,
[AS_HELP_STRING([--enable-native-io-manager],
[Enable the native I/O manager by default.])],
@@ -135,6 +146,7 @@ if test "$EnableNativeIOManager" = "YES"; then
fi
+
dnl CC_STAGE0, LD_STAGE0, AR_STAGE0 are like the "previous" variable
dnl CC, LD, AR (inherited by CC_STAGE[123], etc.)
dnl but instead used by stage0 for bootstrapping stage1
diff --git a/includes/Cmm.h b/includes/Cmm.h
index b1b8680e99..9b17e9f400 100644
--- a/includes/Cmm.h
+++ b/includes/Cmm.h
@@ -211,7 +211,13 @@
Assertions and Debuggery
-------------------------------------------------------------------------- */
-#if defined(DEBUG)
+#if defined(DEBUG) || defined(USE_ASSERTS_ALL_WAYS)
+#define ASSERTS_ENABLED 1
+#else
+#undef ASSERTS_ENABLED
+#endif
+
+#if ASSERTS_ENABLED
#define ASSERT(predicate) \
if (predicate) { \
/*null*/; \
diff --git a/includes/Rts.h b/includes/Rts.h
index 5e657e07ce..82fd48fcbf 100644
--- a/includes/Rts.h
+++ b/includes/Rts.h
@@ -112,7 +112,9 @@ extern "C" {
Assertions and Debuggery
CHECK(p) evaluates p and terminates with an error if p is false
- ASSERT(p) like CHECK(p) if DEBUG is on, otherwise a no-op
+ ASSERT(p) like CHECK(p) a no-op, unless ASSERTS_ENABLED is on. Either
+ because we're building in the DEBUG way or USE_ASSERTS_ALL_WAYS
+ (aka --enable-asserts-all-ways) was enabled at ./configure time.
-------------------------------------------------------------------------- */
void _assertFail(const char *filename, unsigned int linenum)
@@ -130,12 +132,22 @@ void _assertFail(const char *filename, unsigned int linenum)
else \
barf(msg, ##__VA_ARGS__)
-#if !defined(DEBUG)
-#define ASSERT(predicate) /* nothing */
-#define ASSERTM(predicate,msg,...) /* nothing */
+#if defined(DEBUG) || defined(USE_ASSERTS_ALL_WAYS)
+#define ASSERTS_ENABLED 1
#else
-#define ASSERT(predicate) CHECK(predicate)
-#define ASSERTM(predicate,msg,...) CHECKM(predicate,msg,##__VA_ARGS__)
+#undef ASSERTS_ENABLED
+#endif
+
+#if ASSERTS_ENABLED
+#define ASSERT(predicate) \
+ do { CHECK(predicate); } while(0)
+#define ASSERTM(predicate,msg,...) \
+ do { CHECKM(predicate, msg, ##__VA_ARGS__); } while(0)
+#else
+#define ASSERT(predicate) \
+ do { (void) sizeof(predicate); } while(0)
+#define ASSERTM(predicate,msg,...) \
+ do { (void) sizeof(predicate); (void) sizeof(msg); } while(0)
#endif /* DEBUG */
/*
diff --git a/rts/posix/OSThreads.c b/rts/posix/OSThreads.c
index 04375006d2..647b4840d3 100644
--- a/rts/posix/OSThreads.c
+++ b/rts/posix/OSThreads.c
@@ -202,7 +202,7 @@ osThreadIsAlive(OSThreadId id STG_UNUSED)
void
initMutex(Mutex* pMut)
{
-#if defined(DEBUG)
+#if ASSERTS_ENABLED
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK);
diff --git a/rts/sm/CNF.c b/rts/sm/CNF.c
index 31b3cb99f2..bfe6493cfa 100644
--- a/rts/sm/CNF.c
+++ b/rts/sm/CNF.c
@@ -227,9 +227,8 @@ compactAllocateBlockInternal(Capability *cap,
break;
default:
-#if defined(DEBUG)
ASSERT(!"code should not be reached");
-#else
+#if !defined(DEBUG)
RTS_UNREACHABLE;
#endif
}
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index 1a71bd7bf0..21b7b17f0d 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -1545,8 +1545,8 @@ releaseGCThreads (Capability *cap USED_IF_THREADS, bool idle_cap[])
const uint32_t n_threads = n_capabilities;
const uint32_t me = cap->no;
uint32_t i;
-#if defined(DEBUG)
uint32_t num_idle = 0;
+#if defined(ASSERTS_ENABLED)
for(i=0; i < n_threads; ++i) {
ASSERT(!(i==me && idle_cap[i]));
if (idle_cap[i]) { ++num_idle;}
diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c
index b8d120823c..379e3aaa80 100644
--- a/rts/sm/MarkWeak.c
+++ b/rts/sm/MarkWeak.c
@@ -417,7 +417,7 @@ markWeakPtrList ( void )
for (w = gen->weak_ptr_list; w != NULL; w = RELAXED_LOAD(&w->link)) {
// w might be WEAK, EVACUATED, or DEAD_WEAK (actually CON_STATIC) here
-#if defined(DEBUG)
+#if defined(ASSERTS_ENABLED)
{ // careful to do this assertion only reading the info ptr
// once, because during parallel GC it might change under our feet.
const StgInfoTable *info = RELAXED_LOAD(&w->header.info);