checker: do not allow &u8(0), force nil like we do with &Type(0)

This commit is contained in:
Alexander Medvednikov 2025-05-03 22:37:51 +03:00
parent 3ab660b4c6
commit 7d57a19d7e
52 changed files with 184 additions and 118 deletions

View File

@ -7710,7 +7710,7 @@ fn main() {
C.sqlite3_finalize(stmt)
println('There are ${nr_users} users in the database.')
error_msg := &char(0)
error_msg := &char(unsafe { nil })
query_all_users := 'select * from users'
rc := C.sqlite3_exec(db, &char(query_all_users.str), my_callback, voidptr(7), &error_msg)
if rc != C.SQLITE_OK {

View File

@ -72,7 +72,7 @@ fn main() {
error_code := C.wkhtmltopdf_http_error_code(converter)
println('wkhtmltopdf_http_error_code: ${error_code}')
if result {
pdata := &char(0)
pdata := &char(unsafe { nil })
ppdata := &pdata
size := C.wkhtmltopdf_get_output(converter, voidptr(ppdata))
println('wkhtmltopdf_get_output: ${size} bytes')

View File

@ -37,7 +37,7 @@ fn create_texture(w int, h int, buf &u8) (gfx.Image, gfx.Sampler) {
height: h
num_mipmaps: 0
// usage: .dynamic
label: &char(0)
label: &char(unsafe { nil })
d3d11_texture: 0
}
// comment, if .dynamic is enabled

View File

@ -61,7 +61,7 @@ fn create_texture(w int, h int, buf &u8) (gfx.Image, gfx.Sampler) {
height: h
num_mipmaps: 0
// usage: .dynamic
label: &char(0)
label: &char(unsafe { nil })
d3d11_texture: 0
}
// comment if .dynamic is enabled

View File

@ -64,7 +64,7 @@ fn create_texture(w int, h int, buf &u8) (gfx.Image, gfx.Sampler) {
// usage: .dynamic
// wrap_u: .clamp_to_edge
// wrap_v: .clamp_to_edge
label: &char(0)
label: &char(unsafe { nil })
d3d11_texture: 0
}
// comment if .dynamic is enabled

View File

@ -75,7 +75,7 @@ fn create_texture(w int, h int, buf byteptr) (gfx.Image, gfx.Sampler) {
//usage: .dynamic
// wrap_u: .clamp_to_edge
// wrap_v: .clamp_to_edge
label: &char(0)
label: &char(unsafe { nil })
d3d11_texture: 0
}
// vfmt on

View File

@ -29,7 +29,7 @@ pub fn create_texture(w int, h int, buf &u8) (gfx.Image, gfx.Sampler) {
// usage: .dynamic
// wrap_u: .clamp_to_edge
// wrap_v: .clamp_to_edge
label: &char(0)
label: &char(unsafe { nil })
d3d11_texture: 0
}
// comment if .dynamic is enabled

View File

@ -119,7 +119,7 @@ fn create_texture(w int, h int, buf &u8) (gfx.Image, gfx.Sampler) {
height: h
num_mipmaps: 0
// usage: .dynamic
label: &u8(0)
label: &u8(unsafe { nil })
d3d11_texture: 0
}
// comment if .dynamic is enabled

View File

@ -87,7 +87,7 @@ fn print_backtrace_skipping_top_frames_msvc(skipframes int) bool {
si.f_max_name_len = sizeof(SymbolInfoContainer) - sizeof(SymbolInfo) - 1
fname := &char(&si.f_name)
mut sline64 := Line64{
f_file_name: &u8(0)
f_file_name: &u8(unsafe { nil })
}
sline64.f_size_of_struct = sizeof(Line64)

View File

@ -438,9 +438,9 @@ pub fn malloc(n isize) &u8 {
if n < 0 {
_memory_panic(@FN, n)
} else if n == 0 {
return &u8(0)
return &u8(unsafe { nil })
}
mut res := &u8(0)
mut res := &u8(unsafe { nil })
$if prealloc {
return unsafe { prealloc_malloc(n) }
} $else $if gcboehm ? {
@ -476,7 +476,7 @@ pub fn malloc_noscan(n isize) &u8 {
if n < 0 {
_memory_panic(@FN, n)
}
mut res := &u8(0)
mut res := &u8(unsafe { nil })
$if prealloc {
return unsafe { prealloc_malloc(n) }
} $else $if gcboehm ? {
@ -529,7 +529,7 @@ pub fn malloc_uncollectable(n isize) &u8 {
_memory_panic(@FN, n)
}
mut res := &u8(0)
mut res := &u8(unsafe { nil })
$if prealloc {
return unsafe { prealloc_malloc(n) }
} $else $if gcboehm ? {
@ -561,7 +561,7 @@ pub fn v_realloc(b &u8, n isize) &u8 {
$if trace_realloc ? {
C.fprintf(C.stderr, c'v_realloc %6d\n', n)
}
mut new_ptr := &u8(0)
mut new_ptr := &u8(unsafe { nil })
$if prealloc {
unsafe {
new_ptr = malloc(n)
@ -613,7 +613,7 @@ pub fn realloc_data(old_data &u8, old_size int, new_size int) &u8 {
return new_ptr
}
}
mut nptr := &u8(0)
mut nptr := &u8(unsafe { nil })
$if gcboehm ? {
nptr = unsafe { C.GC_REALLOC(old_data, new_size) }
} $else {
@ -636,7 +636,7 @@ pub fn vcalloc(n isize) &u8 {
if n < 0 {
_memory_panic(@FN, n)
} else if n == 0 {
return &u8(0)
return &u8(unsafe { nil })
}
$if prealloc {
return unsafe { prealloc_calloc(n) }
@ -645,7 +645,7 @@ pub fn vcalloc(n isize) &u8 {
} $else {
return unsafe { C.calloc(1, n) }
}
return &u8(0) // not reached, TODO: remove when V's checker is improved
return &u8(unsafe { nil }) // not reached, TODO: remove when V's checker is improved
}
// special versions of the above that allocate memory which is not scanned
@ -673,7 +673,7 @@ pub fn vcalloc_noscan(n isize) &u8 {
} $else {
return unsafe { vcalloc(n) }
}
return &u8(0) // not reached, TODO: remove when V's checker is improved
return &u8(unsafe { nil }) // not reached, TODO: remove when V's checker is improved
}
// free allows for manually freeing memory allocated at the address `ptr`.

View File

@ -172,7 +172,7 @@ pub fn winapi_lasterr_str() string {
// handle this case special since `FormatMessageW()` might not work anymore
return 'insufficient memory'
}
mut msgbuf := &u16(0)
mut msgbuf := &u16(unsafe { nil })
res := C.FormatMessageW(format_message_allocate_buffer | format_message_from_system | format_message_ignore_inserts,
0, err_msg_id, 0, voidptr(&msgbuf), 0, 0)
err_msg := if res == 0 {

View File

@ -1,5 +1,5 @@
fn test_isnil_byteptr() {
pb := &u8(0)
pb := &u8(unsafe { nil })
assert isnil(pb)
}
@ -9,7 +9,7 @@ fn test_isnil_voidptr() {
}
fn test_isnil_charptr() {
pc := &char(0)
pc := &char(unsafe { nil })
assert isnil(pc)
}

View File

@ -200,8 +200,8 @@ fn test_various_map_value() {
m14['test'] = voidptr(0)
assert m14['test'] == voidptr(0)
mut m15 := map[string]&byte{}
m15['test'] = &u8(0)
assert m15['test'] == &u8(0)
m15['test'] = &u8(unsafe { nil })
assert m15['test'] == &u8(unsafe { nil })
mut m16 := map[string]i64{}
m16['test'] = i64(0)
assert m16['test'] == i64(0)

View File

@ -10,7 +10,8 @@ fn mm_alloc(size u64) (&u8, Errno) {
map_flags := unsafe { MapFlags(int(MapFlags.map_private) | int(MapFlags.map_anonymous)) }
// END CONSTS
a, e := sys_mmap(&u8(0), size + sizeof(u64), mem_prot, map_flags, -1, 0)
a, e := sys_mmap(&u8(unsafe { nil }), size + sizeof(u64), mem_prot, map_flags, -1,
0)
if e == .enoerror {
unsafe {
mut ap := &u64(a)
@ -19,7 +20,7 @@ fn mm_alloc(size u64) (&u8, Errno) {
return x2, e
}
}
return &u8(0), e
return &u8(unsafe { nil }), e
}
fn mm_free(addr &u8) Errno {
@ -38,7 +39,7 @@ fn system_alloc(_ voidptr, size usize) (voidptr, usize, u32) {
map_flags := unsafe { MapFlags(int(MapFlags.map_private) | int(MapFlags.map_anonymous)) }
// END CONSTS
a, e := sys_mmap(&u8(0), u64(size), mem_prot, map_flags, -1, 0)
a, e := sys_mmap(&u8(unsafe { nil }), u64(size), mem_prot, map_flags, -1, 0)
if e == .enoerror {
return a, size, 0

View File

@ -19,7 +19,7 @@ pub fn mm_alloc(size u64) (&u8, Errno) {
*ap = pages
return &u8(a + 4), e
}
return &u8(0), e
return &u8(unsafe { nil }), e
}
pub fn mm_free(addr &u8) Errno {

View File

@ -19,7 +19,8 @@ fn fast_string_eq(a string, b string) bool {
fn map_hash_string(pkey voidptr) u64 {
key := *unsafe { &string(pkey) }
return C.wyhash(key.str, u64(key.len), 0, &u64(C._wyp))
// XTODO remove voidptr cast once virtual C.consts can be declared
return C.wyhash(key.str, u64(key.len), 0, &u64(voidptr(C._wyp)))
}
fn map_hash_int_1(pkey voidptr) u64 {

View File

@ -213,8 +213,8 @@ fn test_various_map_value() {
m14['test'] = unsafe { nil }
assert unsafe { m14['test'] } == unsafe { nil }
mut m15 := map[string]&u8{}
m15['test'] = &u8(0)
assert unsafe { m15['test'] } == &u8(0)
m15['test'] = &u8(unsafe { nil })
assert unsafe { m15['test'] } == &u8(unsafe { nil })
mut m16 := map[string]i64{}
m16['test'] = i64(0)
assert m16['test'] == i64(0)

View File

@ -409,7 +409,7 @@ fn read_property(d &C.Display, w Window, p Atom) Property {
actual_format := 0
nitems := u64(0)
bytes_after := u64(0)
ret := &u8(0)
ret := &u8(unsafe { nil })
mut read_bytes := 1024
for {
if ret != 0 {

View File

@ -205,7 +205,7 @@ pub fn (mut zentry Zip) create_entry(name string) ! {
// NOTE: remember to release the memory allocated for an output buffer.
// for large entries, please take a look at zip_entry_extract function.
pub fn (mut zentry Zip) read_entry() !voidptr {
mut buf := &u8(0)
mut buf := &u8(unsafe { nil })
mut bsize := usize(0)
res := C.zip_entry_read(zentry, unsafe { &voidptr(&buf) }, &bsize)
if res == -1 {

View File

@ -45,7 +45,7 @@ pub fn (db DB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que
.type_string, .type_var_string, .type_blob, .type_tiny_blob, .type_medium_blob,
.type_long_blob {
// Memory will be allocated later dynamically depending on the length of the value.
data_pointers << &u8(0)
data_pointers << &u8(unsafe { nil })
}
else {
return error('\'${unsafe { FieldType(field.type) }}\' is not yet implemented. Please create a new issue at https://github.com/vlang/v/issues/new')

View File

@ -176,7 +176,7 @@ fn pg_stmt_match(mut types []u32, mut vals []&char, mut lens []int, mut formats
}
orm.Null {
types << u32(0) // we do not know col type, let server infer
vals << &char(0) // NULL pointer indicates NULL
vals << &char(unsafe { nil }) // NULL pointer indicates NULL
lens << int(0) // ignored
formats << 0 // ignored
}

View File

@ -392,14 +392,14 @@ pub fn (db DB) copy_expert(query string, mut file io.ReaderWriter) !int {
}
}
code := C.PQputCopyEnd(db.conn, &char(0))
code := C.PQputCopyEnd(db.conn, &char(unsafe { nil }))
if code != 1 {
return error('pg copy error: Failed to finish copy command, code: ${code}')
}
} else if status == .copy_out {
for {
address := &char(0)
address := &char(unsafe { nil })
n_bytes := C.PQgetCopyData(db.conn, &address, 0)
if n_bytes > 0 {
mut local_buf := []u8{len: n_bytes}

View File

@ -224,7 +224,7 @@ pub fn (db &DB) q_string(query string) !string {
return db.error_message(code, query)
}
val := unsafe { &u8(C.sqlite3_column_text(stmt, 0)) }
return if val != &u8(0) { unsafe { tos_clone(val) } } else { '' }
return if val != &u8(unsafe { nil }) { unsafe { tos_clone(val) } } else { '' }
}
// exec_map executes the query on the given `db`, and returns an array of maps of strings, or an error on failure
@ -254,7 +254,7 @@ pub fn (db &DB) exec_map(query string) ![]map[string]string {
val := unsafe { &u8(C.sqlite3_column_text(stmt, i)) }
col_char := unsafe { &u8(C.sqlite3_column_name(stmt, i)) }
col := unsafe { col_char.vstring() }
if val == &u8(0) {
if val == &u8(unsafe { nil }) {
row[col] = ''
} else {
row[col] = unsafe { tos_clone(val) }
@ -294,7 +294,7 @@ pub fn (db &DB) exec(query string) ![]Row {
mut row := Row{}
for i in 0 .. nr_cols {
val := unsafe { &u8(C.sqlite3_column_text(stmt, i)) }
if val == &u8(0) {
if val == &u8(unsafe { nil }) {
row.vals << ''
} else {
row.vals << unsafe { val.vstring() }
@ -388,7 +388,7 @@ pub fn (db &DB) exec_param_many(query string, params []string) ![]Row {
mut row := Row{}
for i in 0 .. nr_cols {
val := unsafe { &u8(C.sqlite3_column_text(stmt, i)) }
if val == &u8(0) {
if val == &u8(unsafe { nil }) {
row.vals << ''
} else {
row.vals << unsafe { val.vstring() }

View File

@ -71,7 +71,7 @@ fn (stmt &Stmt) get_text(idx int) ?string {
return none
} else {
b := &char(C.sqlite3_column_text(stmt.stmt, idx))
if b == &char(0) {
if b == &char(unsafe { nil }) {
return ''
}
return unsafe { b.vstring() }

View File

@ -204,7 +204,7 @@ pub fn (s &Context) set_font(font_id int) {
// The function returns the `x` coordinate of the resulting render.
@[inline]
pub fn (s &Context) draw_text(x f32, y f32, text string) f32 {
return C.fonsDrawText(s, x, y, &char(text.str), &char(0))
return C.fonsDrawText(s, x, y, &char(text.str), &char(unsafe { nil }))
}
// text_bounds fills the `bounds` argument with the pixel dimensions
@ -218,7 +218,7 @@ pub fn (s &Context) draw_text(x f32, y f32, text string) f32 {
// `bounds[3]` is the `y` coordinate of the bottom-right point.
@[inline]
pub fn (s &Context) text_bounds(x f32, y f32, text string, bounds &f32) f32 {
return C.fonsTextBounds(s, x, y, &char(text.str), &char(0), bounds)
return C.fonsTextBounds(s, x, y, &char(text.str), &char(unsafe { nil }), bounds)
}
// line_bounds fills `miny` and `maxy` with the values of the `minimum`

View File

@ -307,7 +307,7 @@ pub fn (ctx &Context) draw_image_with_config(config DrawImageConfig) {
return
}
if img.width == 0 {
println('w=0')
println('gg: draw_image() width=0')
return
}
if !os.exists(img.path) {

View File

@ -9,7 +9,7 @@ fn C.wyhash64(u64, u64) u64
// wyhash_c returns a hash given a byte string `key`, its `len`, and a `seed`.
@[inline]
pub fn wyhash_c(key &u8, len u64, seed u64) u64 {
return C.wyhash(key, len, seed, &u64(C._wyp))
return C.wyhash(key, len, seed, &u64(voidptr(C._wyp)))
}
// wyhash64_c returns a hash given two u64 values `a` and `b`.

View File

@ -85,6 +85,9 @@ pub fn unsetenv(name string) int {
// See: https://docs.microsoft.com/bg-bg/windows/win32/api/processenv/nf-processenv-getenvironmentstrings
// os.environ returns a map of all the current environment variables
// TODO how to declare Virtual C globals?
// const C.environ &&char
pub fn environ() map[string]string {
mut res := map[string]string{}
$if windows {
@ -102,7 +105,7 @@ pub fn environ() map[string]string {
}
C.FreeEnvironmentStringsW(estrings)
} $else {
start := &&char(C.environ)
start := &&char(voidptr(C.environ))
mut i := 0
for {
x := unsafe { start[i] }

View File

@ -579,7 +579,7 @@ pub fn get_raw_line() string {
}
} $else {
max := usize(0)
buf := unsafe { &u8(0) }
buf := &u8(unsafe { nil })
nr_chars := unsafe { C.getline(voidptr(&buf), &max, C.stdin) }
str := unsafe { tos(buf, if nr_chars < 0 { 0 } else { nr_chars }) }
ret := str.clone()
@ -624,7 +624,7 @@ pub fn get_raw_stdin() []u8 {
}
} $else {
max := usize(0)
buf := unsafe { &u8(0) }
buf := &u8(unsafe { nil })
nr_chars := unsafe { C.getline(voidptr(&buf), &max, C.stdin) }
return array{
element_size: 1
@ -995,7 +995,7 @@ pub fn execvp(cmdpath string, cmdargs []string) ! {
for i in 0 .. cmdargs.len {
cargs << &char(cmdargs[i].str)
}
cargs << &char(0)
cargs << &char(unsafe { nil })
mut res := int(0)
$if windows {
res = C._execvp(&char(cmdpath.str), cargs.data)
@ -1026,8 +1026,8 @@ pub fn execve(cmdpath string, cmdargs []string, envs []string) ! {
for i in 0 .. envs.len {
cenvs << &char(envs[i].str)
}
cargv << &char(0)
cenvs << &char(0)
cargv << &char(unsafe { nil })
cenvs << &char(unsafe { nil })
mut res := int(0)
$if windows {
res = C._execve(&char(cmdpath.str), cargv.data, cenvs.data)

View File

@ -293,9 +293,9 @@ pub fn execute(cmd string) Result {
// user provided escape sequences.
@[unsafe]
pub fn raw_execute(cmd string) Result {
mut child_stdin := &u32(0)
mut child_stdout_read := &u32(0)
mut child_stdout_write := &u32(0)
mut child_stdin := &u32(unsafe { nil })
mut child_stdout_read := &u32(unsafe { nil })
mut child_stdout_write := &u32(unsafe { nil })
mut sa := SecurityAttributes{}
sa.n_length = sizeof(C.SECURITY_ATTRIBUTES)
sa.b_inherit_handle = true
@ -609,8 +609,8 @@ pub fn disk_usage(path string) !DiskUsage {
mut available := u64(0)
mut ret := false
if path == '.' || path == '' {
ret = C.GetDiskFreeSpaceExA(&char(0), &free_bytes_available_to_caller, &total,
&available)
ret = C.GetDiskFreeSpaceExA(&char(unsafe { nil }), &free_bytes_available_to_caller,
&total, &available)
} else {
ret = C.GetDiskFreeSpaceExA(&char(path.str), &free_bytes_available_to_caller,
&total, &available)

View File

@ -32,10 +32,10 @@ fn failed_cfn_report_error(ok bool, label string) {
fn close_valid_handle(p voidptr) {
h := &&u32(p)
if *h != &u32(0) {
if *h != &u32(unsafe { nil }) {
C.CloseHandle(*h)
unsafe {
*h = &u32(0)
*h = &u32(nil)
}
}
}
@ -231,7 +231,7 @@ fn (mut p Process) win_read_string(idx int, _maxbytes int) (string, int) {
if unsafe { wdata == 0 } {
return '', 0
}
mut rhandle := &u32(0)
mut rhandle := &u32(unsafe { nil })
if idx == 1 {
rhandle = wdata.child_stdout_read
}
@ -263,7 +263,7 @@ fn (mut p Process) win_is_pending(idx int) bool {
if unsafe { wdata == 0 } {
return false
}
mut rhandle := &u32(0)
mut rhandle := &u32(unsafe { nil })
if idx == 1 {
rhandle = wdata.child_stdout_read
}
@ -285,7 +285,7 @@ fn (mut p Process) win_slurp(idx int) string {
if unsafe { wdata == 0 } {
return ''
}
mut rhandle := &u32(0)
mut rhandle := &u32(unsafe { nil })
if idx == 1 {
rhandle = wdata.child_stdout_read
}

View File

@ -49,7 +49,7 @@ pub mut:
sample_count int
blend_color Color
alpha_to_coverage_enabled bool
label &char = &char(0)
label &char = &char(unsafe { nil })
}
pub type PipelineDesc = C.sg_pipeline_desc

View File

@ -29,7 +29,7 @@ pub fn screenshot_window() &Screenshot {
pub fn (mut ss Screenshot) free() {
unsafe {
free(ss.pixels)
ss.pixels = &u8(0)
ss.pixels = &u8(nil)
}
}

View File

@ -69,8 +69,8 @@ pub fn new_channel[T](n u32) &Channel {
fn new_channel_st(n u32, st u32) &Channel {
wsem := if n > 0 { n } else { 1 }
rsem := if n > 0 { u32(0) } else { 1 }
rbuf := if n > 0 { unsafe { malloc(int(n * st)) } } else { &u8(0) }
sbuf := if n > 0 { vcalloc_noscan(int(n * 2)) } else { &u8(0) }
rbuf := if n > 0 { unsafe { malloc(int(n * st)) } } else { &u8(unsafe { nil }) }
sbuf := if n > 0 { vcalloc_noscan(int(n * 2)) } else { &u8(unsafe { nil }) }
mut ch := Channel{
objsize: st
cap: n
@ -92,8 +92,8 @@ fn new_channel_st_noscan(n u32, st u32) &Channel {
$if gcboehm_opt ? {
wsem := if n > 0 { n } else { 1 }
rsem := if n > 0 { u32(0) } else { 1 }
rbuf := if n > 0 { unsafe { malloc_noscan(int(n * st)) } } else { &u8(0) }
sbuf := if n > 0 { vcalloc_noscan(int(n * 2)) } else { &u8(0) }
rbuf := if n > 0 { unsafe { malloc_noscan(int(n * st)) } } else { &u8(unsafe { nil }) }
sbuf := if n > 0 { vcalloc_noscan(int(n * 2)) } else { &u8(unsafe { nil }) }
mut ch := Channel{
objsize: st
cap: n

View File

@ -914,7 +914,7 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ! {
first := DottedKey([dotted_key[0]]) // The array that holds the entries
last := DottedKey([dotted_key[1]]) // The key the parsed array data should be added to
mut t_arr := &[]ast.Value(0)
mut t_arr := &[]ast.Value(unsafe { nil })
mut t_map := ast.Value(ast.Null{})
unsafe {

View File

@ -3594,6 +3594,17 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
c.error('cannot cast type `${ft}` to `${tt}`', node.pos)
}
// if from_type == ast.voidptr_type_idx && !c.inside_unsafe && !c.pref.translated
// Do not allow `&u8(unsafe { nil })` etc, force nil or voidptr cast
if from_type.is_number() && to_type.is_ptr() && !c.inside_unsafe && !c.pref.translated
&& !c.file.is_translated {
if from_sym.language != .c {
// TODO make an error
c.warn('cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`',
node.pos)
}
}
// T(0) where T is array or map
if node.typ.has_flag(.generic) && to_sym.kind in [.array, .map, .array_fixed]
&& node.expr.is_literal() {

View File

@ -1,13 +1,13 @@
vlib/v/checker/tests/cast_expr_T_type_err.vv:4:9: error: unknown type `A`
vlib/v/checker/tests/cast_expr_T_type_err.vv:4:6: error: unknown type `A`
2 |
3 | fn main() {
4 | _ = A(0)
| ~~~~
5 | _ = &A(0)
5 | _ = &A(unsafe { nil })
6 | }
vlib/v/checker/tests/cast_expr_T_type_err.vv:5:9: error: unknown type `A`
vlib/v/checker/tests/cast_expr_T_type_err.vv:5:6: error: unknown type `A`
3 | fn main() {
4 | _ = A(0)
5 | _ = &A(0)
| ~~~~~
5 | _ = &A(unsafe { nil })
| ~~~~~~~~~~~~~~~~~~
6 | }

View File

@ -2,5 +2,5 @@ module main
fn main() {
_ = A(0)
_ = &A(0)
_ = &A(unsafe { nil })
}

View File

@ -3,17 +3,17 @@ vlib/v/checker/tests/fixed_array_conv.vv:3:5: notice: left-side of assignment ex
2 | mut p := unsafe { nil }
3 | p = arr
| ~~~
4 | mut ip := &int(0)
4 | mut ip := &int(unsafe { nil })
5 | ip = arr
vlib/v/checker/tests/fixed_array_conv.vv:5:6: notice: left-side of assignment expects a mutable reference, but variable `arr` is immutable, declare it with `mut` to make it mutable or clone it
3 | p = arr
4 | mut ip := &int(0)
4 | mut ip := &int(unsafe { nil })
5 | ip = arr
| ~~~
6 | _ = &int(arr)
7 | _ = p
vlib/v/checker/tests/fixed_array_conv.vv:6:5: warning: cannot cast a fixed array (use e.g. `&arr[0]` instead)
4 | mut ip := &int(0)
4 | mut ip := &int(unsafe { nil })
5 | ip = arr
6 | _ = &int(arr)
| ~~~~~~~~~
@ -24,25 +24,25 @@ vlib/v/checker/tests/fixed_array_conv.vv:3:3: error: mismatched types `voidptr`
2 | mut p := unsafe { nil }
3 | p = arr
| ^
4 | mut ip := &int(0)
4 | mut ip := &int(unsafe { nil })
5 | ip = arr
vlib/v/checker/tests/fixed_array_conv.vv:3:5: error: cannot assign to `p`: expected `voidptr`, not `[2]int`
1 | arr := [2, 3]!
2 | mut p := unsafe { nil }
3 | p = arr
| ~~~
4 | mut ip := &int(0)
4 | mut ip := &int(unsafe { nil })
5 | ip = arr
vlib/v/checker/tests/fixed_array_conv.vv:5:4: error: mismatched types `&int` and `[2]int`
3 | p = arr
4 | mut ip := &int(0)
4 | mut ip := &int(unsafe { nil })
5 | ip = arr
| ^
6 | _ = &int(arr)
7 | _ = p
vlib/v/checker/tests/fixed_array_conv.vv:5:6: error: cannot assign to `ip`: expected `&int`, not `[2]int`
3 | p = arr
4 | mut ip := &int(0)
4 | mut ip := &int(unsafe { nil })
5 | ip = arr
| ~~~
6 | _ = &int(arr)

View File

@ -1,7 +1,7 @@
arr := [2, 3]!
mut p := unsafe { nil }
p = arr
mut ip := &int(0)
mut ip := &int(unsafe { nil })
ip = arr
_ = &int(arr)
_ = p

View File

@ -1,3 +1,10 @@
vlib/v/checker/tests/globals/cast_expr_T_type_err.vv:5:8: warning: cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`
3 | __global (
4 | fo = A(0)
5 | fo1 = &A(0)
| ~~~~~
6 | )
7 |
vlib/v/checker/tests/globals/cast_expr_T_type_err.vv:4:7: error: unknown type `A`
2 |
3 | __global (

View File

@ -1,3 +1,21 @@
vlib/v/checker/tests/struct_ptr_cast_int_outside_unsafe_err.vv:7:5: warning: cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`
5 | a := 1
6 |
7 | _ = &Context(a)
| ~~~~~~~~~~~
8 | _ = &Context(b)
9 | _ = &Context(1)
vlib/v/checker/tests/struct_ptr_cast_int_outside_unsafe_err.vv:8:5: warning: cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`
6 |
7 | _ = &Context(a)
8 | _ = &Context(b)
| ~~~~~~~~~~~
9 | _ = &Context(1)
vlib/v/checker/tests/struct_ptr_cast_int_outside_unsafe_err.vv:9:5: warning: cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`
7 | _ = &Context(a)
8 | _ = &Context(b)
9 | _ = &Context(1)
| ~~~~~~~~~~~
vlib/v/checker/tests/struct_ptr_cast_int_outside_unsafe_err.vv:7:5: error: cannot cast int to a struct pointer outside `unsafe`
5 | a := 1
6 |

View File

@ -1,3 +1,21 @@
vlib/v/checker/tests/struct_ptr_cast_zero_err.vv:7:5: warning: cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`
5 | b := 0
6 |
7 | _ = &Context(0)
| ~~~~~~~~~~~
8 | _ = &Context(a)
9 | _ = &Context(b)
vlib/v/checker/tests/struct_ptr_cast_zero_err.vv:8:5: warning: cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`
6 |
7 | _ = &Context(0)
8 | _ = &Context(a)
| ~~~~~~~~~~~
9 | _ = &Context(b)
vlib/v/checker/tests/struct_ptr_cast_zero_err.vv:9:5: warning: cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`
7 | _ = &Context(0)
8 | _ = &Context(a)
9 | _ = &Context(b)
| ~~~~~~~~~~~
vlib/v/checker/tests/struct_ptr_cast_zero_err.vv:7:5: error: cannot null cast a struct pointer, use &Context(unsafe { nil })
5 | b := 0
6 |

View File

@ -1 +1,8 @@
vlib/v/checker/tests/unsafe_generic_call_test.vv:8:15: warning: cannot cast a number to a type reference, use `nil` or a voidptr cast first: `&Type(voidptr(123))`
6 |
7 | fn test_main() {
8 | pointers := [&int(1234)]
| ~~~~~~~~~~
9 | length := 1
10 | array := unsafe { arrays.carray_to_varray[&Blah](pointers, length) }
[&Blah{}]

View File

@ -26,11 +26,11 @@ pub fn (mut ed EmbedFileData) free() {
ed.compression_type.free()
if ed.free_compressed {
free(ed.compressed)
ed.compressed = &u8(0)
ed.compressed = &u8(nil)
}
if ed.free_uncompressed {
free(ed.uncompressed)
ed.uncompressed = &u8(0)
ed.uncompressed = &u8(nil)
}
}
}

View File

@ -13,10 +13,10 @@ fn main() {
dump(voidptr(ppb))
dump(voidptr(pppb))
dump(voidptr(ppppb))
pc := &char(0)
ppc := &&char(0)
pppc := &&&char(0)
ppppc := &&&&char(0)
pc := &char(nil)
ppc := &&char(nil)
pppc := &&&char(nil)
ppppc := &&&&char(nil)
dump(voidptr(pc))
dump(voidptr(ppc))
dump(voidptr(pppc))

View File

@ -96,7 +96,7 @@ mut:
is_assign_lhs bool // inside left part of assign expr (for array_set(), etc)
is_void_expr_stmt bool // ExprStmt whose result is discarded
is_arraymap_set bool // map or array set value state
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&u8(0)` etc
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&u8(unsafe { nil })` etc
is_sql bool // Inside `sql db{}` statement, generating sql instead of C (e.g. `and` instead of `&&` etc)
is_shared bool // for initialization of hidden mutex in `[rw]shared` literals
is_vlines_enabled bool // is it safe to generate #line directives when -g is passed

View File

@ -1,8 +1,8 @@
type ALchar = char
fn test_alias_char_type_reference() {
c1 := &char(0)
c2 := &ALchar(0)
c1 := &char(unsafe { nil })
c2 := &ALchar(unsafe { nil })
println('${typeof(c1).name} ${c1}')
assert '${c1}' == '0'
println('${typeof(c2).name} ${c2}')

View File

@ -96,7 +96,7 @@ fn test_inttypes_string_interpolation() {
i := -1622999040 // -0x60BD 0000
ui := u32(3421958087) // 0xCBF6 EFC7
vp := voidptr(ui)
mut bp := &u8(0)
mut bp := &u8(unsafe { nil })
$if x64 {
bp = &u8(15541149836) // 0x3 9E53 208C
} $else {

View File

@ -3,7 +3,7 @@ fn multi_voidptr_ret() (voidptr, bool) {
}
fn multi_byteptr_ret() (&u8, bool) {
return &u8(0), true
return &u8(unsafe { nil }), true
}
fn test_multi_ptrtype_ret() {

View File

@ -2,12 +2,12 @@
module trace_calls
@[markused]
__global g_stack_base = &u8(0)
__global g_stack_base = &u8(unsafe { nil })
__global g_start_time = u64(0)
@[markused]
pub fn on_call(fname string) {
mut volatile pfbase := unsafe { &u8(0) }
mut volatile pfbase := &u8(unsafe { nil })
volatile fbase := u8(0)
ns := current_time() - g_start_time
mut ssize := u64(0)

View File

@ -131,7 +131,7 @@ pub fn (mut tf_skl TTF_render_Sokol) create_texture() {
height: h
num_mipmaps: 0
// usage: .dynamic
label: &char(0)
label: &char(unsafe { nil })
d3d11_texture: 0
}
// comment for dynamic