From 4e65c8f69fd808f252e5a25b5df5e3ad643ebd34 Mon Sep 17 00:00:00 2001 From: Patryk Obara Date: Tue, 12 Nov 2019 10:45:46 +0100 Subject: [PATCH] Add asserts to prevent a potential bug Use C++11 static_assert to assure, that code behaves correctly; if Chip or Channel structs will be changed to non-std layout or a different first fields will be introduced, that will invalidate the offset calculation. Additionally, add asserts to prevent possibility of introducing a bug when offset stored in one the tables is 0. --- src/hardware/adlib.h | 1 + src/hardware/dbopl.cpp | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/hardware/adlib.h b/src/hardware/adlib.h index e22d49ea..7fbc7820 100644 --- a/src/hardware/adlib.h +++ b/src/hardware/adlib.h @@ -27,6 +27,7 @@ #include "pic.h" #include "hardware.h" +#include namespace Adlib { diff --git a/src/hardware/dbopl.cpp b/src/hardware/dbopl.cpp index b4cd183c..c61351ce 100644 --- a/src/hardware/dbopl.cpp +++ b/src/hardware/dbopl.cpp @@ -32,15 +32,14 @@ //DUNNO Keyon in 4op, switch to 2op without keyoff. */ +#include "dbopl.h" - +#include +#include #include #include #include -#include -#include "dosbox.h" -#include "dbopl.h" - +#include #ifndef PI #define PI 3.14159265358979323846 @@ -1450,6 +1449,13 @@ void InitTables( void ) { //Add back the bits for highest ones if ( i >= 16 ) index += 9; + + static_assert(std::is_standard_layout::value, + "struct Chip is not a standard layout type"); + static_assert(offsetof(Chip, chan) == 0, + "offset table stores values relative to the start of struct"); + // values stored in offset tables are artificially increased by 1 + // to keep macros REGCHAN and REGOP working correctly ChanOffsetTable[i] = 1+(Bit16u)(index*sizeof(DBOPL::Channel)); } //Same for operators @@ -1463,7 +1469,13 @@ void InitTables( void ) { if ( chNum >= 12 ) chNum += 16 - 12; Bitu opNum = ( i % 8 ) / 3; + + static_assert(std::is_standard_layout::value, + "struct Channel is not a standard layout type"); + static_assert(offsetof(Channel, op) == 0, + "offset table stores values relative to the start of struct"); OpOffsetTable[i] = ChanOffsetTable[chNum]+(Bit16u)(opNum*sizeof(DBOPL::Operator)); + assert(OpOffsetTable[i] > 0); // needs to be non-zero; see REGOP macro } #if 0 DBOPL::Chip* chip = 0;