Implement -Wunmatched-directive

This commit is contained in:
Rangi42
2024-11-28 14:06:52 -05:00
committed by Eldred Habert
parent 9216485bca
commit a27f704c25
15 changed files with 51 additions and 0 deletions

View File

@@ -192,6 +192,7 @@ _rgbasm_completions() {
shift-amount shift-amount
truncation truncation
unmapped-char unmapped-char
unmatched-directive
unterminated-load unterminated-load
user user
all all

View File

@@ -26,6 +26,7 @@ _rgbasm_warnings() {
'shift-amount:Warn when a shift'\''s operand it negative or \> 32' 'shift-amount:Warn when a shift'\''s operand it negative or \> 32'
'truncation:Warn when implicit truncation loses bits' 'truncation:Warn when implicit truncation loses bits'
'unmapped-char:Warn on unmapped character' 'unmapped-char:Warn on unmapped character'
'unmatched-directive:Warn on unmatched directive pair'
'unterminated-load:Warn on LOAD without ENDL' 'unterminated-load:Warn on LOAD without ENDL'
'user:Warn when executing the WARN built-in' 'user:Warn when executing the WARN built-in'
) )

View File

@@ -18,6 +18,7 @@ void charmap_New(std::string const &name, std::string const *baseName);
void charmap_Set(std::string const &name); void charmap_Set(std::string const &name);
void charmap_Push(); void charmap_Push();
void charmap_Pop(); void charmap_Pop();
void charmap_CheckStack();
void charmap_Add(std::string const &mapping, std::vector<int32_t> &&value); void charmap_Add(std::string const &mapping, std::vector<int32_t> &&value);
bool charmap_HasChar(std::string const &input); bool charmap_HasChar(std::string const &input);
std::vector<int32_t> charmap_Convert(std::string const &input); std::vector<int32_t> charmap_Convert(std::string const &input);

View File

@@ -14,5 +14,6 @@ void opt_Parse(char const *option);
void opt_Push(); void opt_Push();
void opt_Pop(); void opt_Pop();
void opt_CheckStack();
#endif // RGBDS_ASM_OPT_HPP #endif // RGBDS_ASM_OPT_HPP

View File

@@ -102,5 +102,6 @@ void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t len
void sect_EndSection(); void sect_EndSection();
void sect_PushSection(); void sect_PushSection();
void sect_PopSection(); void sect_PopSection();
void sect_CheckStack();
#endif // RGBDS_ASM_SECTION_HPP #endif // RGBDS_ASM_SECTION_HPP

View File

