diff --git a/TESTS/mbedmicro-mbed/attributes/attributes.c b/TESTS/mbedmicro-mbed/attributes/attributes.c index df7ede99bb..08436b523c 100644 --- a/TESTS/mbedmicro-mbed/attributes/attributes.c +++ b/TESTS/mbedmicro-mbed/attributes/attributes.c @@ -145,6 +145,24 @@ int testNoReturn() } +int testFallthrough1(int i) +{ + switch (i) { + case 1: + case 2: + i *= 2; + MBED_FALLTHROUGH; + default: + return i; + } +} + +int testFallthrough() +{ + return testFallthrough1(0); +} + + int testUnreachable1(int i) { switch (i) { diff --git a/TESTS/mbedmicro-mbed/attributes/main.cpp b/TESTS/mbedmicro-mbed/attributes/main.cpp index 31d014e4ba..bb84b9dba6 100644 --- a/TESTS/mbedmicro-mbed/attributes/main.cpp +++ b/TESTS/mbedmicro-mbed/attributes/main.cpp @@ -33,6 +33,7 @@ extern "C" { int testPure(); int testForceInline(); int testNoReturn(); + int testFallthrough(); int testUnreachable(); int testDeprecated(); } @@ -59,6 +60,7 @@ Case cases[] = { Case("Testing PURE attribute", test_wrapper), Case("Testing FORCEINLINE attribute", test_wrapper), Case("Testing NORETURN attribute", test_wrapper), + Case("Testing FALLTHROUGH attribute", test_wrapper), Case("Testing UNREACHABLE attribute", test_wrapper), Case("Testing DEPRECATED attribute", test_wrapper), }; diff --git a/platform/mbed_toolchain.h b/platform/mbed_toolchain.h index cd60336ce7..255ab39fd5 100644 --- a/platform/mbed_toolchain.h +++ b/platform/mbed_toolchain.h @@ -340,6 +340,44 @@ #endif #endif +/** MBED_FALLTHROUGH + * Marks a point in a switch statement where fallthrough can occur. + * Should be placed as the last statement before a label. + * + * @code + * #include "mbed_toolchain.h" + * + * int foo(int arg) { + * switch (arg) { + * case 1: + * case 2: + * case 3: + * arg *= 2; + * MBED_FALLTHROUGH; + * default: + * return arg; + * } + * } + * @endcode + */ +#ifndef MBED_FALLTHROUGH +#if __cplusplus >= 201703 +#define MBED_FALLTHROUGH [[fallthrough]] +#elif defined(__clang__) +#if __cplusplus >= 201103 +#define MBED_FALLTHROUGH [[clang::fallthrough]] +#elif __has_attribute(fallthrough) +#define MBED_FALLTHROUGH __attribute__((fallthrough)) +#else +#define MBED_FALLTHROUGH +#endif +#elif defined (__GNUC__) && !defined(__CC_ARM) +#define MBED_FALLTHROUGH __attribute__((fallthrough)) +#else +#define MBED_FALLTHROUGH +#endif +#endif + /** MBED_DEPRECATED("message string") * Mark a function declaration as deprecated, if it used then a warning will be * issued by the compiler possibly including the provided message. Note that not