Skip to content

Commit 018e257

Browse files
committed
Added other attributes on supported compilers
tested on GCC, Clang, online compiler, and IAR attributes - PACK - ALIGN - UNUSED - WEAK - PURE - FORCEINLINE - NORETURN - UNREACHABLE - DEPRECATED
1 parent f05240b commit 018e257

File tree

3 files changed

+217
-27
lines changed

3 files changed

+217
-27
lines changed

hal/TESTS/api/toolchain/attributes.c

Lines changed: 90 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,57 @@
44
#include <stdint.h>
55

66

7-
struct TestAttrPackedStruct {
7+
typedef struct {
88
char a;
99
int x;
10-
} PACKED;
10+
} PACKED TestAttrPackedStruct;
1111

1212
int testPacked() {
1313
int failed = 0;
1414

15-
if (sizeof(struct TestAttrPackedStruct) != sizeof(int) + sizeof(char)) {
15+
if (sizeof(TestAttrPackedStruct) != sizeof(int) + sizeof(char)) {
1616
failed++;
1717
}
1818

1919
return failed;
2020
}
2121

2222

23-
int testUnused1(UNUSED int arg) {
24-
return 0;
25-
}
23+
int testAlign() {
24+
int failed = 0;
2625

27-
int testUnused() {
28-
return testUnused1(0);
29-
}
26+
ALIGN(8) char a;
27+
ALIGN(8) char b;
28+
ALIGN(16) char c;
29+
ALIGN(8) char d;
30+
ALIGN(16) char e;
3031

32+
if(((uintptr_t)&a) & 0x7){
33+
failed++;
34+
}
35+
if(((uintptr_t)&b) & 0x7){
36+
failed++;
37+
}
38+
if(((uintptr_t)&c) & 0xf){
39+
failed++;
40+
}
41+
if(((uintptr_t)&d) & 0x7){
42+
failed++;
43+
}
44+
if(((uintptr_t)&e) & 0xf){
45+
failed++;
46+
}
3147

32-
DEPRECATED("this message should not be displayed")
33-
void testDeprecatedUnused();
34-
void testDeprecatedUnused() { }
48+
return failed;
49+
}
3550

36-
DEPRECATED("this message should be displayed")
37-
int testDeprecatedUsed();
38-
int testDeprecatedUsed() {
51+
52+
int testUnused1(UNUSED int arg) {
3953
return 0;
4054
}
4155

42-
int testDeprecated() {
43-
return testDeprecatedUsed();
56+
int testUnused() {
57+
return testUnused1(0);
4458
}
4559

4660

@@ -59,3 +73,62 @@ int testWeak() {
5973
return testWeak1() | testWeak2();
6074
}
6175

76+
77+
PURE int testPure1() {
78+
return 0;
79+
}
80+
81+
int testPure() {
82+
return testPure1();
83+
}
84+
85+
86+
FORCEINLINE int testForceInline1() {
87+
return 0;
88+
}
89+
90+
int testForceInline() {
91+
return testForceInline1();
92+
}
93+
94+
95+
NORETURN int testNoReturn1() {
96+
while (1) {}
97+
}
98+
99+
int testNoReturn() {
100+
if (0) {
101+
testNoReturn1();
102+
}
103+
return 0;
104+
}
105+
106+
107+
int testUnreachable1(int i) {
108+
switch (i) {
109+
case 0:
110+
return 0;
111+
}
112+
113+
UNREACHABLE;
114+
}
115+
116+
int testUnreachable() {
117+
return testUnreachable1(0);
118+
}
119+
120+
121+
DEPRECATED("this message should not be displayed")
122+
void testDeprecatedUnused();
123+
void testDeprecatedUnused() { }
124+
125+
DEPRECATED("this message should be displayed")
126+
int testDeprecatedUsed();
127+
int testDeprecatedUsed() {
128+
return 0;
129+
}
130+
131+
int testDeprecated() {
132+
return testDeprecatedUsed();
133+
}
134+

hal/TESTS/api/toolchain/main.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ using namespace utest::v1;
1212
// Test functions declared as C functions to avoid issues with name mangling
1313
extern "C" {
1414
int testPacked();
15+
int testAlign();
1516
int testUnused();
16-
int testDeprecated();
1717
int testWeak();
18+
int testPure();
19+
int testForceInline();
20+
int testNoReturn();
21+
int testUnreachable();
22+
int testDeprecated();
1823
}
1924

2025

@@ -30,10 +35,15 @@ status_t test_setup(const size_t number_of_cases) {
3035
}
3136

3237
Case cases[] = {
33-
Case("Testing PACKED attribute", test_wrapper<testPacked>),
34-
Case("Testing UNUSED attribute", test_wrapper<testUnused>),
35-
Case("Testing DEPRECATED attribute", test_wrapper<testDeprecated>),
36-
Case("Testing WEAK attribute", test_wrapper<testWeak>),
38+
Case("Testing PACKED attribute", test_wrapper<testPacked>),
39+
Case("Testing ALIGN attribute", test_wrapper<testAlign>),
40+
Case("Testing UNUSED attribute", test_wrapper<testUnused>),
41+
Case("Testing WEAK attribute", test_wrapper<testWeak>),
42+
Case("Testing PURE attribute", test_wrapper<testPure>),
43+
Case("Testing FORCEINLINE attribute", test_wrapper<testForceInline>),
44+
Case("Testing NORETURN attribute", test_wrapper<testNoReturn>),
45+
Case("Testing UNREACHABLE attribute", test_wrapper<testUnreachable>),
46+
Case("Testing DEPRECATED attribute", test_wrapper<testDeprecated>),
3747
};
3848

3949
Specification specification(test_setup, cases);

hal/api/toolchain.h

Lines changed: 112 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@
2828

2929
// Attributes
3030

31-
/** PACK
31+
/** PACKED
3232
* Pack a structure, preventing any padding from being added between fields.
3333
*
3434
* @code
3535
* #include "toolchain.h"
3636
*
37-
* struct foo {
37+
* typedef struct {
3838
* char x;
3939
* int y;
40-
* } PACKED;
40+
* } PACKED foo;
4141
* @endcode
4242
*/
4343
#ifndef PACKED
@@ -48,19 +48,37 @@
4848
#endif
4949
#endif
5050

51+
/** ALIGN(N)
52+
* Declare a variable to be aligned on an N-byte boundary.
53+
*
54+
* @code
55+
* #include "toolchain.h"
56+
*
57+
* ALIGN(16) char a;
58+
* @endcode
59+
*/
60+
#ifndef ALIGN
61+
#if defined(__ICCARM__)
62+
#define _ALIGN(N) _Pragma(#N)
63+
#define ALIGN(N) _ALIGN(data_alignment=N)
64+
#else
65+
#define ALIGN(N) __attribute__((aligned(N)))
66+
#endif
67+
#endif
68+
5169
/** UNUSED
5270
* Declare a function argument to be unused, suppressing compiler warnings
5371
*
5472
* @code
5573
* #include "toolchain.h"
5674
*
57-
* void foo(UNUSED int arg){
75+
* void foo(UNUSED int arg) {
5876
*
5977
* }
6078
* @endcode
6179
*/
6280
#ifndef UNUSED
63-
#if defined(__GNUC__) || defined(__CC_ARM) || defined(__clang__)
81+
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
6482
#define UNUSED __attribute__((__unused__))
6583
#else
6684
#define UNUSED
@@ -93,6 +111,95 @@
93111
#endif
94112
#endif
95113

114+
/** PURE
115+
* Hint to the compiler that a function depends only on parameters
116+
*
117+
* @code
118+
* #include "toolchain.h"
119+
*
120+
* PURE int foo(int arg){
121+
* // no access to global variables
122+
* }
123+
* @endcode
124+
*/
125+
#ifndef PURE
126+
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
127+
#define PURE __attribute__((const))
128+
#else
129+
#define PURE
130+
#endif
131+
#endif
132+
133+
/** FORCEINLINE
134+
* Declare a function that must always be inlined. Failure to inline
135+
* such a function will result in an error.
136+
*
137+
* @code
138+
* #include "toolchain.h"
139+
*
140+
* FORCEINLINE void foo() {
141+
*
142+
* }
143+
* @endcode
144+
*/
145+
#ifndef FORCEINLINE
146+
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
147+
#define FORCEINLINE static inline __attribute__((always_inline))
148+
#elif defined(__ICCARM__)
149+
#define FORCEINLINE _Pragma("inline=force") static
150+
#else
151+
#define FORCEINLINE static inline
152+
#endif
153+
#endif
154+
155+
/** NORETURN
156+
* Declare a function that will never return.
157+
*
158+
* @code
159+
* #include "toolchain.h"
160+
*
161+
* NORETURN void foo() {
162+
* // must never return
163+
* while (1) {}
164+
* }
165+
* @endcode
166+
*/
167+
#ifndef NORETURN
168+
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
169+
#define NORETURN __attribute__((noreturn))
170+
#elif defined(__ICCARM__)
171+
#define NORETURN __noreturn
172+
#else
173+
#define NORETURN
174+
#endif
175+
#endif
176+
177+
/** UNREACHABLE
178+
* An unreachable statement. If the statement is reached,
179+
* behaviour is undefined. Useful in situations where the compiler
180+
* cannot deduce the unreachability of code.
181+
*
182+
* @code
183+
* #include "toolchain.h"
184+
*
185+
* void foo(int arg) {
186+
* switch (arg) {
187+
* case 1: return 1;
188+
* case 2: return 2;
189+
* ...
190+
* }
191+
* UNREACHABLE;
192+
* }
193+
* @endcode
194+
*/
195+
#ifndef UNREACHABLE
196+
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__CC_ARM)
197+
#define UNREACHABLE __builtin_unreachable()
198+
#else
199+
#define UNREACHABLE while (1)
200+
#endif
201+
#endif
202+
96203
/** DEPRECATED("message string")
97204
* Mark a function declaration as deprecated, if it used then a warning will be
98205
* issued by the compiler possibly including the provided message. Note that not

0 commit comments

Comments
 (0)