mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Implement -Wunmatched-directive
This commit is contained in:
@@ -192,6 +192,7 @@ _rgbasm_completions() {
|
||||
shift-amount
|
||||
truncation
|
||||
unmapped-char
|
||||
unmatched-directive
|
||||
unterminated-load
|
||||
user
|
||||
all
|
||||
|
||||
@@ -26,6 +26,7 @@ _rgbasm_warnings() {
|
||||
'shift-amount:Warn when a shift'\''s operand it negative or \> 32'
|
||||
'truncation:Warn when implicit truncation loses bits'
|
||||
'unmapped-char:Warn on unmapped character'
|
||||
'unmatched-directive:Warn on unmatched directive pair'
|
||||
'unterminated-load:Warn on LOAD without ENDL'
|
||||
'user:Warn when executing the WARN built-in'
|
||||
)
|
||||
|
||||
@@ -18,6 +18,7 @@ void charmap_New(std::string const &name, std::string const *baseName);
|
||||
void charmap_Set(std::string const &name);
|
||||
void charmap_Push();
|
||||
void charmap_Pop();
|
||||
void charmap_CheckStack();
|
||||
void charmap_Add(std::string const &mapping, std::vector<int32_t> &&value);
|
||||
bool charmap_HasChar(std::string const &input);
|
||||
std::vector<int32_t> charmap_Convert(std::string const &input);
|
||||
|
||||
@@ -14,5 +14,6 @@ void opt_Parse(char const *option);
|
||||
|
||||
void opt_Push();
|
||||
void opt_Pop();
|
||||
void opt_CheckStack();
|
||||
|
||||
#endif // RGBDS_ASM_OPT_HPP
|
||||
|
||||
@@ -102,5 +102,6 @@ void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t len
|
||||
void sect_EndSection();
|
||||
void sect_PushSection();
|
||||
void sect_PopSection();
|
||||
void sect_CheckStack();
|
||||
|
||||
#endif // RGBDS_ASM_SECTION_HPP
|
||||
|
||||
@@ -20,6 +20,7 @@ enum WarningID {
|
||||
WARNING_OBSOLETE, // Obsolete/deprecated things
|
||||
WARNING_SHIFT, // Undefined `SHIFT` behavior
|
||||
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_USER, // User-defined `WARN`ings
|
||||
|
||||
|
||||
11
man/rgbasm.1
11
man/rgbasm.1
@@ -370,6 +370,17 @@ only warns if the active charmap is not empty.
|
||||
.Fl Wunmapped-char=2
|
||||
warns if the active charmap is empty, and/or is not the default charmap
|
||||
.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
|
||||
Warn when a
|
||||
.Ic LOAD
|
||||
|
||||
@@ -113,6 +113,12 @@ void charmap_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) {
|
||||
if (mapping.empty()) {
|
||||
error("Cannot map an empty string\n");
|
||||
|
||||
@@ -384,6 +384,10 @@ int main(int argc, char *argv[]) {
|
||||
sect_CheckLoadClosed();
|
||||
sect_CheckSizes();
|
||||
|
||||
charmap_CheckStack();
|
||||
opt_CheckStack();
|
||||
sect_CheckStack();
|
||||
|
||||
if (nbErrors != 0)
|
||||
errx("Assembly aborted (%u error%s)!", nbErrors, nbErrors == 1 ? "" : "s");
|
||||
|
||||
|
||||
@@ -184,3 +184,9 @@ void opt_Pop() {
|
||||
warningsAreErrors = entry.warningsAreErrors;
|
||||
warningStates = entry.warningStates;
|
||||
}
|
||||
|
||||
void opt_CheckStack() {
|
||||
if (!stack.empty()) {
|
||||
warning(WARNING_UNMATCHED_DIRECTIVE, "`PUSHO` without corresponding `POPO`\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -973,6 +973,12 @@ void sect_PopSection() {
|
||||
std::swap(currentUnionStack, entry.unionStack);
|
||||
}
|
||||
|
||||
void sect_CheckStack() {
|
||||
if (!sectionStack.empty()) {
|
||||
warning(WARNING_UNMATCHED_DIRECTIVE, "`PUSHS` without corresponding `POPS`\n");
|
||||
}
|
||||
}
|
||||
|
||||
void sect_EndSection() {
|
||||
if (!currentSection)
|
||||
fatalerror("Cannot end the section outside of a SECTION\n");
|
||||
|
||||
@@ -56,6 +56,7 @@ static const WarningFlag warningFlags[NB_WARNINGS] = {
|
||||
{"obsolete", LEVEL_DEFAULT },
|
||||
{"shift", LEVEL_EVERYTHING},
|
||||
{"shift-amount", LEVEL_EVERYTHING},
|
||||
{"unmatched-directive", LEVEL_EXTRA },
|
||||
{"unterminated-load", LEVEL_EXTRA },
|
||||
{"user", LEVEL_DEFAULT },
|
||||
// Parametric warnings
|
||||
|
||||
@@ -3,3 +3,4 @@ SECTION "This is invalid", ROM0
|
||||
PUSHS
|
||||
; We should be outside of section scope now
|
||||
db 69
|
||||
POPS
|
||||
|
||||
4
test/asm/unmatched-directive.asm
Normal file
4
test/asm/unmatched-directive.asm
Normal file
@@ -0,0 +1,4 @@
|
||||
SECTION "test", ROM0
|
||||
PUSHC
|
||||
PUSHO
|
||||
PUSHS
|
||||
6
test/asm/unmatched-directive.err
Normal file
6
test/asm/unmatched-directive.err
Normal 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`
|
||||
Reference in New Issue
Block a user