Avoid writing to and reading from misaligned pointers in UnitTests

Use of pointers which do not meet the alignment requirements of the underlying
type have undefined behaviour in C++.

This change replaces direct use of the pointers, with use of memcpy
to copy between aligned buffers and misaligned buffers.

Fixes errors found by -fsanitize=undefined

Signed-off-by: Matthew Bentham <matthew.bentham@arm.com>
Change-Id: Ia37a6b5aae2803d1d0e160d1646f711bfe647a60
diff --git a/src/backends/backendsCommon/test/EndToEndTestImpl.hpp b/src/backends/backendsCommon/test/EndToEndTestImpl.hpp
index c69a4a5..086f6b7 100644
--- a/src/backends/backendsCommon/test/EndToEndTestImpl.hpp
+++ b/src/backends/backendsCommon/test/EndToEndTestImpl.hpp
@@ -951,11 +951,12 @@
     uintptr_t alignment = GetDataTypeSize(DataType::Float32);
     CHECK (reinterpret_cast<uintptr_t>(misalignedMemPtr) % alignment);
 
-    auto inputBuffer = reinterpret_cast<float*>(misalignedMemPtr);
-    for (int i = 0; i < 4; i++)
+    std::vector<float> inputData
     {
-        inputBuffer[i] = 1.0f + static_cast<float>(i);
-    }
+         1.0f, 2.0f, 3.0f, 4.0f
+    };
+
+    std::memcpy(misalignedMemPtr, inputData.data(), 4*sizeof(float));
 
     std::vector<float> outputData(4);
     // Check our output buffer is aligned
@@ -1129,9 +1130,11 @@
         // Check the output is correct
     }
     unsigned int index = 0;
+    char outputData[expectedOutput.size() * sizeof(float)];
+    std::memcpy(outputData, misalignedMemPtr, expectedOutput.size() * sizeof(float));
     for (auto outputValue : expectedOutput)
     {
-        CHECK(outputValue == reinterpret_cast<float*>(misalignedMemPtr)[index]);
+        CHECK(outputValue == reinterpret_cast<float*>(outputData)[index]);
         ++index;
     }
     std::free(memPtr);
@@ -1183,11 +1186,11 @@
     // Check if our pointer is truly misaligned
     uintptr_t alignment = GetDataTypeSize(DataType::Float32);
     CHECK (reinterpret_cast<uintptr_t>(misalignedInputPtr) % alignment);
-    auto inputBuffer = reinterpret_cast<float*>(misalignedInputPtr);
-    for (int i = 0; i < 4; i++)
+    std::vector<float> inputData
     {
-        inputBuffer[i] = 1.0f + static_cast<float>(i);
-    }
+         1.0f, 2.0f, 3.0f, 4.0f
+    };
+    std::memcpy(misalignedInputPtr, inputData.data(), 4*sizeof(float));
 
     auto outputMemPtr = std::malloc(4 * sizeof(float) + sizeof(char));
     float* misalignedOutputPtr = reinterpret_cast<float*>(reinterpret_cast<char*>(outputMemPtr) + 1);
@@ -1238,9 +1241,11 @@
     }
     // Check the output is correct
     unsigned int index = 0;
-    for (auto outputValue : expectedOutput)
+    std::vector<float> outputData(expectedOutput.size());
+    std::memcpy(outputData.data(), misalignedOutputPtr, expectedOutput.size() * sizeof(float));
+    for (auto expectedValue : expectedOutput)
     {
-        CHECK(outputValue == reinterpret_cast<float*>(misalignedOutputPtr)[index]);
+        CHECK(expectedValue == outputData[index]);
         ++index;
     }
     std::free(inputMemPtr);
@@ -1356,11 +1361,13 @@
 
     // Check if our pointer is truly misaligned
     CHECK (reinterpret_cast<uintptr_t>(misalignedInputPtr) % alignment);
-    auto inputBuffer = reinterpret_cast<float*>(misalignedInputPtr);
-    for (int i = 0; i < 4; i++)
+
+    std::vector<float> inputValues
     {
-        inputBuffer[i] = 2.0f + static_cast<float>(i);
-    }
+         2.0f, 3.0f, 4.0f, 5.0f
+    };
+
+    std::memcpy(misalignedInputPtr, inputValues.data(), inputValues.size()*sizeof(float));
 
     auto outputMemPtr = std::malloc(4 * sizeof(float) + sizeof(char));
     float* misalignedOutputPtr = reinterpret_cast<float*>(reinterpret_cast<char*>(outputMemPtr) + 1);
@@ -1411,9 +1418,11 @@
     }
     // Check the output is correct
     unsigned int index = 0;
+    std::vector<float> alignedOutputData(expectedMisalignedOutput.size());
+    std::memcpy(alignedOutputData.data(), misalignedOutputPtr, expectedMisalignedOutput.size() * sizeof(float));
     for (auto outputValue : expectedMisalignedOutput)
     {
-        CHECK(outputValue == reinterpret_cast<float*>(misalignedOutputPtr)[index]);
+        CHECK(outputValue == alignedOutputData[index]);
         ++index;
     }
     // Clean up to avoid interfering with other tests
@@ -1471,11 +1480,11 @@
     // Check if our pointer is truly misaligned
     uintptr_t alignment = GetDataTypeSize(DataType::Float32);
     CHECK (reinterpret_cast<uintptr_t>(misalignedInputPtr) % alignment);
-    auto inputBuffer = reinterpret_cast<float*>(misalignedInputPtr);
-    for (int i = 0; i < 4; i++)
+    std::vector<float> inputValues
     {
-        inputBuffer[i] = 2.0f + static_cast<float>(i);
-    }
+         2.0f, 3.0f, 4.0f, 5.0f
+    };
+    std::memcpy(misalignedInputPtr, inputValues.data(), inputValues.size() * sizeof(float));
 
     auto outputMemPtr = std::malloc(4 * sizeof(float) + sizeof(char));
     float* misalignedOutputPtr = reinterpret_cast<float*>(reinterpret_cast<char*>(outputMemPtr) + 1);
@@ -1530,9 +1539,11 @@
     }
     // Check the output is correct
     unsigned int index = 0;
+    std::vector<float> alignedOutput(expectedMisalignedOutput.size());
+    std::memcpy(alignedOutput.data(), misalignedOutputPtr, expectedMisalignedOutput.size()*sizeof(float));
     for (auto outputValue : expectedMisalignedOutput)
     {
-        CHECK(outputValue == reinterpret_cast<float*>(misalignedOutputPtr)[index]);
+        CHECK(outputValue == alignedOutput[index]);
         ++index;
     }
     std::free(inputMemPtr);