From ff2a92809112a02bef3927ef25acd04bb4e0437a Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Fri, 3 Apr 2020 15:50:19 +0300 Subject: [PATCH 1/2] Work around ARM C 6 constexpr assert ARMC6's assert macro does not work in C++14 constexpr context as it should. By defining __DO_NOT_LINK_PROMISE_WITH_ASSERT, we deactivate the extension that breaks it (having `__promise` inside `assert` - see the compiler manual). The extension does not appear to be useful - we have no code using ARMC6's `__promise` directly, and putting a `__promise` inside the assert does not appear to affect code generation in my tests. --- platform/mbed_toolchain.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform/mbed_toolchain.h b/platform/mbed_toolchain.h index a0fc28cf05e..2fa91d69e26 100644 --- a/platform/mbed_toolchain.h +++ b/platform/mbed_toolchain.h @@ -24,6 +24,15 @@ #define __error_t_defined 1 #endif +/* Work around ARM Compiler 6 bug - assert does not work in constexpr + * functions unless you stop it from using its __promise built-in. + */ +#ifdef __ARMCC_VERSION +#ifndef __DO_NOT_LINK_PROMISE_WITH_ASSERT +#define __DO_NOT_LINK_PROMISE_WITH_ASSERT +#endif +#endif + // Warning for unsupported compilers #if !defined(__GNUC__) /* GCC */ \ && !defined(__clang__) /* LLVM/Clang */ \ From fd933b4c7296d5017ecb76659e43b426bea9fba0 Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Fri, 3 Apr 2020 15:56:45 +0300 Subject: [PATCH 2/2] mbed_chrono: restore asserts Now that we've got a workaround for ARMC6, asserts can be restored. --- platform/mbed_chrono.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/platform/mbed_chrono.h b/platform/mbed_chrono.h index a051588c71e..210d64b3fe2 100644 --- a/platform/mbed_chrono.h +++ b/platform/mbed_chrono.h @@ -19,6 +19,7 @@ #ifndef __MBED_CHRONO_H__ #define __MBED_CHRONO_H__ +#include "mbed_toolchain.h" #include #include #include @@ -85,10 +86,7 @@ inline namespace chrono_literals { constexpr chrono::deciseconds operator "" _ds(unsigned long long x) { chrono::deciseconds::rep val = static_cast(x); - if (val < 0) { - assert(false); - } - assert(static_cast(val) == x); + assert(val >= 0 && static_cast(val) == x); return chrono::deciseconds(val); } @@ -106,10 +104,7 @@ constexpr chrono::deciseconds operator "" _ds(unsigned long long x) constexpr chrono::centiseconds operator "" _cs(unsigned long long x) { chrono::centiseconds::rep val = static_cast(x); - if (val < 0) { - assert(false); - } - assert(static_cast(val) == x); + assert(val >= 0 && static_cast(val) == x); return chrono::centiseconds(val); }