Do not implicitly convert enums to ordinal in formatting functions.

This commit is contained in:
Christoffer Lerno
2025-03-25 12:27:51 +01:00
parent 439349ceb8
commit fa707db078
7 changed files with 17 additions and 13 deletions

View File

@@ -46,7 +46,7 @@ macro Char16[] @char16(String $string) @builtin
@param [in] fmt : `The formatting string` @param [in] fmt : `The formatting string`
*> *>
fn ZString tformat_zstr(String fmt, args...) fn ZString tformat_zstr(String fmt, args...) @format(0)
{ {
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8); DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
str.appendf(fmt, ...args); str.appendf(fmt, ...args);
@@ -59,7 +59,7 @@ fn ZString tformat_zstr(String fmt, args...)
@param [inout] allocator : `The allocator to use` @param [inout] allocator : `The allocator to use`
@param [in] fmt : `The formatting string` @param [in] fmt : `The formatting string`
*> *>
fn String format(Allocator allocator, String fmt, args...) => @pool() fn String format(Allocator allocator, String fmt, args...) @format(1) => @pool()
{ {
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8); DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
str.appendf(fmt, ...args); str.appendf(fmt, ...args);
@@ -71,7 +71,7 @@ fn String format(Allocator allocator, String fmt, args...) => @pool()
@param [in] fmt : `The formatting string` @param [in] fmt : `The formatting string`
*> *>
fn String tformat(String fmt, args...) fn String tformat(String fmt, args...) @format(0)
{ {
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8); DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
str.appendf(fmt, ...args); str.appendf(fmt, ...args);

View File

@@ -339,7 +339,7 @@ macro usz? @wrap_bad(Formatter* f, #action)
case INTERNAL_BUFFER_EXCEEDED: case INTERNAL_BUFFER_EXCEEDED:
return f.first_err(err)?; return f.first_err(err)?;
default: default:
err = f.first_err(INVALID_ARGUMENT); err = f.first_err(INVALID_ARGUMENT);
f.out_substr("<INVALID>")!; f.out_substr("<INVALID>")!;
return err?; return err?;
} }

View File

@@ -43,7 +43,6 @@ fn uint128? int_from_any(any arg, bool *is_neg) @private
*is_neg = false; *is_neg = false;
return (uint128)(uptr)*(void**)arg.ptr; return (uint128)(uptr)*(void**)arg.ptr;
case TypeKind.DISTINCT: case TypeKind.DISTINCT:
case TypeKind.ENUM:
return int_from_any(arg.as_inner(), is_neg); return int_from_any(arg.as_inner(), is_neg);
default: default:
break; break;

View File

@@ -45,18 +45,18 @@ fn String format(Allocator allocator, DateTimeFormat type, TzDateTime dt)
return string::format(allocator, "%s, %02d %s %d %02d:%02d:%02d %s", dt.weekday.abbrev, dt.day, dt.month.abbrev, dt.year, dt.hour, dt.min, dt.sec, temp_numeric_tzsuffix(dt.gmt_offset)); return string::format(allocator, "%s, %02d %s %d %02d:%02d:%02d %s", dt.weekday.abbrev, dt.day, dt.month.abbrev, dt.year, dt.hour, dt.min, dt.sec, temp_numeric_tzsuffix(dt.gmt_offset));
case RFC3339: case RFC3339:
dt = dt.to_gmt_offset(0); dt = dt.to_gmt_offset(0);
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02dZ", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec); return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02dZ", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec);
case RFC3339Z: case RFC3339Z:
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d%s", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec, temp_numeric_tzsuffix_colon(dt.gmt_offset)); return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d%s", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec, temp_numeric_tzsuffix_colon(dt.gmt_offset));
case RFC3339MS: case RFC3339MS:
dt = dt.to_gmt_offset(0); dt = dt.to_gmt_offset(0);
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d.%dZ", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec, dt.usec); return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d.%dZ", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec, dt.usec);
case RFC3339ZMS: case RFC3339ZMS:
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d.%d%s", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec, dt.usec, temp_numeric_tzsuffix_colon(dt.gmt_offset)); return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d.%d%s", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec, dt.usec, temp_numeric_tzsuffix_colon(dt.gmt_offset));
case DATETIME: case DATETIME:
return string::format(allocator, "%04d-%02d-%02d %02d:%02d:%02d", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec); return string::format(allocator, "%04d-%02d-%02d %02d:%02d:%02d", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec);
case DATEONLY: case DATEONLY:
return string::format(allocator, "%04d-%02d-%02d", dt.year, dt.month + 1, dt.day); return string::format(allocator, "%04d-%02d-%02d", dt.year, dt.month.ordinal + 1, dt.day);
case TIMEONLY: case TIMEONLY:
return string::format(allocator, "%02d:%02d:%02d", dt.hour, dt.min, dt.sec); return string::format(allocator, "%02d:%02d:%02d", dt.hour, dt.min, dt.sec);
} }

View File

@@ -44,6 +44,7 @@
- `tmem` is now a variable. - `tmem` is now a variable.
- Compile test and benchmark functions when invoking `--lsp` #2058. - Compile test and benchmark functions when invoking `--lsp` #2058.
- Added `@format` attribute for compile time printf validation #2057. - Added `@format` attribute for compile time printf validation #2057.
- Formatter no longer implicitly converts enums to ordinals.
### Fixes ### Fixes
- Fix address sanitizer to work on MachO targets (e.g. MacOS). - Fix address sanitizer to work on MachO targets (e.g. MacOS).

View File

@@ -1869,6 +1869,10 @@ CHECK_FORMAT:;
case 'G': case 'G':
if (!type_is_number_or_bool(type)) if (!type_is_number_or_bool(type))
{ {
if (type->type_kind == TYPE_ENUM)
{
RETURN_SEMA_ERROR(vaargs[idx], "An enum cannot directly be turned into a number. Use '.ordinal' to convert it to its value.", type_quoted_error_string(type));
}
RETURN_SEMA_ERROR(vaargs[idx], "Expected a number here, but was %s", type_quoted_error_string(type)); RETURN_SEMA_ERROR(vaargs[idx], "Expected a number here, but was %s", type_quoted_error_string(type));
} }
goto NEXT; goto NEXT;

View File

@@ -107,10 +107,10 @@ fn void printf_enum()
assert(s == "ENUMB", "got '%s'; want 'ENUMB'", s); assert(s == "ENUMB", "got '%s'; want 'ENUMB'", s);
free(s); free(s);
s = string::format(mem, "%d", PrintfTest.ENUMA); s = string::format(mem, "%d", PrintfTest.ENUMA.ordinal);
assert(s == "0", "got '%s'; want '0'", s); assert(s == "0", "got '%s'; want '0'", s);
free(s); free(s);
s = string::format(mem, "%d", PrintfTest.ENUMB); s = string::format(mem, "%d", PrintfTest.ENUMB.ordinal);
assert(s == "1", "got '%s'; want '1'", s); assert(s == "1", "got '%s'; want '1'", s);
free(s); free(s);
} }