mirror of https://github.com/ARMmbed/mbed-os.git
Added other attributes on supported compilers
tested on GCC, Clang, online compiler, and IAR attributes - PACK - ALIGN - UNUSED - WEAK - PURE - FORCEINLINE - NORETURN - UNREACHABLE - DEPRECATED
parent
f05240b666
commit
018e2571e6
|
@ -4,15 +4,44 @@
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
struct TestAttrPackedStruct {
|
||||
typedef struct {
|
||||
char a;
|
||||
int x;
|
||||
} PACKED;
|
||||
} PACKED TestAttrPackedStruct;
|
||||
|
||||
int testPacked() {
|
||||
int failed = 0;
|
||||
|
||||
if (sizeof(struct TestAttrPackedStruct) != sizeof(int) + sizeof(char)) {
|
||||
if (sizeof(TestAttrPackedStruct) != sizeof(int) + sizeof(char)) {
|
||||
failed++;
|
||||
}
|
||||
|
||||
return failed;
|
||||
}
|
||||
|
||||
|
||||
int testAlign() {
|
||||
int failed = 0;
|
||||
|
||||
ALIGN(8) char a;
|
||||
ALIGN(8) char b;
|
||||
ALIGN(16) char c;
|
||||
ALIGN(8) char d;
|
||||
ALIGN(16) char e;
|
||||
|
||||
if(((uintptr_t)&a) & 0x7){
|
||||
failed++;
|
||||
}
|
||||
if(((uintptr_t)&b) & 0x7){
|
||||
failed++;
|
||||
}
|
||||
if(((uintptr_t)&c) & 0xf){
|
||||
failed++;
|
||||
}
|
||||
if(((uintptr_t)&d) & 0x7){
|
||||
failed++;
|
||||
}
|
||||
if(((uintptr_t)&e) & 0xf){
|
||||
failed++;
|
||||
}
|
||||
|
||||
|
@ -29,21 +58,6 @@ int testUnused() {
|
|||
}
|
||||
|
||||
|
||||
DEPRECATED("this message should not be displayed")
|
||||
void testDeprecatedUnused();
|
||||
void testDeprecatedUnused() { }
|
||||
|
||||
DEPRECATED("this message should be displayed")
|
||||
int testDeprecatedUsed();
|
||||
int testDeprecatedUsed() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDeprecated() {
|
||||
return testDeprecatedUsed();
|
||||
}
|
||||
|
||||
|
||||
int testWeak1();
|
||||
int testWeak2();
|
||||
|
||||
|
@ -59,3 +73,62 @@ int testWeak() {
|
|||
return testWeak1() | testWeak2();
|
||||
}
|
||||
|
||||
|
||||
PURE int testPure1() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testPure() {
|
||||
return testPure1();
|
||||
}
|
||||
|
||||
|
||||
FORCEINLINE int testForceInline1() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testForceInline() {
|
||||
return testForceInline1();
|
||||
}
|
||||
|
||||
|
||||
NORETURN int testNoReturn1() {
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
int testNoReturn() {
|
||||
if (0) {
|
||||
testNoReturn1();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int testUnreachable1(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return 0;
|
||||
}
|
||||
|
||||
UNREACHABLE;
|
||||
}
|
||||
|
||||
int testUnreachable() {
|
||||
return testUnreachable1(0);
|
||||
}
|
||||
|
||||
|
||||
DEPRECATED("this message should not be displayed")
|
||||
void testDeprecatedUnused();
|
||||
void testDeprecatedUnused() { }
|
||||
|
||||
DEPRECATED("this message should be displayed")
|
||||
int testDeprecatedUsed();
|
||||
int testDeprecatedUsed() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDeprecated() {
|
||||
return testDeprecatedUsed();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,14 @@ using namespace utest::v1;
|
|||
// Test functions declared as C functions to avoid issues with name mangling
|
||||
extern "C" {
|
||||
int testPacked();
|
||||
int testAlign();
|
||||
int testUnused();
|
||||
int testDeprecated();
|
||||
int testWeak();
|
||||
int testPure();
|
||||
int testForceInline();
|
||||
int testNoReturn();
|
||||
int testUnreachable();
|
||||
int testDeprecated();
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,10 +35,15 @@ status_t test_setup(const size_t number_of_cases) {
|
|||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("Testing PACKED attribute", test_wrapper<testPacked>),
|
||||
Case("Testing UNUSED attribute", test_wrapper<testUnused>),
|
||||
Case("Testing DEPRECATED attribute", test_wrapper<testDeprecated>),
|
||||
Case("Testing WEAK attribute", test_wrapper<testWeak>),
|
||||
Case("Testing PACKED attribute", test_wrapper<testPacked>),
|
||||
Case("Testing ALIGN attribute", test_wrapper<testAlign>),
|
||||
Case("Testing UNUSED attribute", test_wrapper<testUnused>),
|
||||
Case("Testing WEAK attribute", test_wrapper<testWeak>),
|
||||
Case("Testing PURE attribute", test_wrapper<testPure>),
|
||||
Case("Testing FORCEINLINE attribute", test_wrapper<testForceInline>),
|
||||
Case("Testing NORETURN attribute", test_wrapper<testNoReturn>),
|
||||
Case("Testing UNREACHABLE attribute", test_wrapper<testUnreachable>),
|
||||
Case("Testing DEPRECATED attribute", test_wrapper<testDeprecated>),
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
|
|
|
@ -28,16 +28,16 @@
|
|||
|
||||
// Attributes
|
||||
|
||||
/** PACK
|
||||
/** PACKED
|
||||
* Pack a structure, preventing any padding from being added between fields.
|
||||
*
|
||||
* @code
|
||||
* #include "toolchain.h"
|
||||
*
|
||||
* struct foo {
|
||||
* typedef struct {
|
||||
* char x;
|
||||
* int y;
|
||||
* } PACKED;
|
||||
* } PACKED foo;
|
||||
* @endcode
|
||||
*/
|
||||
#ifndef PACKED
|
||||
|
@ -48,19 +48,37 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/** ALIGN(N)
|
||||
* Declare a variable to be aligned on an N-byte boundary.
|
||||
*
|
||||
* @code
|
||||
* #include "toolchain.h"
|
||||
*
|
||||
* ALIGN(16) char a;
|
||||
* @endcode
|
||||
*/
|
||||
#ifndef ALIGN
|
||||
#if defined(__ICCARM__)
|
||||
#define _ALIGN(N) _Pragma(#N)
|
||||
#define ALIGN(N) _ALIGN(data_alignment=N)
|
||||
#else
|
||||
#define ALIGN(N) __attribute__((aligned(N)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** UNUSED
|
||||
* Declare a function argument to be unused, suppressing compiler warnings
|
||||
*
|
||||
* @code
|
||||
* #include "toolchain.h"
|
||||
*
|
||||
* void foo(UNUSED int arg){
|
||||
* void foo(UNUSED int arg) {
|
||||
*
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#ifndef UNUSED
|
||||
#if defined(__GNUC__) || defined(__CC_ARM) || defined(__clang__)
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
|
||||
#define UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define UNUSED
|
||||
|
@ -93,6 +111,95 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/** PURE
|
||||
* Hint to the compiler that a function depends only on parameters
|
||||
*
|
||||
* @code
|
||||
* #include "toolchain.h"
|
||||
*
|
||||
* PURE int foo(int arg){
|
||||
* // no access to global variables
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#ifndef PURE
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
|
||||
#define PURE __attribute__((const))
|
||||
#else
|
||||
#define PURE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** FORCEINLINE
|
||||
* Declare a function that must always be inlined. Failure to inline
|
||||
* such a function will result in an error.
|
||||
*
|
||||
* @code
|
||||
* #include "toolchain.h"
|
||||
*
|
||||
* FORCEINLINE void foo() {
|
||||
*
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#ifndef FORCEINLINE
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
|
||||
#define FORCEINLINE static inline __attribute__((always_inline))
|
||||
#elif defined(__ICCARM__)
|
||||
#define FORCEINLINE _Pragma("inline=force") static
|
||||
#else
|
||||
#define FORCEINLINE static inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** NORETURN
|
||||
* Declare a function that will never return.
|
||||
*
|
||||
* @code
|
||||
* #include "toolchain.h"
|
||||
*
|
||||
* NORETURN void foo() {
|
||||
* // must never return
|
||||
* while (1) {}
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#ifndef NORETURN
|
||||
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#elif defined(__ICCARM__)
|
||||
#define NORETURN __noreturn
|
||||
#else
|
||||
#define NORETURN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** UNREACHABLE
|
||||
* An unreachable statement. If the statement is reached,
|
||||
* behaviour is undefined. Useful in situations where the compiler
|
||||
* cannot deduce the unreachability of code.
|
||||
*
|
||||
* @code
|
||||
* #include "toolchain.h"
|
||||
*
|
||||
* void foo(int arg) {
|
||||
* switch (arg) {
|
||||
* case 1: return 1;
|
||||
* case 2: return 2;
|
||||
* ...
|
||||
* }
|
||||
* UNREACHABLE;
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#ifndef UNREACHABLE
|
||||
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
|
||||
#define UNREACHABLE __builtin_unreachable()
|
||||
#else
|
||||
#define UNREACHABLE while (1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** 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
|
||||
|
|
Loading…
Reference in New Issue