Disallow SECTION UNION for ROM sections

Fixes #1855
This commit is contained in:
Rangi
2025-11-07 11:30:38 -05:00
parent fb9fa6038c
commit 395b03e88e
16 changed files with 31 additions and 104 deletions

View File

@@ -120,9 +120,8 @@ Section *sect_FindSectionByName(std::string const &name) {
++nbSectErrors; \ ++nbSectErrors; \
} while (0) } while (0)
static unsigned int mergeSectUnion( static unsigned int
Section &sect, SectionType type, uint32_t org, uint8_t alignment, uint16_t alignOffset mergeSectUnion(Section &sect, uint32_t org, uint8_t alignment, uint16_t alignOffset) {
) {
unsigned int nbSectErrors = 0; unsigned int nbSectErrors = 0;
assume(alignment < 16); // Should be ensured by the caller assume(alignment < 16); // Should be ensured by the caller
@@ -133,12 +132,6 @@ static unsigned int mergeSectUnion(
uint32_t sectAlignSize = 1u << sect.align; uint32_t sectAlignSize = 1u << sect.align;
uint32_t sectAlignMask = sectAlignSize - 1; uint32_t sectAlignMask = sectAlignSize - 1;
// Unionized sections only need "compatible" constraints, and they end up with the strictest
// combination of both.
if (sectTypeHasData(type)) {
sectError("Cannot declare ROM sections as `UNION`");
}
if (org != UINT32_MAX) { if (org != UINT32_MAX) {
// If both are fixed, they must be the same // If both are fixed, they must be the same
if (sect.org != UINT32_MAX && sect.org != org) { if (sect.org != UINT32_MAX && sect.org != org) {
@@ -266,12 +259,10 @@ static void mergeSections(
} else { } else {
switch (mod) { switch (mod) {
case SECTION_UNION: case SECTION_UNION:
case SECTION_FRAGMENT: case SECTION_FRAGMENT: {
nbSectErrors += mod == SECTION_UNION unsigned int (*merge)(Section &, uint32_t, uint8_t, uint16_t) =
? mergeSectUnion(sect, type, org, alignment, alignOffset) mod == SECTION_UNION ? mergeSectUnion : mergeFragments;
: mergeFragments(sect, org, alignment, alignOffset); nbSectErrors += merge(sect, org, alignment, alignOffset);
// Common checks
// If the section's bank is unspecified, override it // If the section's bank is unspecified, override it
if (sect.bank == UINT32_MAX) { if (sect.bank == UINT32_MAX) {
@@ -282,6 +273,7 @@ static void mergeSections(
sectError("Section already declared with different bank %" PRIu32, sect.bank); sectError("Section already declared with different bank %" PRIu32, sect.bank);
} }
break; break;
}
case SECTION_NORMAL: case SECTION_NORMAL:
errorNoTrace([&]() { errorNoTrace([&]() {
@@ -513,6 +505,11 @@ void sect_NewSection(
} }
} }
if (mod == SECTION_UNION && sectTypeHasData(type)) {
error("Cannot declare ROM sections as `UNION`");
return;
}
if (currentLoadSection) { if (currentLoadSection) {
sect_EndLoadSection("SECTION"); sect_EndLoadSection("SECTION");
} }
@@ -1121,12 +1118,12 @@ std::string sect_PushSectionFragmentLiteral() {
); );
} }
// This section has data (ROM0 or ROMX), so it cannot be a UNION
assume(currentSection->modifier != SECTION_UNION);
if (currentLoadSection) { if (currentLoadSection) {
fatal("`LOAD` blocks cannot contain fragment literals"); fatal("`LOAD` blocks cannot contain fragment literals");
} }
if (currentSection->modifier == SECTION_UNION) {
fatal("`SECTION UNION` cannot contain fragment literals");
}
// A section containing a fragment literal has to become a fragment too // A section containing a fragment literal has to become a fragment too
currentSection->modifier = SECTION_FRAGMENT; currentSection->modifier = SECTION_FRAGMENT;

View File

@@ -1,2 +1,6 @@
FATAL: `SECTION UNION` cannot contain fragment literals error: Cannot declare ROM sections as `UNION`
at fragment-literal-in-union.asm(1)
error: Cannot output data outside of a `SECTION`
at fragment-literal-in-union.asm(2)
FATAL: Cannot output fragment literals outside of a `SECTION`
at fragment-literal-in-union.asm(3) at fragment-literal-in-union.asm(3)

View File

@@ -0,0 +1,2 @@
SECTION UNION "wat", ROM0
db 42

View File

@@ -0,0 +1,5 @@
error: Cannot declare ROM sections as `UNION`
at section-union-data.asm(1)
error: Cannot output data outside of a `SECTION`
at section-union-data.asm(2)
Assembly aborted with 2 errors!

View File

@@ -1,2 +1,2 @@
section fragment "test", rom0 section fragment "test", wram0
db 1 w1:: db

View File

@@ -1,2 +1,2 @@
section union "test", rom0 section union "test", wram0
db 2 w2:: db

View File

@@ -1,10 +0,0 @@
IF !DEF(SECOND)
def DATA equs "ds 4"
ELSE
def DATA equs "db $aa, $bb, $cc, $dd"
ENDC
SECTION UNION "overlaid data", ROM0
{DATA}
PURGE DATA

View File

@@ -1,7 +0,0 @@
FATAL: Section "overlaid data" is of type `ROM0`, which cannot be `UNION`ized
Linking aborted with 1 error
---
error: Cannot declare ROM sections as `UNION`
at <stdin>(18)
FATAL: Cannot create section "overlaid data" (1 error)
at <stdin>(18)

View File

@@ -1,8 +0,0 @@
IF !DEF(SECOND)
def DATA = 1
ELSE
def DATA = 2
ENDC
SECTION UNION "different data", ROM0
db DATA

View File

@@ -1,7 +0,0 @@
FATAL: Section "different data" is of type `ROM0`, which cannot be `UNION`ized
Linking aborted with 1 error
---
error: Cannot declare ROM sections as `UNION`
at <stdin>(16)
FATAL: Cannot create section "different data" (1 error)
at <stdin>(16)

View File

@@ -1,8 +0,0 @@
IF !DEF(SECOND)
def SIZE = 69
ELSE
def SIZE = 420
ENDC
SECTION UNION "different section sizes", ROM0
ds SIZE

View File

@@ -1,7 +0,0 @@
FATAL: Section "different section sizes" is of type `ROM0`, which cannot be `UNION`ized
Linking aborted with 1 error
---
error: Cannot declare ROM sections as `UNION`
at <stdin>(16)
FATAL: Cannot create section "different section sizes" (1 error)
at <stdin>(16)

View File

@@ -1,10 +0,0 @@
IF !DEF(SECOND)
def INSTR equs "sbc a"
ELSE
def INSTR equs "db $9f"
ENDC
SECTION UNION "different syntaxes", ROM0
{INSTR}
PURGE INSTR

View File

@@ -1,7 +0,0 @@
FATAL: Section "different syntaxes" is of type `ROM0`, which cannot be `UNION`ized
Linking aborted with 1 error
---
error: Cannot declare ROM sections as `UNION`
at <stdin>(18)
FATAL: Cannot create section "different syntaxes" (1 error)
at <stdin>(18)

View File

@@ -1,10 +0,0 @@
IF !DEF(SECOND)
def DATA equs "ds 1\ndb $aa"
ELSE
def DATA equs "db $bb\nds 1"
ENDC
SECTION UNION "mutually-overlaid data", ROM0
{DATA}
PURGE DATA

View File

@@ -1,7 +0,0 @@
FATAL: Section "mutually-overlaid data" is of type `ROM0`, which cannot be `UNION`ized
Linking aborted with 1 error
---
error: Cannot declare ROM sections as `UNION`
at <stdin>(18)
FATAL: Cannot create section "mutually-overlaid data" (1 error)
at <stdin>(18)