From 39d0dcb5a1f0b2434e4c4ee83ac1a1dc5397e60d Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Sun, 3 Apr 2016 23:25:53 -0400 Subject: Compile with -fno-strict-aliasing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out I’ve misused reinterpret_cast in a few places. Fixing it would be challenging and not worth the slight performance boost from strict aliasing optimizations, so mark violations and disable strict aliasing. --- CMakeLists.txt | 1 + src/operations.cc | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2a7740..5862df7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftrapv") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong --param=ssp-buffer-size=4") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything -Wno-c++98-compat") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-padded") diff --git a/src/operations.cc b/src/operations.cc index bff7bce..99817a1 100644 --- a/src/operations.cc +++ b/src/operations.cc @@ -86,6 +86,9 @@ int Getattr(const char* const c_path, struct stat* output) { int Fgetattr(const char*, struct stat* const output, struct fuse_file_info* const file_info) { + // This reinterpret_cast violates type aliasing rules, so a compiler may + // invoke undefined behavior if *output is ever dereferenced. However, we + // compile with -fno-strict-aliasing, so this should be safe. *output = reinterpret_cast(file_info->fh)->Stat(); return 0; } @@ -152,6 +155,9 @@ int Open(const char* const path, fuse_file_info* const file_info) { int Read(const char*, char* const buffer, const size_t bytes, const off_t offset, fuse_file_info* const file_info) { + // This reinterpret_cast violates type aliasing rules, so a compiler may + // invoke undefined behavior when file is dereferenced on the next line. + // However, we compile with -fno-strict-aliasing, so it should be safe. auto* const file = reinterpret_cast(file_info->fh); const std::vector read = file->Read(offset, bytes); std::memcpy(buffer, read.data(), read.size()); @@ -160,6 +166,7 @@ int Read(const char*, char* const buffer, const size_t bytes, int Write(const char*, const char* const buffer, const size_t bytes, const off_t offset, fuse_file_info* const file_info) { + // See notes in Read about undefined behavior. auto* const file = reinterpret_cast(file_info->fh); const std::vector to_write(buffer, buffer + bytes); file->Write(offset, to_write); @@ -209,6 +216,7 @@ int Opendir(const char* const path, fuse_file_info* const file_info) { int Readdir(const char*, void* const buffer, fuse_fill_dir_t filler, const off_t offset, fuse_file_info* const file_info) { + // See notes in Read about undefined behavior. auto* const directory = reinterpret_cast(file_info->fh); static_assert(std::is_same(), @@ -246,6 +254,7 @@ int Truncate(const char* const c_path, const off_t size) { } int Ftruncate(const char*, const off_t size, fuse_file_info* const file_info) { + // See notes in Read about undefined behavior. reinterpret_cast(file_info->fh)->Truncate(size); return 0; } -- cgit v1.2.3