From 464966135e5cc7af30d9a3f6bdc81be937b95ac3 Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Fri, 1 Jul 2022 09:53:55 +0200
Subject: [PATCH] fix(core): use of compound volatile operations (deprecated in
 C++20)

C++20 deprecated compound volatile operations, so this code fails to
compile in C++20 mode due to -Werror.

Fix by separating loading and saving of the value, which, in the case
of architecture_definitions.h, even reduces the per-operation loads
from two to one.

Fixes: #5247
---
 include/open62541/architecture_definitions.h | 24 +++++++++++++-------
 include/open62541/util.h                     |  2 +-
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/include/open62541/architecture_definitions.h b/include/open62541/architecture_definitions.h
index f22f401d..15a21505 100644
--- a/include/open62541/architecture_definitions.h
+++ b/include/open62541/architecture_definitions.h
@@ -456,8 +456,10 @@ UA_atomic_addUInt32(volatile uint32_t *addr, uint32_t increase) {
     return __sync_add_and_fetch(addr, increase);
 #endif
 #else
-    *addr += increase;
-    return *addr;
+    uint32_t accu = *addr;
+    accu += increase;
+    *addr = accu;
+    return accu;
 #endif
 }
 
@@ -470,8 +472,10 @@ UA_atomic_addSize(volatile size_t *addr, size_t increase) {
     return __sync_add_and_fetch(addr, increase);
 #endif
 #else
-    *addr += increase;
-    return *addr;
+    size_t accu = *addr;
+    accu += increase;
+    *addr = accu;
+    return accu;
 #endif
 }
 
@@ -484,8 +488,10 @@ UA_atomic_subUInt32(volatile uint32_t *addr, uint32_t decrease) {
     return __sync_sub_and_fetch(addr, decrease);
 #endif
 #else
-    *addr -= decrease;
-    return *addr;
+    uint32_t accu = *addr;
+    accu -= decrease;
+    *addr = accu;
+    return accu;
 #endif
 }
 
@@ -498,8 +504,10 @@ UA_atomic_subSize(volatile size_t *addr, size_t decrease) {
     return __sync_sub_and_fetch(addr, decrease);
 #endif
 #else
-    *addr -= decrease;
-    return *addr;
+    size_t accu = *addr;
+    accu -= decrease;
+    *addr = accu;
+    return accu;
 #endif
 }
 
diff --git a/include/open62541/util.h b/include/open62541/util.h
index 79e49f20..9f3b5fea 100644
--- a/include/open62541/util.h
+++ b/include/open62541/util.h
@@ -213,7 +213,7 @@ UA_constantTimeEqual(const void *ptr1, const void *ptr2, size_t length) {
     volatile UA_Byte c = 0;
     for(size_t i = 0; i < length; ++i) {
         UA_Byte x = a[i], y = b[i];
-        c |= x ^ y;
+        c = c | (x ^ y);
     }
     return !c;
 }
-- 
2.25.1