@@ -20,6 +20,7 @@ enum WarningID {
WARNING_OBSOLETE, // Obsolete/deprecated things WARNING_OBSOLETE, // Obsolete/deprecated things
WARNING_SHIFT, // Undefined `SHIFT` behavior WARNING_SHIFT, // Undefined `SHIFT` behavior
WARNING_SHIFT_AMOUNT, // Strange `SHIFT` amount WARNING_SHIFT_AMOUNT, // Strange `SHIFT` amount
WARNING_UNMATCHED_DIRECTIVE, // `PUSH[C|O|S]` without `POP[C|O|S]`
WARNING_UNTERMINATED_LOAD, // `LOAD` without `ENDL` WARNING_UNTERMINATED_LOAD, // `LOAD` without `ENDL`
WARNING_USER, // User-defined `WARN`ings WARNING_USER, // User-defined `WARN`ings

View File

@@ -370,6 +370,17 @@ only warns if the active charmap is not empty.
.Fl Wunmapped-char=2 .Fl Wunmapped-char=2
warns if the active charmap is empty, and/or is not the default charmap warns if the active charmap is empty, and/or is not the default charmap
.Sq main . .Sq main .
.It Fl Wunmatched-directive
Warn when a
.Ic PUSHC , PUSHO ,
or
.Ic PUSHS
directive does not have a corresponding
.Ic POPC , POPO ,
or
.Ic POPS .
This warning is enabled by
.Fl Wextra .
.It Fl Wunterminated-load .It Fl Wunterminated-load
Warn when a Warn when a
.Ic LOAD .Ic LOAD

View File

@@ -113,6 +113,12 @@ void charmap_Pop() {
charmapStack.pop(); charmapStack.pop();
} }
void charmap_CheckStack() {
if (!charmapStack.empty()) {
warning(WARNING_UNMATCHED_DIRECTIVE, "`PUSHC` without corresponding `POPC`\n");
}
}
void charmap_Add(std::string const &mapping, std::vector<int32_t> &&value) { void charmap_Add(std::string const &mapping, std::vector<int32_t> &&value) {
if (mapping.empty()) { if (mapping.empty()) {
error("Cannot map an empty string\n"); error("Cannot map an empty string\n");

View File

@@ -384,6 +384,10 @@ int main(int argc, char *argv[]) {
sect_CheckLoadClosed(); sect_CheckLoadClosed();
sect_CheckSizes(); sect_CheckSizes();
charmap_CheckStack();
opt_CheckStack();
sect_CheckStack();
if (nbErrors != 0) if (nbErrors != 0)
errx("Assembly aborted (%u error%s)!", nbErrors, nbErrors == 1 ? "" : "s"); errx("Assembly aborted (%u error%s)!", nbErrors, nbErrors == 1 ? "" : "s");

View File

@@ -184,3 +184,9 @@ void opt_Pop() {
warningsAreErrors = entry.warningsAreErrors; warningsAreErrors = entry.warningsAreErrors;
warningStates = entry.warningStates; warningStates = entry.warningStates;
} }
void opt_CheckStack() {
if (!stack.empty()) {
warning(WARNING_UNMATCHED_DIRECTIVE, "`PUSHO` without corresponding `POPO`\n");
}
}

View File

@@ -973,6 +973,12 @@ void sect_PopSection() {
std::swap(currentUnionStack, entry.unionStack); std::swap(currentUnionStack, entry.unionStack);
} }
void sect_CheckStack() {
if (!sectionStack.empty()) {
warning(WARNING_UNMATCHED_DIRECTIVE, "`PUSHS` without corresponding `POPS`\n");
}
}
void sect_EndSection() { void sect_EndSection() {
if (!currentSection) if (!currentSection)
fatalerror("Cannot end the section outside of a SECTION\n"); fatalerror("Cannot end the section outside of a SECTION\n");

View File

@@ -56,6 +56,7 @@ static const WarningFlag warningFlags[NB_WARNINGS] = {
{"obsolete", LEVEL_DEFAULT }, {"obsolete", LEVEL_DEFAULT },
{"shift", LEVEL_EVERYTHING}, {"shift", LEVEL_EVERYTHING},
{"shift-amount", LEVEL_EVERYTHING}, {"shift-amount", LEVEL_EVERYTHING},
{"unmatched-directive", LEVEL_EXTRA },
{"unterminated-load", LEVEL_EXTRA }, {"unterminated-load", LEVEL_EXTRA },
{"user", LEVEL_DEFAULT }, {"user", LEVEL_DEFAULT },
// Parametric warnings // Parametric warnings

View File

@@ -3,3 +3,4 @@ SECTION "This is invalid", ROM0
PUSHS PUSHS
; We should be outside of section scope now ; We should be outside of section scope now
db 69 db 69
POPS

View File

@@ -0,0 +1,4 @@
SECTION "test", ROM0
PUSHC
PUSHO
PUSHS

View File

@@ -0,0 +1,6 @@
warning: unmatched-directive.asm(5): [-Wunmatched-directive]
`PUSHC` without corresponding `POPC`
warning: unmatched-directive.asm(5): [-Wunmatched-directive]
`PUSHO` without corresponding `POPO`
warning: unmatched-directive.asm(5): [-Wunmatched-directive]
`PUSHS` without corresponding `POPS`