mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Fix -W parameter parsing
This commit is contained in:
@@ -28,7 +28,7 @@ struct WarningState {
|
||||
void update(WarningState other);
|
||||
};
|
||||
|
||||
std::pair<WarningState, std::optional<uint8_t>> getInitialWarningState(std::string &flag);
|
||||
std::pair<WarningState, std::optional<uint32_t>> getInitialWarningState(std::string &flag);
|
||||
|
||||
template<typename L>
|
||||
struct WarningFlag {
|
||||
@@ -150,20 +150,17 @@ std::string Diagnostics<L, W>::processWarningFlag(char const *flag) {
|
||||
if (!param.has_value() || *param == 0) {
|
||||
param = paramWarning.defaultLevel;
|
||||
} else if (*param > maxParam) {
|
||||
if (*param != 255) { // Don't warn if already capped
|
||||
warnx(
|
||||
"Invalid parameter %" PRIu8
|
||||
" for warning flag \"%s\"; capping at maximum %" PRIu8,
|
||||
*param,
|
||||
"Invalid warning flag parameter \"%s=%" PRIu32 "\"; capping at maximum %" PRIu8,
|
||||
rootFlag.c_str(),
|
||||
*param,
|
||||
maxParam
|
||||
);
|
||||
}
|
||||
*param = maxParam;
|
||||
}
|
||||
|
||||
// Set the first <param> to enabled/error, and disable the rest
|
||||
for (uint8_t ofs = 0; ofs < maxParam; ofs++) {
|
||||
for (uint32_t ofs = 0; ofs < maxParam; ofs++) {
|
||||
if (WarningState &warning = state.flagStates[baseID + ofs]; ofs < *param) {
|
||||
warning.update(flagState);
|
||||
} else {
|
||||
@@ -174,7 +171,7 @@ std::string Diagnostics<L, W>::processWarningFlag(char const *flag) {
|
||||
}
|
||||
|
||||
if (param.has_value()) {
|
||||
warnx("Unknown warning flag parameter \"%s\"", rootFlag.c_str());
|
||||
warnx("Unknown warning flag parameter \"%s=%" PRIu32 "\"", rootFlag.c_str(), *param);
|
||||
return rootFlag;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ void WarningState::update(WarningState other) {
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<WarningState, std::optional<uint8_t>> getInitialWarningState(std::string &flag) {
|
||||
std::pair<WarningState, std::optional<uint32_t>> getInitialWarningState(std::string &flag) {
|
||||
// Check for prefixes that affect what the flag does
|
||||
WarningState state;
|
||||
if (flag.starts_with("error=")) {
|
||||
@@ -51,28 +51,22 @@ std::pair<WarningState, std::optional<uint8_t>> getInitialWarningState(std::stri
|
||||
// Is the rest of the string a decimal number?
|
||||
// We want to avoid `strtoul`'s whitespace and sign, so we parse manually
|
||||
char const *ptr = flag.c_str() + equals + 1;
|
||||
uint8_t param = 0;
|
||||
bool warned = false;
|
||||
uint32_t param = 0;
|
||||
bool overflowed = false;
|
||||
|
||||
// The `if`'s condition above ensures that this will run at least once
|
||||
do {
|
||||
// If we don't have a digit, bail
|
||||
if (*ptr < '0' || *ptr > '9') {
|
||||
break;
|
||||
}
|
||||
// Avoid overflowing!
|
||||
if (param > UINT8_MAX - (*ptr - '0')) {
|
||||
if (!warned) {
|
||||
warnx("Invalid warning flag \"%s\": capping parameter at 255", flag.c_str());
|
||||
}
|
||||
warned = true; // Only warn once, cap always
|
||||
param = 255;
|
||||
for (; *ptr >= '0' && *ptr <= '9'; ++ptr) {
|
||||
if (overflowed) {
|
||||
continue;
|
||||
}
|
||||
param = param * 10 + (*ptr - '0');
|
||||
|
||||
++ptr;
|
||||
} while (*ptr);
|
||||
uint32_t c = *ptr - '0';
|
||||
if (param > (UINT32_MAX - c) / 10) {
|
||||
overflowed = true;
|
||||
param = UINT32_MAX;
|
||||
continue;
|
||||
}
|
||||
param = param * 10 + c;
|
||||
}
|
||||
|
||||
// If we reached the end of the string, truncate it at the '='
|
||||
if (*ptr == '\0') {
|
||||
|
||||
4
test/asm/diagnostic-parameter-cap.asm
Normal file
4
test/asm/diagnostic-parameter-cap.asm
Normal file
@@ -0,0 +1,4 @@
|
||||
opt Wtruncation=256
|
||||
section "test", rom0
|
||||
db 999
|
||||
db -254
|
||||
5
test/asm/diagnostic-parameter-cap.err
Normal file
5
test/asm/diagnostic-parameter-cap.err
Normal file
@@ -0,0 +1,5 @@
|
||||
warning: Invalid warning flag parameter "truncation=256"; capping at maximum 2
|
||||
warning: diagnostic-parameter-cap.asm(3): [-Wtruncation]
|
||||
Expression must be 8-bit; use LOW() to force 8-bit
|
||||
warning: diagnostic-parameter-cap.asm(4): [-Wtruncation]
|
||||
Expression must be 8-bit; use LOW() to force 8-bit
|
||||
@@ -1,4 +1,4 @@
|
||||
warning: Invalid parameter 99 for warning flag "truncation"; capping at maximum 2
|
||||
warning: Invalid warning flag parameter "truncation=99"; capping at maximum 2
|
||||
warning: invalid-param.asm(2): [-Wtruncation]
|
||||
Expression must be 8-bit; use LOW() to force 8-bit
|
||||
warning: invalid-param.asm(3): [-Wtruncation]
|
||||
|
||||
Reference in New Issue
Block a user