From 0a06817da12212b29cac740066fe51c89e1084af Mon Sep 17 00:00:00 2001 From: batt Date: Mon, 21 Feb 2011 22:27:21 +0000 Subject: [PATCH] Fix undefined behaviour. In the expression: (a) ^= (b) ^= (a) ^= (b) 'a' and 'b' are evaluated and assigned multiple times, and it is not clear in which order operations are performed. This patch re-write the XOR swap in a more canonical way. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4719 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/byteorder.h | 2 +- bertos/cpu/byteorder_test.c | 71 +++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 bertos/cpu/byteorder_test.c diff --git a/bertos/cpu/byteorder.h b/bertos/cpu/byteorder.h index 721f81e5..37d7a841 100644 --- a/bertos/cpu/byteorder.h +++ b/bertos/cpu/byteorder.h @@ -132,7 +132,7 @@ INLINE float swab_float(float x) /* Avoid breaking strict aliasing rules. */ char *cx = (char *)(&x); STATIC_ASSERT(sizeof(float) == 4); - #define BYTEORDER_SWAP(a, b) ((a) ^= (b) ^= (a) ^= (b)) + #define BYTEORDER_SWAP(a, b) do { (a) ^= (b); (b) ^= (a); (a) ^= (b); } while(0) BYTEORDER_SWAP(cx[0], cx[3]); BYTEORDER_SWAP(cx[1], cx[2]); #undef BYTEORDER_SWAP diff --git a/bertos/cpu/byteorder_test.c b/bertos/cpu/byteorder_test.c new file mode 100644 index 00000000..0064c621 --- /dev/null +++ b/bertos/cpu/byteorder_test.c @@ -0,0 +1,71 @@ +/** + * \file + * + * + * \brief byteorder.h macros test. + * + * \author Francesco Sacchi + */ + +#include +#include +#include + +#include "byteorder.h" + +int byteorder_testSetup(void) +{ + kdbg_init(); + return 0; +} + +int byteorder_testTearDown(void) +{ + return 0; +} + +int byteorder_testRun(void) +{ + float a; + float b; + float c; + + for (a = 0; a < 12345; a += 0.01) + { + b = swab_float(a); + c = swab_float(b); +// kprintf("a=%08lX, b=%08lX, c=%08lX\n", *((uint32_t *)&a), *((uint32_t *)&b), *((uint32_t *)&c)); + ASSERT(a == c); + } + return 0; +} + +TEST_MAIN(byteorder); -- 2.25.1