add a test for -fno-strict-aliasing
Change-Id: I0548968b062b813a4c546c4ddf79861875841210
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/79207
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bb01da1..a052367 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -122,7 +122,7 @@
if(CMAKE_COMPILER_IS_GNUCXX OR CLANG)
# Note clang-cl is odd and sets both CLANG and MSVC. We base our configuration
# primarily on our normal Clang one.
- set(C_CXX_FLAGS "-Werror -Wformat=2 -Wsign-compare -Wwrite-strings -Wvla -Wshadow -Wtype-limits -Wmissing-field-initializers")
+ set(C_CXX_FLAGS "-fno-strict-aliasing -Werror -Wformat=2 -Wsign-compare -Wwrite-strings -Wvla -Wshadow -Wtype-limits -Wmissing-field-initializers")
if(MSVC)
# clang-cl sets different default warnings than clang. It also treats -Wall
# as -Weverything, to match MSVC. Instead -W3 is the alias for -Wall.
diff --git a/crypto/compiler_test.cc b/crypto/compiler_test.cc
index 95c3569..c65028f 100644
--- a/crypto/compiler_test.cc
+++ b/crypto/compiler_test.cc
@@ -21,6 +21,7 @@
#include "test/test_util.h"
+namespace {
// C and C++ have two forms of unspecified behavior: undefined behavior and
// implementation-defined behavior.
@@ -215,3 +216,31 @@
EXPECT_EQ(Bytes(bytes),
Bytes(reinterpret_cast<uint8_t *>(&null), sizeof(null)));
}
+
+static uintptr_t aba(uintptr_t *a, void **b) {
+ *a = (uintptr_t)1;
+ *b = NULL;
+ return *a; // 0 if a == b, 1 if a and b are disjoint
+}
+
+TEST(CompilerTest, NoStrictAliasing) {
+ // Sequential memory access must be sequentially consistent across types.
+ // Compilers such as clang and gcc need to be passed -fno-strict-aliasing
+ // for this to remain true at at higher optimization levels. Use with the
+ // opposite configuration, -fstrict-aliasing, is not supported.
+ // Even though some subset of type punning through memory is considered
+ // undefined behavior, the subtlety of exactly which subset that is and the
+ // limited sanitizer-tooling support make it impractical to avoid reliably.
+ uint8_t aliased[sizeof(void *)] = {};
+ uint8_t zeros[sizeof(void *)] = {};
+
+ OPENSSL_memset(aliased, -1, sizeof(aliased));
+ EXPECT_EQ(aba((uintptr_t *)aliased, (void **)aliased), (uintptr_t)0);
+ EXPECT_EQ(Bytes(aliased), Bytes(zeros));
+
+ volatile auto volatile_aba = &aba;
+ OPENSSL_memset(aliased, -1, sizeof(aliased));
+ EXPECT_EQ(volatile_aba((uintptr_t *)aliased, (void **)aliased), (uintptr_t)0);
+ EXPECT_EQ(Bytes(aliased), Bytes(zeros));
+}
+} // namespace