aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@mit.edu>2016-04-03 23:25:53 -0400
committerGravatar Benjamin Barenblat <bbaren@mit.edu>2016-04-03 23:25:53 -0400
commit39d0dcb5a1f0b2434e4c4ee83ac1a1dc5397e60d (patch)
treeca2e5cf507ab82fc53f7f31d56daecca7b0ce06c
parent69ef8f9008c612656649c93f33d3a5279a6483bb (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.txt1
-rw-r--r--src/operations.cc9
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;
}