core: Fix undefined behaviour in C11 atomics

Casting pointers to volatile memory to pointers to regular memory is permitted,
but using those pointers to access the memory results in undefined behavior.
This commit changes the casts to no longer drop the volatile qualifier.

References: https://en.cppreference.com/w/c/language/volatile
This commit is contained in:
Marian Buschsieweke 2019-05-15 14:31:01 +02:00
parent bf000a1fa5
commit 7749e621b8
No known key found for this signature in database
GPG Key ID: 61F64C6599B1539F

View File

@ -66,7 +66,7 @@ typedef uint64_t I8;
{ \
(void) memorder; \
unsigned int mask = irq_disable(); \
I##n old = *(I##n *)ptr; \
I##n old = *(const volatile I##n *)ptr; \
irq_restore(mask); \
return old; \
}
@ -81,7 +81,7 @@ typedef uint64_t I8;
{ \
(void) memorder; \
unsigned int mask = irq_disable(); \
*(I##n *)ptr = val; \
*(volatile I##n *)ptr = val; \
irq_restore(mask); \
}
@ -95,8 +95,8 @@ typedef uint64_t I8;
{ \
(void) memorder; \
unsigned int mask = irq_disable(); \
I##n old = *(I##n *)ptr; \
*(I##n *)ptr = desired; \
I##n old = *(volatile I##n *)ptr; \
*(volatile I##n *)ptr = desired; \
irq_restore(mask); \
return old; \
}
@ -114,14 +114,14 @@ typedef uint64_t I8;
(void) success_memorder; \
(void) failure_memorder; \
unsigned int mask = irq_disable(); \
I##n cur = *(I##n *)ptr; \
I##n cur = *(volatile I##n *)ptr; \
if (cur != *(I##n *)expected) { \
*(I##n *)expected = cur; \
irq_restore(mask); \
return false; \
} \
\
*(I##n *)ptr = desired; \
*(volatile I##n *)ptr = desired; \
irq_restore(mask); \
return true; \
}
@ -139,8 +139,8 @@ typedef uint64_t I8;
{ \
unsigned int mask = irq_disable(); \
(void)memmodel; \
I##n tmp = *(I##n *)ptr; \
*(I##n *)ptr = prefixop(tmp op val); \
I##n tmp = *(volatile I##n *)ptr; \
*(volatile I##n *)ptr = prefixop(tmp op val); \
irq_restore(mask); \
return tmp; \
}
@ -158,8 +158,8 @@ typedef uint64_t I8;
{ \
(void)memmodel; \
unsigned int mask = irq_disable(); \
I##n tmp = prefixop((*(I##n *)ptr) op val); \
*(I##n *)ptr = tmp; \
I##n tmp = prefixop((*(volatile I##n *)ptr) op val); \
*(volatile I##n *)ptr = tmp; \
irq_restore(mask); \
return tmp; \
}