diff --git a/src/asm/section.cpp b/src/asm/section.cpp index 733ca3db..8dfce013 100644 --- a/src/asm/section.cpp +++ b/src/asm/section.cpp @@ -274,14 +274,6 @@ static void mergeSections( ) { sectErrors.clear(); - if (type != sect.type) { - sectError( - "Section \"%s\" already exists but with type `%s`", - sect.name.c_str(), - sectionTypeInfo[sect.type].name.c_str() - ); - } - if (sect.modifier != mod) { sectError( "Section \"%s\" already declared as `SECTION %s`", @@ -290,8 +282,29 @@ static void mergeSections( ); } else { switch (mod) { + case SECTION_NORMAL: + // Only union/fragment sections can end up with multiple errors queued in `sectErrors`, + // and they cannot encounter this error, so it's okay for this one to skip the queue. + // Queueing it in `sectErrors` would require a sentinel value anyway (e.g. an empty + // string) to handle the "no trace" callback. + assume(sectErrors.empty()); + fatalNoTrace([§]() { + fprintf(stderr, "Section \"%s\" already defined\n", sect.name.c_str()); + fstk_TraceCurrent(); + fputs(" and also:\n", stderr); + sect.src->printBacktrace(sect.fileLine); + }); + case SECTION_UNION: case SECTION_FRAGMENT: { + if (type != sect.type) { + sectError( + "Section \"%s\" already exists but with type `%s`", + sect.name.c_str(), + sectionTypeInfo[sect.type].name.c_str() + ); + } + void (*merge)(Section &, uint32_t, uint8_t, uint16_t) = mod == SECTION_UNION ? mergeSectUnion : mergeFragments; merge(sect, org, alignment, alignOffset); @@ -310,20 +323,6 @@ static void mergeSections( } break; } - - case SECTION_NORMAL: - // Only union/fragment sections can end up with multiple errors queued in `sectErrors`, - // and they cannot encounter this error, so it's okay for this one to skip the queue. - // Queueing it in `sectErrors` would require a sentinel value anyway (e.g. an empty - // string) to handle the "no trace" callback. - assume(sectErrors.empty()); - fatalNoTrace([§]() { - fprintf(stderr, "Section \"%s\" already defined\n", sect.name.c_str()); - fstk_TraceCurrent(); - fputs(" and also:\n", stderr); - sect.src->printBacktrace(sect.fileLine); - }); - break; } } diff --git a/test/asm/load-already-defined.asm b/test/asm/load-already-defined.asm new file mode 100644 index 00000000..c718df68 --- /dev/null +++ b/test/asm/load-already-defined.asm @@ -0,0 +1,3 @@ +SECTION "test", ROM0 +LOAD "test", WRAM0 +ENDL diff --git a/test/asm/load-already-defined.err b/test/asm/load-already-defined.err new file mode 100644 index 00000000..e37f92ce --- /dev/null +++ b/test/asm/load-already-defined.err @@ -0,0 +1,4 @@ +FATAL: Section "test" already defined + at load-already-defined.asm(2) + and also: + at load-already-defined.asm(1) diff --git a/test/asm/section-already-defined.asm b/test/asm/section-already-defined.asm new file mode 100755 index 00000000..eadfbc92 --- /dev/null +++ b/test/asm/section-already-defined.asm @@ -0,0 +1,2 @@ +SECTION "test", ROM0 +SECTION "test", WRAM0 diff --git a/test/asm/section-already-defined.err b/test/asm/section-already-defined.err new file mode 100644 index 00000000..a95efd47 --- /dev/null +++ b/test/asm/section-already-defined.err @@ -0,0 +1,4 @@ +FATAL: Section "test" already defined + at section-already-defined.asm(2) + and also: + at section-already-defined.asm(1)