Enable -Wstrict-aliasing=1 (GCC)

Fixed partially.
This commit is contained in:
Nekotekina 2021-03-08 23:41:23 +03:00
parent 3990e2d3e6
commit a4fdbf0a88
34 changed files with 141 additions and 81 deletions

View File

@ -1301,7 +1301,9 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
static_assert(sizeof(iovec) == sizeof(iovec_clone), "Weird iovec size");
static_assert(offsetof(iovec, iov_len) == offsetof(iovec_clone, iov_len), "Weird iovec::iov_len offset");
const auto result = ::writev(m_fd, reinterpret_cast<const iovec*>(buffers), buf_count);
iovec arg;
std::memcpy(&arg, buffers, sizeof(arg));
const auto result = ::writev(m_fd, &arg, buf_count);
ensure(result != -1); // "file::write_gather"
return result;

View File

@ -282,6 +282,7 @@ asmjit::Runtime& asmjit::get_global_runtime()
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/FormattedStream.h"

View File

@ -14,6 +14,7 @@
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#include <asmjit/asmjit.h>
#pragma GCC diagnostic pop
#endif
@ -180,6 +181,7 @@ inline FT build_function_asm(F&& builder)
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wsuggest-override"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#ifdef __clang__
#pragma clang diagnostic ignored "-Winconsistent-missing-override"
#endif

View File

@ -344,7 +344,9 @@ struct fmt::cfmt_src
template <typename T>
T get(usz index) const
{
return *reinterpret_cast<const T*>(reinterpret_cast<const u8*>(args + index));
T res{};
std::memcpy(&res, reinterpret_cast<const u8*>(args + index), sizeof(res));
return res;
}
void skip(usz extra)

View File

@ -1261,7 +1261,9 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
{
if (op == X64OP_NONE)
{
sig_log.error("decode_x64_reg_op(%p): unsupported opcode: %s", code, *reinterpret_cast<const be_t<v128, 1>*>(code));
be_t<v128> dump;
std::memcpy(&dump, code, sizeof(dump));
sig_log.error("decode_x64_reg_op(%p): unsupported opcode: %s", code, dump);
}
};

View File

