diff options
author | Benjamin Barenblat <bbaren@mit.edu> | 2016-04-03 23:25:53 -0400 |
---|---|---|
committer | Benjamin Barenblat <bbaren@mit.edu> | 2016-04-03 23:25:53 -0400 |
commit | 39d0dcb5a1f0b2434e4c4ee83ac1a1dc5397e60d (patch) | |
tree | ca2e5cf507ab82fc53f7f31d56daecca7b0ce06c | |
parent | 69ef8f9008c612656649c93f33d3a5279a6483bb (diff) |
Compile with -fno-strict-aliasing
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.
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/operations.cc | 9 |
2 files changed, 10 insertions, 0 deletions
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*>(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*>(file_info->fh); const std::vector<std::uint8_t> 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*>(file_info->fh); const std::vector<std::uint8_t> 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<Directory*>(file_info->fh); static_assert(std::is_same<off_t, long>(), @@ -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*>(file_info->fh)->Truncate(size); return 0; } |