diff --git a/src/asm/section.cpp b/src/asm/section.cpp index 8dfce013..4acf8b52 100644 --- a/src/asm/section.cpp +++ b/src/asm/section.cpp @@ -214,10 +214,8 @@ static void mergeFragments(Section §, uint32_t org, uint8_t alignment, uint1 // combination of both. // The merging is however performed at the *end* of the original section! if (org != UINT32_MAX) { - uint16_t curOrg = org - sect.size; - - // If both are fixed, they must be the same - if (sect.org != UINT32_MAX && sect.org != curOrg) { + // If both are fixed, they must be compatible + if (uint16_t curOrg = org - sect.size; sect.org != UINT32_MAX && sect.org != curOrg) { sectError( "Section \"%s\" already declared as fixed at incompatible address $%04" PRIx32, sect.name.c_str(), @@ -231,6 +229,16 @@ static void mergeFragments(Section §, uint32_t org, uint8_t alignment, uint1 sectAlignSize, sect.alignOfs ); + } else if (org < sect.size) { + // Check that `curOrg` did not underflow. Note that it's safe for the above checks to + // use an underflowed value, since their reported errors will still be accurate. + sectError( + "Section \"%s\" already contains %" PRIu32 + " bytes, higher than this fragment's fixed address $%04" PRIx32, + sect.name.c_str(), + sect.size, + org + ); } else { // Otherwise, just override sect.org = curOrg; diff --git a/test/asm/fragment-org-beyond-size.asm b/test/asm/fragment-org-beyond-size.asm new file mode 100644 index 00000000..dfab377c --- /dev/null +++ b/test/asm/fragment-org-beyond-size.asm @@ -0,0 +1,4 @@ +SECTION FRAGMENT "test", ROM0 +ds $11, 42 + +SECTION FRAGMENT "test", ROM0[$10] diff --git a/test/asm/fragment-org-beyond-size.err b/test/asm/fragment-org-beyond-size.err new file mode 100644 index 00000000..bce7ffa6 --- /dev/null +++ b/test/asm/fragment-org-beyond-size.err @@ -0,0 +1,2 @@ +FATAL: Section "test" already contains 17 bytes, higher than this fragment's fixed address $0010 + at fragment-org-beyond-size.asm(4)