checker: fix warning & allow assigning to a union field without unsafe (#7970)
parent
8d3069f643
commit
141b0cb882
|
@ -522,7 +522,6 @@ pub fn atof64(s string) f64 {
|
|||
|
||||
res_parsing,pn = parser(s + ' ') // TODO: need an extra char for now
|
||||
// println(pn)
|
||||
unsafe {
|
||||
match res_parsing {
|
||||
parser_ok {
|
||||
res.u = converter(mut pn)
|
||||
|
@ -542,6 +541,5 @@ pub fn atof64(s string) f64 {
|
|||
else {
|
||||
}
|
||||
}
|
||||
return res.f
|
||||
}
|
||||
return unsafe {res.f}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ pub fn atof_quick(s string) f64 {
|
|||
i++
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
// infinite
|
||||
if s[i] == `i` && i + 2 < s.len && s[i + 1] == `n` && s[i + 2] == `f` {
|
||||
if sign > 0.0 {
|
||||
|
@ -46,7 +45,7 @@ pub fn atof_quick(s string) f64 {
|
|||
else {
|
||||
f.u = double_minus_infinity
|
||||
}
|
||||
return f.f
|
||||
return unsafe {f.f}
|
||||
}
|
||||
// skip zeros
|
||||
for i < s.len && s[i] == `0` {
|
||||
|
@ -59,7 +58,7 @@ pub fn atof_quick(s string) f64 {
|
|||
else {
|
||||
f.u = double_minus_zero
|
||||
}
|
||||
return f.f
|
||||
return unsafe {f.f}
|
||||
}
|
||||
}
|
||||
// integer part
|
||||
|
@ -110,11 +109,11 @@ pub fn atof_quick(s string) f64 {
|
|||
else {
|
||||
f.u = double_minus_infinity
|
||||
}
|
||||
return f.f
|
||||
return unsafe {f.f}
|
||||
}
|
||||
tmp_mul := Float64u{u: pos_exp[exp]}
|
||||
// C.printf("exp: %d [0x%016llx] %f,",exp,pos_exp[exp],tmp_mul)
|
||||
f.f = f.f * tmp_mul.f
|
||||
f.f = unsafe {f.f * tmp_mul.f}
|
||||
}
|
||||
else {
|
||||
if exp > neg_exp.len {
|
||||
|
@ -124,14 +123,15 @@ pub fn atof_quick(s string) f64 {
|
|||
else {
|
||||
f.u = double_minus_zero
|
||||
}
|
||||
return f.f
|
||||
return unsafe {f.f}
|
||||
}
|
||||
tmp_mul := Float64u{u: neg_exp[exp]}
|
||||
|
||||
// C.printf("exp: %d [0x%016llx] %f,",exp,pos_exp[exp],tmp_mul)
|
||||
f.f = f.f * tmp_mul.f
|
||||
f.f = unsafe {f.f * tmp_mul.f}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
f.f = f.f * sign
|
||||
return f.f
|
||||
}
|
||||
|
|
|
@ -22,14 +22,14 @@ fn f64_from_bits1(b u64) f64 {
|
|||
mut x := Ufloat64{}
|
||||
x.b = b
|
||||
//C.printf("bin: %016llx\n",x.f)
|
||||
return x.f
|
||||
return unsafe {x.f}
|
||||
}
|
||||
|
||||
fn f32_from_bits1(b u32) f32 {
|
||||
mut x := Ufloat32{}
|
||||
x.b = b
|
||||
//C.printf("bin: %08x\n",x.f)
|
||||
return x.f
|
||||
return unsafe {x.f}
|
||||
}
|
||||
|
||||
fn test_float_to_str() {
|
||||
|
|
|
@ -321,7 +321,7 @@ pub fn f32_to_decimal(mant u32, exp u32) Dec32 {
|
|||
// f32_to_str return a string in scientific notation with max n_digit after the dot
|
||||
pub fn f32_to_str(f f32, n_digit int) string {
|
||||
mut u1 := Uf32{}
|
||||
unsafe { u1.f = f }
|
||||
u1.f = f
|
||||
u := unsafe {u1.u}
|
||||
|
||||
neg := (u>>(mantbits32+expbits32)) != 0
|
||||
|
@ -348,7 +348,7 @@ pub fn f32_to_str(f f32, n_digit int) string {
|
|||
// f32_to_str return a string in scientific notation with max n_digit after the dot
|
||||
pub fn f32_to_str_pad(f f32, n_digit int) string {
|
||||
mut u1 := Uf32{}
|
||||
unsafe { u1.f = f }
|
||||
u1.f = f
|
||||
u := unsafe {u1.u}
|
||||
|
||||
neg := (u>>(mantbits32+expbits32)) != 0
|
||||
|
|
|
@ -370,7 +370,7 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
|
|||
// f64_to_str return a string in scientific notation with max n_digit after the dot
|
||||
pub fn f64_to_str(f f64, n_digit int) string {
|
||||
mut u1 := Uf64{}
|
||||
unsafe { u1.f = f }
|
||||
u1.f = f
|
||||
u := unsafe {u1.u}
|
||||
|
||||
neg := (u>>(mantbits64+expbits64)) != 0
|
||||
|
@ -395,7 +395,7 @@ pub fn f64_to_str(f f64, n_digit int) string {
|
|||
// f64_to_str return a string in scientific notation with max n_digit after the dot
|
||||
pub fn f64_to_str_pad(f f64, n_digit int) string {
|
||||
mut u1 := Uf64{}
|
||||
unsafe { u1.f = f }
|
||||
u1.f = f
|
||||
u := unsafe {u1.u}
|
||||
|
||||
neg := (u>>(mantbits64+expbits64)) != 0
|
||||
|
|
|
@ -108,6 +108,7 @@ pub:
|
|||
field_name string
|
||||
is_mut bool // is used for the case `if mut ident.selector is MyType {`, it indicates if the root ident is mutable
|
||||
mut_pos token.Position
|
||||
next_token token.Kind
|
||||
pub mut:
|
||||
expr_type table.Type // type of `Foo` in `Foo.bar`
|
||||
typ table.Type // type of the entire thing (`Foo.bar`)
|
||||
|
|
|
@ -1062,9 +1062,6 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
|
|||
// No automatic lock for struct access
|
||||
explicit_lock_needed = true
|
||||
}
|
||||
if struct_info.is_union && !c.inside_unsafe {
|
||||
c.warn('accessing union fields requires `unsafe`', expr.pos)
|
||||
}
|
||||
}
|
||||
.array, .string {
|
||||
// This should only happen in `builtin`
|
||||
|
@ -2028,6 +2025,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T
|
|||
has_field = true
|
||||
field = f
|
||||
} else {
|
||||
// look for embedded field
|
||||
if sym.info is table.Struct {
|
||||
mut found_fields := []table.Field{}
|
||||
mut embed_of_found_fields := []table.Type{}
|
||||
|
@ -2050,6 +2048,14 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T
|
|||
unknown_field_msg = err
|
||||
}
|
||||
}
|
||||
if !c.inside_unsafe {
|
||||
if sym.info is table.Struct {
|
||||
if sym.info.is_union && selector_expr.next_token !in token.assign_tokens {
|
||||
c.warn('reading a union field (or its address) requires `unsafe`',
|
||||
selector_expr.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if has_field {
|
||||
if sym.mod != c.mod && !field.is_pub && sym.language != .c {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
vlib/v/checker/tests/union_unsafe_fields.vv:10:9: error: reading a union field (or its address) requires `unsafe`
|
||||
8 | mut u := Uf32{u: 3}
|
||||
9 | u.f = 3.3 // ok
|
||||
10 | _ := u.u
|
||||
| ^
|
||||
11 | return &u.f
|
||||
12 | }
|
||||
vlib/v/checker/tests/union_unsafe_fields.vv:11:12: error: reading a union field (or its address) requires `unsafe`
|
||||
9 | u.f = 3.3 // ok
|
||||
10 | _ := u.u
|
||||
11 | return &u.f
|
||||
| ^
|
||||
12 | }
|
|
@ -0,0 +1,12 @@
|
|||
union Uf32 {
|
||||
mut:
|
||||
f f32
|
||||
u u32
|
||||
}
|
||||
|
||||
fn f() f32 {
|
||||
mut u := Uf32{u: 3}
|
||||
u.f = 3.3 // ok
|
||||
_ := u.u
|
||||
return &u.f
|
||||
}
|
|
@ -1528,13 +1528,12 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
|
|||
is_mut: is_mut
|
||||
mut_pos: mut_pos
|
||||
scope: p.scope
|
||||
next_token: p.tok.kind
|
||||
}
|
||||
mut node := ast.Expr{}
|
||||
node = sel_expr
|
||||
if is_filter {
|
||||
p.close_scope()
|
||||
}
|
||||
return node
|
||||
return sel_expr
|
||||
}
|
||||
|
||||
// `.green`
|
||||
|
|
Loading…
Reference in New Issue