@ -547,58 +547,70 @@ static std::basic_string<u32> apply_modification(const patch_engine::patch_info&
}
case patch_type::le16:
{
*reinterpret_cast<le_t<u16, 1>*>(ptr) = static_cast<u16>(p.value.long_value);
le_t<u16> val = static_cast<u16>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::le32:
{
*reinterpret_cast<le_t<u32, 1>*>(ptr) = static_cast<u32>(p.value.long_value);
le_t<u32> val = static_cast<u32>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::lef32:
{
*reinterpret_cast<le_t<u32, 1>*>(ptr) = std::bit_cast<u32, f32>(static_cast<f32>(p.value.double_value));
le_t<f32> val = static_cast<f32>(p.value.double_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::le64:
{
*reinterpret_cast<le_t<u64, 1>*>(ptr) = static_cast<u64>(p.value.long_value);
le_t<u64> val = static_cast<u64>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::lef64:
{
*reinterpret_cast<le_t<u64, 1>*>(ptr) = std::bit_cast<u64, f64>(p.value.double_value);
le_t<f64> val = p.value.double_value;
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::be16:
{
*reinterpret_cast<be_t<u16, 1>*>(ptr) = static_cast<u16>(p.value.long_value);
be_t<u16> val = static_cast<u16>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::bd32:
{
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value.long_value);
be_t<u32> val = static_cast<u32>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::be32:
{
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value.long_value);
if (offset % 4 == 0) resval = offset;
be_t<u32> val = static_cast<u32>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
if (offset % 4 == 0)
resval = offset;
break;
}
case patch_type::bef32:
{
*reinterpret_cast<be_t<u32, 1>*>(ptr) = std::bit_cast<u32, f32>(static_cast<f32>(p.value.double_value));
be_t<f32> val = static_cast<f32>(p.value.double_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::bd64:
{
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value.long_value);
be_t<u64> val = static_cast<u64>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::be64:
{
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value.long_value);
be_t<u64> val = static_cast<u64>(p.value.long_value);
std::memcpy(ptr, &val, sizeof(val));
if (offset % 4)
{
@ -611,7 +623,8 @@ static std::basic_string<u32> apply_modification(const patch_engine::patch_info&
}
case patch_type::bef64:
{
*reinterpret_cast<be_t<u64, 1>*>(ptr) = std::bit_cast<u64, f64>(p.value.double_value);
be_t<f64> val = p.value.double_value;
std::memcpy(ptr, &val, sizeof(val));
break;
}
case patch_type::utf8:

View File

@ -10,6 +10,7 @@
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/IRBuilder.h"

View File

@ -7,7 +7,9 @@ const ppu_decoder<PPUDisAsm> s_ppu_disasm;
u32 PPUDisAsm::disasm(u32 pc)
{
dump_pc = pc;
m_op = *reinterpret_cast<const atomic_be_t<u32>*>(m_offset + pc);
be_t<u32> op{};
std::memcpy(&op, m_offset + pc, 4);
m_op = op;
(this->*(s_ppu_disasm.decode(m_op)))({ m_op });
return 4;
}

View File

@ -3411,9 +3411,11 @@ bool ppu_interpreter::MFOCRF(ppu_thread& ppu, ppu_opcode_t op)
else
{
// MFCR
auto* lanes = reinterpret_cast<be_t<v128>*>(+ppu.cr.bits);
const u32 mh = _mm_movemask_epi8(_mm_slli_epi64(lanes[0].value().vi, 7));
const u32 ml = _mm_movemask_epi8(_mm_slli_epi64(lanes[1].value().vi, 7));
be_t<v128> lane0, lane1;
std::memcpy(&lane0, ppu.cr.bits, sizeof(v128));
std::memcpy(&lane1, ppu.cr.bits + 16, sizeof(v128));
const u32 mh = _mm_movemask_epi8(_mm_slli_epi64(lane0.value().vi, 7));
const u32 ml = _mm_movemask_epi8(_mm_slli_epi64(lane0.value().vi, 7));
ppu.gpr[op.rd] = (mh << 16) | ml;
}

View File

@ -344,12 +344,8 @@ static void ppu_initialize_modules(ppu_linkage_info* link)
alloc_addr += variable.second.size;
}
if (variable.second.var)
{
variable.second.var->set(variable.second.addr);
}
ppu_loader.trace("Allocated HLE variable %s.%s at 0x%x", _module->name, variable.second.name, variable.second.var->addr());
*variable.second.var = variable.second.addr;
ppu_loader.trace("Allocated HLE variable %s.%s at 0x%x", _module->name, variable.second.name, *variable.second.var);
// Initialize HLE variable
if (variable.second.init)

View File

@ -54,7 +54,7 @@ struct ppu_static_function
struct ppu_static_variable
{
const char* name;
vm::gvar<char>* var; // Pointer to variable address storage
u32* var; // Pointer to variable address storage
void(*init)(); // Variable initialization function
u32 size;
u32 align;
@ -144,7 +144,7 @@ public:
auto& info = access_static_variable(_module, vnid);
info.name = name;
info.var = reinterpret_cast<vm::gvar<char>*>(Var);
info.var = &Var->raw();
info.init = [] {};
info.size = gvar::alloc_size;
info.align = gvar::alloc_align;

View File

@ -31,6 +31,7 @@
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MemoryBuffer.h"

View File

@ -13,7 +13,9 @@ const spu_decoder<spu_iflag> s_spu_iflag;
u32 SPUDisAsm::disasm(u32 pc)
{
dump_pc = pc;
m_op = *reinterpret_cast<const atomic_be_t<u32>*>(m_offset + pc);
be_t<u32> op;
std::memcpy(&op, m_offset + pc, 4);
m_op = op;
(this->*(s_spu_disasm.decode(m_op)))({ m_op });
return 4;
}

View File

@ -3221,6 +3221,7 @@ void spu_recompiler_base::dump(const spu_program& result, std::string& out)
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
#include "llvm/ADT/Triple.h"
#include "llvm/IR/LegacyPassManager.h"

View File

@ -2161,7 +2161,7 @@ void spu_thread::do_dma_transfer(spu_thread* _this, const spu_mfc_cmd& args, u8*
auto& res = vm::reservation_acquire(eal);
// Lock each bit corresponding to a byte being written, using some free space in reservation memory
auto* bits = reinterpret_cast<atomic_t<u128>*>(vm::g_reservations + (eal & 0xff80) / 2 + 16);
auto* bits = reinterpret_cast<atomic_t<u128>*>(vm::g_reservations + ((eal & 0xff80) / 2 + 16));
// Get writing mask
const u128 wmask = (~u128{} << (eal & 127)) & (~u128{} >> (127 - ((eal + size0 - 1) & 127)));
@ -4735,7 +4735,8 @@ bool spu_thread::capture_local_storage() const
for (; pc0; pc0 -= 4)
{
const u32 op = *std::launder(reinterpret_cast<be_t<u32, 1>*>(prog.bin.data() + pc0 - 4));
be_t<u32> op;
std::memcpy(&op, prog.bin.data() + pc0 - 4, 4);
// Try to find function entry (if they are placed sequentially search for BI $LR of previous function)
if (!op || op == 0x35000000u || s_spu_itype.decode(op) == spu_itype::UNK)

View File

@ -211,6 +211,12 @@ namespace vm
{
return vm::try_access(vm::cast(m_addr), const_cast<T*>(&_in), sizeof(T), true);
}
// Don't use
auto& raw()
{
return m_addr;
}
};
template<typename AT, typename RT, typename... T>
@ -262,6 +268,12 @@ namespace vm
return vm::cast(m_addr);
}
// Don't use
auto& raw()
{
return m_addr;
}
// Callback; defined in PPUCallback.h, passing context is mandatory
RT operator()(ppu_thread& ppu, T... args) const;
const ppu_func_opd_t& opd() const;

View File

@ -140,13 +140,12 @@ namespace
}
}
if (remaining)
for (u32 i = 0; i < remaining; ++i)
{
const auto src_ptr2 = reinterpret_cast<const se_t<u32, true, 1>*>(src_ptr);
const auto dst_ptr2 = reinterpret_cast<nse_t<u32, 1>*>(dst_ptr);
for (u32 i = 0; i < remaining; ++i)
dst_ptr2[i] = src_ptr2[i];
be_t<u32> val;
std::memcpy(&val, src_ptr + i * sizeof(val), sizeof(val));
le_t<u32> nval = +val;
std::memcpy(dst_ptr + i * sizeof(nval), &nval, sizeof(nval));
}
}
@ -218,20 +217,18 @@ namespace
const u32 remaining = dword_count % 4;
if (remaining)
for (u32 i = 0; i < remaining; ++i)
{
const auto src_ptr2 = reinterpret_cast<const se_t<u32, true, 1>*>(src_ptr);
const auto dst_ptr2 = reinterpret_cast<nse_t<u32, 1>*>(dst_ptr);
be_t<u32> val;
std::memcpy(&val, src_ptr + i * sizeof(val), sizeof(val));
le_t<u32> nval;
std::memcpy(&nval, dst_ptr + i * sizeof(nval), sizeof(nval));
for (u32 i = 0; i < remaining; ++i)
if (val != nval)
{
const u32 data = src_ptr2[i];
if (dst_ptr2[i] != data)
{
dst_ptr2[i] = data;
bits_diff = _mm_set1_epi64x(-1);
}
nval = val;
std::memcpy(dst_ptr + i * sizeof(nval), &nval, sizeof(nval));
bits_diff = _mm_set1_epi64x(-1);
}
}
@ -283,13 +280,12 @@ namespace
}
}
if (remaining)
for (u32 i = 0; i < remaining; ++i)
{
auto src_ptr2 = reinterpret_cast<const se_t<u16, true, 1>*>(src_ptr);
auto dst_ptr2 = reinterpret_cast<nse_t<u16, 1>*>(dst_ptr);
for (u32 i = 0; i < remaining; ++i)
dst_ptr2[i] = src_ptr2[i];
be_t<u16> val;
std::memcpy(&val, src_ptr + i * sizeof(val), sizeof(val));
le_t<u16> nval = +val;
std::memcpy(dst_ptr + i * sizeof(nval), &nval, sizeof(nval));
}
}

View File

@ -3,10 +3,10 @@
#include "Emu/RSX/RSXFragmentProgram.h"
#include "Emu/RSX/RSXVertexProgram.h"
#include "Utilities/hash.h"
#include "Utilities/mutex.h"
#include "util/logs.hpp"
#include "Utilities/span.h"
#include "util/fnv_hash.hpp"
#include <deque>
#include <unordered_map>

View File

@ -1,7 +1,7 @@
#include "stdafx.h"
#include "texture_cache_utils.h"
#include "Utilities/address_range.h"
#include "Utilities/hash.h"
#include "util/fnv_hash.hpp"
namespace rsx
{

View File

@ -115,10 +115,10 @@ namespace gl
virtual void bind_resources() {}
virtual void cleanup_resources() {}
virtual void upload_vertex_data(f32* data, u32 elements_count)
template <typename T>
void upload_vertex_data(T* data, u32 elements_count)
{
elements_count <<= 2;
m_vertex_data_buffer.data(elements_count, data);
m_vertex_data_buffer.data(elements_count * sizeof(T), data);
}
virtual void emit_geometry()
@ -594,7 +594,7 @@ namespace gl
for (auto &cmd : ui.get_compiled().draw_commands)
{
set_primitive_type(cmd.config.primitives);
upload_vertex_data(reinterpret_cast<f32*>(cmd.verts.data()), ::size32(cmd.verts) * 4u);
upload_vertex_data(cmd.verts.data(), ::size32(cmd.verts));
num_drawable_elements = ::size32(cmd.verts);
GLint texture_read = GL_TRUE;

View File

@ -2169,7 +2169,8 @@ namespace rsx
{
if (layout.attribute_placement[index] == attribute_buffer_placement::none)
{
reinterpret_cast<u64*>(buffer)[index] = 0;
static constexpr u64 zero = 0;
std::memcpy(buffer + index * 2, &zero, sizeof(zero));
continue;
}

View File

@ -45,6 +45,7 @@ private:
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsuggest-override"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#ifdef __clang__
#pragma clang diagnostic ignored "-Winconsistent-missing-override"
#endif

View File

@ -14,8 +14,8 @@
#include "../Overlays/overlays.h"
#include "Utilities/hash.h"
#include <unordered_map>
#include "util/fnv_hash.hpp"
#define VK_OVERLAY_MAX_DRAW_CALLS 1024
@ -180,11 +180,12 @@ namespace vk
return {};
}
void upload_vertex_data(f32 *data, u32 count)
template <typename T>
void upload_vertex_data(T* data, u32 count)
{
check_heap();
const auto size = count * sizeof(f32);
const auto size = count * sizeof(T);
m_vao_offset = static_cast<u32>(m_vao.alloc<16>(size));
auto dst = m_vao.map(m_vao_offset, size);
std::memcpy(dst, data, size);
@ -812,9 +813,8 @@ namespace vk
for (auto &command : ui.get_compiled().draw_commands)
{
num_drawable_elements = static_cast<u32>(command.verts.size());
const u32 value_count = num_drawable_elements * 4;
upload_vertex_data(reinterpret_cast<f32*>(command.verts.data()), value_count);
upload_vertex_data(command.verts.data(), num_drawable_elements);
set_primitive_type(command.config.primitives);
m_skip_texture_read = false;

View File

@ -1,9 +1,9 @@
#pragma once
#include "../rsx_utils.h"
#include "Utilities/hash.h"
#include "Utilities/lockless.h"
#include "VKProgramPipeline.h"
#include "vkutils/graphics_pipeline_state.hpp"
#include "util/fnv_hash.hpp"
namespace vk
{

View File

@ -2,10 +2,11 @@
#include "VKVertexProgram.h"
#include "VKFragmentProgram.h"
#include "../Common/ProgramStateCache.h"
#include "Utilities/hash.h"
#include "VKRenderPass.h"
#include "VKPipelineCompiler.h"
#include "util/fnv_hash.hpp"
namespace vk
{
struct VKTraits

View File

@ -1,5 +1,4 @@
#pragma once
#include "Utilities/hash.h"
#include "Utilities/File.h"
#include "Utilities/lockless.h"
#include "Utilities/Thread.h"
@ -17,6 +16,7 @@
#include "util/vm.hpp"
#include "util/sysinfo.hpp"
#include "util/fnv_hash.hpp"
namespace rsx
{

View File

@ -12,6 +12,7 @@
#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
extern "C"
{

View File

@ -35,14 +35,23 @@ else()
add_compile_options(-Wunused-parameter)
add_compile_options(-Wignored-qualifiers)
#add_compile_options(-Wdeprecated-copy)
#add_compile_options(-Wtautological-compare)
#add_compile_options(-Wshadow)
#add_compile_options(-Wconversion)
#add_compile_options(-Wpadded)
add_compile_options(-Wempty-body)
add_compile_options(-Wstrict-aliasing=1)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Werror=inconsistent-missing-override)
elseif(CMAKE_COMPILER_IS_GNUCXX)
add_compile_options(-Werror=suggest-override)
add_compile_options(-Wclobbered)
add_compile_options(-Wcast-function-type)
#add_compile_options(-Wduplicated-branches)
#add_compile_options(-Wduplicated-cond)
#add_compile_options(-Wredundant-decls)
endif()
#TODO Clean the code so these are removed

View File

@ -499,7 +499,7 @@
<ClInclude Include="..\Utilities\CRC.h" />
<ClInclude Include="..\Utilities\date_time.h" />
<ClInclude Include="..\Utilities\geometry.h" />
<ClInclude Include="..\Utilities\hash.h" />
<ClInclude Include="util\fnv_hash.hpp" />
<ClInclude Include="..\Utilities\JIT.h" />
<ClInclude Include="..\Utilities\lockless.h" />
<ClInclude Include="..\Utilities\mutex.h" />

View File

@ -1645,7 +1645,7 @@
<ClInclude Include="Emu\RSX\Common\GLSLCommon.h">
<Filter>Emu\GPU\RSX\Common</Filter>
</ClInclude>
<ClInclude Include="..\Utilities\hash.h">
<ClInclude Include="util\fnv_hash.hpp">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="Emu\Cell\lv2\sys_gamepad.h">

View File

@ -16,6 +16,7 @@
#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#include <stb_image.h>
#include <stb_truetype.h>
#pragma GCC diagnostic pop

View File

@ -1,42 +1,45 @@
#pragma once
#include "util/types.hpp"
#include <cstring>
namespace rpcs3
{
constexpr usz fnv_seed = 14695981039346656037ull;
constexpr usz fnv_prime = 1099511628211ull;
template<typename T>
template <typename T>
static usz hash_base(T value)
{
return static_cast<usz>(value);
}
template<typename T, typename = std::enable_if_t<std::is_integral<T>::value, bool>>
static inline usz hash64(usz hash_value, const T data)
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
static inline usz hash64(usz hash_value, T data)
{
hash_value ^= data;
hash_value *= fnv_prime;
return hash_value;
}
template<typename T, typename U>
template <typename T, typename U>
static usz hash_struct_base(const T& value)
{
// FNV 64-bit
usz result = fnv_seed;
const U *bits = reinterpret_cast<const U*>(&value);
const uchar* bits = reinterpret_cast<const uchar*>(&value);
for (usz n = 0; n < (sizeof(T) / sizeof(U)); ++n)
{
result = hash64(result, bits[n]);
U val{};
std::memcpy(&val, bits + (n * sizeof(U)), sizeof(U));
result = hash64(result, val);
}
return result;
}
template<typename T>
template <typename T>
static usz hash_struct(const T& value)
{
static constexpr auto block_sz = sizeof(T);

View File

@ -258,6 +258,12 @@ namespace stx
r.m_ptr = static_cast<decltype(r.m_ptr)>(std::exchange(m_ptr, nullptr));
return r;
}
// Raw access for make_single()
auto& raw() noexcept
{
return m_ptr;
}
};
#ifndef _MSC_VER
@ -302,11 +308,11 @@ namespace stx
if constexpr (std::is_array_v<T>)
{
reinterpret_cast<etype*&>(r) = +ptr->m_data;
r.raw() = +ptr->m_data;
}
else
{
reinterpret_cast<etype*&>(r) = &ptr->m_data;
r.raw() = &ptr->m_data;
}
return r;
@ -370,7 +376,7 @@ namespace stx
};
single_ptr<T> r;
reinterpret_cast<std::remove_extent_t<T>*&>(r) = std::launder(arr);
r.raw() = std::launder(arr);
return r;
}

View File

@ -13,6 +13,7 @@
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wattributes"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#include "yaml-cpp/yaml.h"
#pragma GCC diagnostic pop
#endif