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
|
shift-amount
|
||||||
truncation
|
truncation
|
||||||
unmapped-char
|
unmapped-char
|
||||||
|
unmatched-directive
|
||||||
unterminated-load
|
unterminated-load
|
||||||
user
|
user
|
||||||
all
|
all
|
||||||
|
|||||||
@@ -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'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
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
|
.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
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
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