ci: fix all `-cstrict` warnings with gcc and clang (#9792)

pull/9804/head
spaceface 2021-04-19 14:38:48 +02:00 committed by GitHub
parent dde3189e66
commit 73352583e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 295 additions and 296 deletions

View File

@ -59,7 +59,7 @@ jobs:
echo $VFLAGS
make
./v -d debug_malloc -d debug_realloc -o v cmd/v
./v -cg -cflags -Werror -o v cmd/v
./v -cg -cstrict -o v cmd/v
# Test v -realloc arena allocation
./v -o vrealloc -prealloc cmd/v && ./vrealloc -o v3 cmd/v && ./v3 -o v4 cmd/v
- name: Test v->c
@ -78,8 +78,8 @@ jobs:
./cmd/tools/test_if_v_test_system_works
- name: Self tests
run: ./v -silent test-self
- name: Self tests (-Werror)
run: ./v -cflags -Werror test-self
# - name: Self tests (-cstrict)
# run: ./v -cstrict test-self
- name: Test time functions in a timezone UTC-12
run: TZ=Etc/GMT+12 ./v test vlib/time/
- name: Test time functions in a timezone UTC-3
@ -268,7 +268,7 @@ jobs:
brew install postgresql
export LIBRARY_PATH="$LIBRARY_PATH:/usr/local/opt/openssl/lib/"
- name: Build V
run: make -j4 && ./v -cg -cflags -Werror -o v cmd/v
run: make -j4 && ./v -cg -cstrict -o v cmd/v
- name: Run sanitizers
run: |
./v -o v2 cmd/v -cflags -fsanitize=undefined
@ -339,7 +339,7 @@ jobs:
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev
- name: Build V
run: make -j4 && ./v -cc gcc -cg -cflags -Werror -o v cmd/v
run: make -j4 && ./v -cc gcc -cg -cstrict -o v cmd/v
- name: Valgrind v.c
run: valgrind --error-exitcode=1 ./v -o v.c cmd/v
- name: Run sanitizers
@ -375,8 +375,8 @@ jobs:
./v -silent test-self
- name: Self tests (-prod)
run: ./v -o vprod -prod cmd/v && ./vprod -silent test-self
- name: Self tests (-Werror)
run: ./v -cc gcc -cflags "-Werror" test-self
- name: Self tests (-cstrict)
run: ./v -cc gcc -cstrict test-self
- name: Build examples
run: ./v build-examples
- name: Build tetris.v with -autofree
@ -434,7 +434,7 @@ jobs:
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev
sudo apt-get install clang
- name: Build V
run: make -j4 && ./v -cc clang -cg -cflags -Werror -o v cmd/v
run: make -j4 && ./v -cc clang -cg -cstrict -o v cmd/v
- name: Valgrind
run: valgrind --error-exitcode=1 ./v -o v.c cmd/v
- name: Run sanitizers
@ -460,8 +460,8 @@ jobs:
./v -silent test-self
- name: Self tests (-prod)
run: ./v -o vprod -prod cmd/v && ./vprod -silent test-self
- name: Self tests (-Werror)
run: ./v -cflags "-Werror" test-self
- name: Self tests (-cstrict)
run: ./v -cstrict test-self
- name: Build examples
run: ./v build-examples
- name: Build examples with -autofree

View File

@ -27,7 +27,7 @@ jobs:
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev
sudo apt-get install clang
- name: Build V
run: make -j4 && ./v -cg -cflags -Werror -o v cmd/v
run: make -j4 && ./v -cg -cstrict -o v cmd/v
- name: Self tests (-fsanitize=undefined)
run: ./v -cflags "-fsanitize=undefined" -o v2 cmd/v && ./v2 -cflags -fsanitize=undefined test-self
- name: Build examples (V compiled with -fsanitize=undefined)
@ -50,7 +50,7 @@ jobs:
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev
- name: Build V
run: make -j4 && ./v -cg -cflags -Werror -o v cmd/v
run: make -j4 && ./v -cg -cstrict -o v cmd/v
- name: Self tests (-fsanitize=undefined)
run: ./v -cflags "-fsanitize=undefined" -o v2 cmd/v && ./v2 -cflags -fsanitize=undefined test-self
- name: Build examples (V compiled with -fsanitize=undefined)
@ -74,7 +74,7 @@ jobs:
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev
sudo apt-get install clang
- name: Build V
run: make -j4 && ./v -cg -cflags -Werror -o v cmd/v
run: make -j4 && ./v -cg -cstrict -o v cmd/v
- name: Self tests (-fsanitize=address)
run: ASAN_OPTIONS=detect_leaks=0 ./v -cflags "-fsanitize=address,pointer-compare,pointer-subtract" test-self
- name: Self tests (V compiled with -fsanitize=address)
@ -128,7 +128,7 @@ jobs:
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev
sudo apt-get install clang
- name: Build V
run: make -j4 && ./v -cg -cflags -Werror -o v cmd/v
run: make -j4 && ./v -cg -cstrict -o v cmd/v
- name: Self tests (-fsanitize=address)
run: ASAN_OPTIONS=detect_leaks=0 ./v -cflags -fsanitize=address test-self
- name: Self tests (V compiled with -fsanitize=address)
@ -156,7 +156,7 @@ jobs:
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev
sudo apt-get install clang
- name: Build V
run: make -j4 && ./v -cc clang -cg -cflags -Werror -o v cmd/v
run: make -j4 && ./v -cc clang -cg -cstrict -o v cmd/v
- name: Self tests (-fsanitize=memory)
run: ./v -cflags -fsanitize=memory test-self
- name: Self tests (V compiled with -fsanitize=memory)

View File

@ -58,8 +58,8 @@ fn get_all_commands() []Command {
okmsg: 'V can compile itself.'
}
res << Command{
line: '$vexe -o vtmp_werror -cflags -Werror cmd/v'
okmsg: 'V can compile itself with -cflags -Werror too.'
line: '$vexe -o vtmp_werror -cstrict cmd/v'
okmsg: 'V can compile itself with -cstrict too.'
}
res << Command{
line: '$vexe $vargs -progress test-cleancode'

View File

@ -27,61 +27,16 @@ const (
'vlib/crypto/rand/crypto_rand_read_test.v',
]
skip_with_fsanitize_address = [
'vlib/json/json_test.v',
'vlib/regex/regex_test.v',
'vlib/x/websocket/websocket_test.v',
]
skip_with_fsanitize_undefined = [
'do_not_remove',
]
skip_with_werror = [
'vlib/clipboard/clipboard_test.v',
'vlib/eventbus/eventbus_test.v',
'vlib/json/json_test.v',
'vlib/orm/orm_test.v',
'vlib/sqlite/sqlite_test.v',
'vlib/regex/regex_test.v',
'vlib/strconv/f32_f64_to_string_test.v',
'vlib/strconv/number_to_base_test.v',
'vlib/sync/atomic2/atomic_test.v',
'vlib/sync/pool/pool_test.v',
'vlib/v/tests/assert_sumtype_test.v',
'vlib/v/tests/autolock_array1_test.v',
'vlib/v/tests/blank_ident_test.v',
'vlib/v/tests/comptime_call_test.v',
'vlib/v/tests/comptime_at_test.v',
'vlib/v/tests/comptime_if_expr_test.v',
'vlib/v/tests/cstrings_test.v',
'vlib/v/tests/enum_test.v',
'vlib/v/tests/fn_variadic_test.v',
'vlib/v/tests/generics_method_test.v',
'vlib/v/tests/generics_test.v',
'vlib/v/tests/in_expression_test.v',
'vlib/v/tests/interface_edge_cases/assign_to_interface_field_test.v',
'vlib/v/tests/interface_fields_test.v',
'vlib/v/tests/interface_variadic_test.v',
'vlib/v/tests/operator_overloading_with_string_interpolation_test.v',
'vlib/v/tests/orm_sub_struct_test.v',
'vlib/v/tests/shared_array_test.v',
'vlib/v/tests/shared_autolock_test.v',
'vlib/v/tests/shared_elem_test.v',
'vlib/v/tests/shared_lock_2_test.v',
'vlib/v/tests/shared_lock_3_test.v',
'vlib/v/tests/shared_lock_4_test.v',
'vlib/v/tests/shared_lock_test.v',
'vlib/v/tests/shift_test.v',
'vlib/v/tests/str_gen_test.v',
'vlib/v/tests/string_interpolation_multi_return_test.v',
'vlib/v/tests/string_interpolation_test.v',
'vlib/v/tests/struct_test.v',
'vlib/v/tests/sum_type_test.v',
'vlib/v/tests/type_name_test.v',
// -Wduplicated-branches
'vlib/v/tests/match_in_fn_call_test.v',
'vlib/v/tests/match_test.v',
'vlib/v/tests/unsafe_test.v',
'vlib/v/tests/working_with_an_empty_struct_test.v',
'vlib/vweb/request_test.v',
'vlib/vweb/route_test.v',
'vlib/x/websocket/websocket_test.v',
'vlib/x/ttf/ttf_test.v',
]
skip_with_asan_compiler = [
'do_not_remove',
@ -164,7 +119,7 @@ fn main() {
if arg.contains('-msan-compiler') {
msan_compiler = true
}
if arg.contains('-Werror') {
if arg.contains('-Werror') || arg.contains('-cstrict') {
werror = true
}
if arg.contains('-fsanitize=memory') {

View File

@ -211,10 +211,10 @@ static inline unsigned atomic_fetch_xor_u32(unsigned* x, unsigned y) {
static inline unsigned short atomic_load_u16(unsigned short* x) {
return __atomic_load_2(x, memory_order_seq_cst);
}
static inline void atomic_store_u16(unsigned short* x, unsigned short y) {
static inline void atomic_store_u16(void* x, unsigned short y) {
__atomic_store_2(x, y, memory_order_seq_cst);
}
static inline int atomic_compare_exchange_weak_u16(unsigned short* x, unsigned short* expected, unsigned short y) {
static inline int atomic_compare_exchange_weak_u16(void* x, unsigned short* expected, unsigned short y) {
return (int)__atomic_compare_exchange_2(x, expected, y, memory_order_seq_cst, memory_order_seq_cst);
}
static inline int atomic_compare_exchange_strong_u16(unsigned short* x, unsigned short* expected, unsigned short y) {

View File

@ -64,7 +64,7 @@ fn test_unsigned_cast() {
assert '-0x00_0_f_ff'.u32() == 0
assert '10_000_000'.u32() == 10000000
for n in 0 .. 100 {
for n in 0 .. u32(100) {
s := n.str() + 'z'
assert s.u32() == n
}
@ -92,7 +92,7 @@ fn test_unsigned_cast() {
assert '-0x00_0_f_ff'.u64() == 0
assert '10_000_000'.u64() == 10000000
for n in 0 .. 10000 {
for n in 0 .. u64(10000) {
s := n.str() + 'z'
assert s.u64() == n
}

View File

@ -15,13 +15,8 @@ import math
struct C.Display {
}
[typedef]
struct C.Atom {
}
[typedef]
struct C.Window {
}
type Window = u64
type Atom = u64
fn C.XInitThreads() int
@ -29,35 +24,35 @@ fn C.XCloseDisplay(d &C.Display)
fn C.XFlush(d &C.Display)
fn C.XDestroyWindow(d &C.Display, w C.Window)
fn C.XDestroyWindow(d &C.Display, w Window)
fn C.XNextEvent(d &C.Display, e &C.XEvent)
fn C.XSetSelectionOwner(d &C.Display, a C.Atom, w C.Window, time int)
fn C.XSetSelectionOwner(d &C.Display, a Atom, w Window, time int)
fn C.XGetSelectionOwner(d &C.Display, a C.Atom) C.Window
fn C.XGetSelectionOwner(d &C.Display, a Atom) Window
fn C.XChangeProperty(d &C.Display, requestor C.Window, property C.Atom, typ C.Atom, format int, mode int, data voidptr, nelements int) int
fn C.XChangeProperty(d &C.Display, requestor Window, property Atom, typ Atom, format int, mode int, data voidptr, nelements int) int
fn C.XSendEvent(d &C.Display, requestor C.Window, propogate int, mask i64, event &C.XEvent)
fn C.XSendEvent(d &C.Display, requestor Window, propogate int, mask i64, event &C.XEvent)
fn C.XInternAtom(d &C.Display, typ byteptr, only_if_exists int) C.Atom
fn C.XInternAtom(d &C.Display, typ byteptr, only_if_exists int) Atom
fn C.XCreateSimpleWindow(d &C.Display, root C.Window, x int, y int, width u32, height u32, border_width u32, border u64, background u64) C.Window
fn C.XCreateSimpleWindow(d &C.Display, root Window, x int, y int, width u32, height u32, border_width u32, border u64, background u64) Window
fn C.XOpenDisplay(name byteptr) &C.Display
fn C.XConvertSelection(d &C.Display, selection C.Atom, target C.Atom, property C.Atom, requestor C.Window, time int) int
fn C.XConvertSelection(d &C.Display, selection Atom, target Atom, property Atom, requestor Window, time int) int
fn C.XSync(d &C.Display, discard int) int
fn C.XGetWindowProperty(d &C.Display, w C.Window, property C.Atom, offset i64, length i64, delete int, req_type C.Atom, actual_type_return &C.Atom, actual_format_return &int, nitems &u64, bytes_after_return &u64, prop_return &byteptr) int
fn C.XGetWindowProperty(d &C.Display, w Window, property Atom, offset i64, length i64, delete int, req_type Atom, actual_type_return &Atom, actual_format_return &int, nitems &u64, bytes_after_return &u64, prop_return &byteptr) int
fn C.XDeleteProperty(d &C.Display, w C.Window, property C.Atom) int
fn C.XDeleteProperty(d &C.Display, w Window, property Atom) int
fn C.DefaultScreen(display &C.Display) int
fn C.RootWindow(display &C.Display, screen_number int) C.Window
fn C.RootWindow(display &C.Display, screen_number int) Window
fn C.BlackPixel(display &C.Display, screen_number int) u32
@ -71,11 +66,11 @@ fn todo_del() {}
struct C.XSelectionRequestEvent {
mut:
display &C.Display // Display the event was read from
owner C.Window
requestor C.Window
selection C.Atom
target C.Atom
property C.Atom
owner Window
requestor Window
selection Atom
target Atom
property Atom
time int
}
@ -84,24 +79,24 @@ struct C.XSelectionEvent {
mut:
@type int
display &C.Display // Display the event was read from
requestor C.Window
selection C.Atom
target C.Atom
property C.Atom
requestor Window
selection Atom
target Atom
property Atom
time int
}
[typedef]
struct C.XSelectionClearEvent {
mut:
window C.Window
selection C.Atom
window Window
selection Atom
}
[typedef]
struct C.XDestroyWindowEvent {
mut:
window C.Window
window Window
}
[typedef]
@ -141,9 +136,9 @@ enum AtomType {
pub struct Clipboard {
display &C.Display
mut:
selection C.Atom // the selection atom
window C.Window
atoms []C.Atom
selection Atom // the selection atom
window Window
atoms []Atom
mutex &sync.Mutex
text string // text data sent or received
got_text bool // used to confirm that we have got the text
@ -151,7 +146,7 @@ mut:
}
struct Property {
actual_type C.Atom
actual_type Atom
actual_format int
nitems u64
data byteptr
@ -204,14 +199,14 @@ pub fn (cb &Clipboard) check_availability() bool {
pub fn (mut cb Clipboard) free() {
C.XDestroyWindow(cb.display, cb.window)
cb.window = C.Window(C.None)
cb.window = Window(0)
// FIX ME: program hangs when closing display
// XCloseDisplay(cb.display)
}
pub fn (mut cb Clipboard) clear() {
cb.mutex.@lock()
C.XSetSelectionOwner(cb.display, cb.selection, C.Window(C.None), C.CurrentTime)
C.XSetSelectionOwner(cb.display, cb.selection, Window(0), C.CurrentTime)
C.XFlush(cb.display)
cb.is_owner = false
cb.text = ''
@ -229,7 +224,7 @@ fn (cb &Clipboard) take_ownership() {
// set_text stores `text` in the system clipboard.
pub fn (mut cb Clipboard) set_text(text string) bool {
if cb.window == C.Window(C.None) {
if cb.window == Window(0) {
return false
}
cb.mutex.@lock()
@ -244,7 +239,7 @@ pub fn (mut cb Clipboard) set_text(text string) bool {
}
pub fn (mut cb Clipboard) get_text() string {
if cb.window == C.Window(C.None) {
if cb.window == Window(0) {
return ''
}
if cb.is_owner {
@ -289,7 +284,7 @@ fn (mut cb Clipboard) transmit_selection(xse &C.XSelectionEvent) bool {
fn (mut cb Clipboard) start_listener() {
event := C.XEvent{}
mut sent_request := false
mut to_be_requested := C.Atom(0)
mut to_be_requested := Atom(0)
for {
C.XNextEvent(cb.display, &event)
if unsafe { event.@type == 0 } {
@ -330,7 +325,7 @@ fn (mut cb Clipboard) start_listener() {
property: xsre.property
}
if !cb.transmit_selection(&xse) {
xse.property = new_atom(C.None)
xse.property = new_atom(0)
}
C.XSendEvent(cb.display, xse.requestor, 0, C.PropertyChangeMask, voidptr(&xse))
C.XFlush(cb.display)
@ -339,19 +334,19 @@ fn (mut cb Clipboard) start_listener() {
C.SelectionNotify {
if unsafe {
event.xselection.selection == cb.selection
&& event.xselection.property != C.Atom(C.None)
&& event.xselection.property != Atom(0)
} {
if unsafe { event.xselection.target == cb.get_atom(.targets) && !sent_request } {
sent_request = true
prop := read_property(cb.display, cb.window, cb.selection)
to_be_requested = cb.pick_target(prop)
if to_be_requested != C.Atom(0) {
if to_be_requested != Atom(0) {
C.XConvertSelection(cb.display, cb.selection, to_be_requested,
cb.selection, cb.window, C.CurrentTime)
}
} else if unsafe { event.xselection.target == to_be_requested } {
sent_request = false
to_be_requested = C.Atom(0)
to_be_requested = Atom(0)
cb.mutex.@lock()
prop := unsafe {
read_property(event.xselection.display, event.xselection.requestor,
@ -382,19 +377,19 @@ fn (mut cb Clipboard) start_listener() {
*/
// intern_atoms initializes all the atoms we need.
fn (mut cb Clipboard) intern_atoms() {
cb.atoms << C.Atom(4) // XA_ATOM
cb.atoms << C.Atom(31) // XA_STRING
cb.atoms << Atom(4) // XA_ATOM
cb.atoms << Atom(31) // XA_STRING
for i, name in x11.atom_names {
only_if_exists := if i == int(AtomType.utf8_string) { 1 } else { 0 }
cb.atoms << C.XInternAtom(cb.display, name.str, only_if_exists)
if i == int(AtomType.utf8_string) && cb.atoms[i] == C.Atom(C.None) {
cb.atoms << C.XInternAtom(cb.display, &char(name.str), only_if_exists)
if i == int(AtomType.utf8_string) && cb.atoms[i] == Atom(0) {
cb.atoms[i] = cb.get_atom(.xa_string)
}
}
}
fn read_property(d &C.Display, w C.Window, p C.Atom) Property {
actual_type := C.Atom(0)
fn read_property(d &C.Display, w Window, p Atom) Property {
actual_type := Atom(0)
actual_format := 0
nitems := u64(0)
bytes_after := u64(0)
@ -404,7 +399,7 @@ fn read_property(d &C.Display, w C.Window, p C.Atom) Property {
if ret != 0 {
C.XFree(ret)
}
C.XGetWindowProperty(d, w, p, 0, read_bytes, 0, C.Atom(C.AnyPropertyType), &actual_type,
C.XGetWindowProperty(d, w, p, 0, read_bytes, 0, 0, &actual_type,
&actual_format, &nitems, &bytes_after, &ret)
read_bytes *= 2
if bytes_after == 0 {
@ -415,7 +410,7 @@ fn read_property(d &C.Display, w C.Window, p C.Atom) Property {
}
// pick_target finds the best target given a local copy of a property.
fn (cb &Clipboard) pick_target(prop Property) C.Atom {
fn (cb &Clipboard) pick_target(prop Property) Atom {
// The list of targets is a list of atoms, so it should have type XA_ATOM
// but it may have the type TARGETS instead.
if (prop.actual_type != cb.get_atom(.xa_atom) && prop.actual_type != cb.get_atom(.targets))
@ -426,9 +421,9 @@ fn (cb &Clipboard) pick_target(prop Property) C.Atom {
// next instead as the lowest common denominator
return cb.get_atom(.xa_string)
} else {
atom_list := &C.Atom(prop.data)
atom_list := &Atom(prop.data)
mut to_be_requested := C.Atom(0)
mut to_be_requested := Atom(0)
// This is higher than the maximum priority.
mut priority := math.max_i32
@ -450,23 +445,23 @@ fn (cb &Clipboard) pick_target(prop Property) C.Atom {
}
}
fn (cb &Clipboard) get_atoms(types ...AtomType) []C.Atom {
mut atoms := []C.Atom{}
fn (cb &Clipboard) get_atoms(types ...AtomType) []Atom {
mut atoms := []Atom{}
for typ in types {
atoms << cb.atoms[typ]
}
return atoms
}
fn (cb &Clipboard) get_atom(typ AtomType) C.Atom {
fn (cb &Clipboard) get_atom(typ AtomType) Atom {
return cb.atoms[typ]
}
fn (cb &Clipboard) is_supported_target(target C.Atom) bool {
fn (cb &Clipboard) is_supported_target(target Atom) bool {
return cb.get_target_index(target) >= 0
}
fn (cb &Clipboard) get_target_index(target C.Atom) int {
fn (cb &Clipboard) get_target_index(target Atom) int {
for i, atom in cb.get_supported_targets() {
if atom == target {
return i
@ -475,15 +470,15 @@ fn (cb &Clipboard) get_target_index(target C.Atom) int {
return -1
}
fn (cb &Clipboard) get_supported_targets() []C.Atom {
fn (cb &Clipboard) get_supported_targets() []Atom {
return cb.get_atoms(AtomType.utf8_string, .xa_string, .text, .text_plain, .text_html)
}
fn new_atom(value int) &C.Atom {
return unsafe { &C.Atom(value) }
fn new_atom(value int) &Atom {
return unsafe { &Atom(&u64(u64(value))) }
}
fn create_xwindow(display &C.Display) C.Window {
fn create_xwindow(display &C.Display) Window {
n := C.DefaultScreen(display)
return C.XCreateSimpleWindow(display, C.RootWindow(display, n), 0, 0, 1, 1, 0, C.BlackPixel(display,
n), C.WhitePixel(display, n))

View File

@ -150,7 +150,7 @@ fn propagate_cancel(parent Context, mut child Canceler) {
// parent has already been canceled
child.cancel(false, p.err)
} else {
p.children[child.id] = child
p.children[child.id] = *child
}
}

View File

@ -336,8 +336,8 @@ pub fn new_context(cfg Config) &Context {
event_userdata_cb: gg_event_fn
fail_userdata_cb: gg_fail_fn
cleanup_userdata_cb: gg_cleanup_fn
window_title: cfg.window_title.str
html5_canvas_name: cfg.window_title.str
window_title: &char(cfg.window_title.str)
html5_canvas_name: &char(cfg.window_title.str)
width: cfg.width
height: cfg.height
sample_count: cfg.sample_count

View File

@ -146,7 +146,7 @@ pub fn (mut img Image) init_sokol_image() &Image {
num_mipmaps: 0
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
label: &byte(0)
label: &char(0)
d3d11_texture: 0
}
img_desc.data.subimage[0][0] = C.sg_range{

View File

@ -189,7 +189,7 @@ pub fn (ctx &Context) draw_text(x int, y int, text_ string, cfg gx.TextCfg) {
// }
ctx.set_cfg(cfg)
scale := if ctx.ft.scale == 0 { f32(1) } else { ctx.ft.scale }
C.fonsDrawText(ctx.ft.fons, x * scale, y * scale, text_.str, 0) // TODO: check offsets/alignment
C.fonsDrawText(ctx.ft.fons, x * scale, y * scale, &char(text_.str), 0) // TODO: check offsets/alignment
}
pub fn (ctx &Context) draw_text_def(x int, y int, text string) {
@ -215,7 +215,7 @@ pub fn (ctx &Context) text_width(s string) int {
return 0
}
mut buf := [4]f32{}
C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, &buf[0])
C.fonsTextBounds(ctx.ft.fons, 0, 0, &char(s.str), 0, &buf[0])
if s.ends_with(' ') {
return int((buf[2] - buf[0]) / ctx.scale) +
ctx.text_width('i') // TODO fix this in fontstash?
@ -236,7 +236,7 @@ pub fn (ctx &Context) text_height(s string) int {
return 0
}
mut buf := [4]f32{}
C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, &buf[0])
C.fonsTextBounds(ctx.ft.fons, 0, 0, &char(s.str), 0, &buf[0])
return int((buf[3] - buf[1]) / ctx.scale)
}
@ -246,7 +246,7 @@ pub fn (ctx &Context) text_size(s string) (int, int) {
return 0, 0
}
mut buf := [4]f32{}
C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, &buf[0])
C.fonsTextBounds(ctx.ft.fons, 0, 0, &char(s.str), 0, &buf[0])
return int((buf[2] - buf[0]) / ctx.scale), int((buf[3] - buf[1]) / ctx.scale)
}

View File

@ -153,7 +153,7 @@ pub fn query_desc() C.sg_desc {
[inline]
pub fn query_backend() Backend {
return C.sg_query_backend()
return Backend(C.sg_query_backend())
}
[inline]
@ -226,27 +226,27 @@ pub fn query_pass_info(pass C.sg_pass) C.sg_pass_info {
// get resource creation desc struct with their default values replaced
[inline]
pub fn query_buffer_defaults(desc &C.sg_buffer) C.sg_buffer_desc {
return C.sg_query_buffer_defaults(desc)
return C.sg_query_buffer_defaults(unsafe { &C.sg_buffer_desc(desc) })
}
[inline]
pub fn query_image_defaults(desc &C.sg_image) C.sg_image_desc {
return C.sg_query_image_defaults(desc)
return C.sg_query_image_defaults(unsafe { &C.sg_image_desc(desc) })
}
[inline]
pub fn query_shader_defaults(desc &C.sg_shader) C.sg_shader_desc {
return C.sg_query_shader_defaults(desc)
return C.sg_query_shader_defaults(unsafe { &C.sg_shader_desc(desc) })
}
[inline]
pub fn query_pipeline_defaults(desc &C.sg_pipeline) C.sg_pipeline_desc {
return C.sg_query_pipeline_defaults(desc)
return C.sg_query_pipeline_defaults(unsafe { &C.sg_pipeline_desc(desc) })
}
[inline]
pub fn query_pass_defaults(desc &C.sg_pass) C.sg_pass_desc {
return C.sg_query_pass_defaults(desc)
return C.sg_query_pass_defaults(unsafe { &C.sg_pass_desc(desc) })
}
/* rendering contexts (optional) */

View File

@ -58,11 +58,11 @@ fn C.sg_query_pipeline_info(pip C.sg_pipeline) C.sg_pipeline_info
fn C.sg_query_pass_info(pass C.sg_pass) C.sg_pass_info
// get resource creation desc struct with their default values replaced
fn C.sg_query_buffer_defaults(desc &C.sg_buffer) C.sg_buffer_desc
fn C.sg_query_image_defaults(desc &C.sg_image) C.sg_image_desc
fn C.sg_query_shader_defaults(desc &C.sg_shader) C.sg_shader_desc
fn C.sg_query_pipeline_defaults(desc &C.sg_pipeline) C.sg_pipeline_desc
fn C.sg_query_pass_defaults(desc &C.sg_pass) C.sg_pass_desc
fn C.sg_query_buffer_defaults(desc &C.sg_buffer_desc) C.sg_buffer_desc
fn C.sg_query_image_defaults(desc &C.sg_image_desc) C.sg_image_desc
fn C.sg_query_shader_defaults(desc &C.sg_shader_desc) C.sg_shader_desc
fn C.sg_query_pipeline_defaults(desc &C.sg_pipeline_desc) C.sg_pipeline_desc
fn C.sg_query_pass_defaults(desc &C.sg_pass_desc) C.sg_pass_desc
/* rendering contexts (optional) */
fn C.sg_setup_context() C.sg_context

View File

@ -161,23 +161,23 @@ pub mut:
}
pub fn (mut desc C.sg_shader_desc) set_vert_src(src string) &C.sg_shader_desc {
desc.vs.source = src.str
desc.vs.source = &char(src.str)
return desc
}
pub fn (mut desc C.sg_shader_desc) set_frag_src(src string) &C.sg_shader_desc {
desc.fs.source = src.str
desc.fs.source = &char(src.str)
return desc
}
pub fn (mut desc C.sg_shader_desc) set_vert_image(index int, name string) &C.sg_shader_desc {
desc.vs.images[index].name = name.str
desc.vs.images[index].name = &char(name.str)
desc.vs.images[index].image_type = ._2d
return desc
}
pub fn (mut desc C.sg_shader_desc) set_frag_image(index int, name string) &C.sg_shader_desc {
desc.fs.images[index].name = name.str
desc.fs.images[index].name = &char(name.str)
desc.fs.images[index].image_type = ._2d
return desc
}
@ -193,13 +193,13 @@ pub fn (mut desc C.sg_shader_desc) set_frag_uniform_block_size(block_index int,
}
pub fn (mut desc C.sg_shader_desc) set_vert_uniform(block_index int, uniform_index int, name string, @type UniformType, array_count int) &C.sg_shader_desc {
desc.vs.uniform_blocks[block_index].uniforms[uniform_index].name = name.str
desc.vs.uniform_blocks[block_index].uniforms[uniform_index].name = &char(name.str)
desc.vs.uniform_blocks[block_index].uniforms[uniform_index].@type = @type
return desc
}
pub fn (mut desc C.sg_shader_desc) set_frag_uniform(block_index int, uniform_index int, name string, @type UniformType, array_count int) &C.sg_shader_desc {
desc.fs.uniform_blocks[block_index].uniforms[uniform_index].name = name.str
desc.fs.uniform_blocks[block_index].uniforms[uniform_index].name = &char(name.str)
desc.fs.uniform_blocks[block_index].uniforms[uniform_index].@type = @type
return desc
}
@ -225,7 +225,7 @@ pub mut:
}
pub fn (mut desc C.sg_shader_stage_desc) set_image(index int, name string) C.sg_shader_stage_desc {
desc.images[index].name = name.str
desc.images[index].name = &char(name.str)
desc.images[index].image_type = ._2d
return *desc
}

View File

@ -128,14 +128,14 @@ pub fn frame_count() u64 {
// write string into clipboard
[inline]
pub fn set_clipboard_string(str byteptr) {
pub fn set_clipboard_string(str &char) {
C.sapp_set_clipboard_string(str)
}
// read string from clipboard (usually during SAPP_EVENTTYPE_CLIPBOARD_PASTED)
[inline]
pub fn get_clipboard_string() byteptr {
return C.sapp_get_clipboard_string()
pub fn get_clipboard_string() &char {
return &char(C.sapp_get_clipboard_string())
}
// special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub)
@ -160,65 +160,65 @@ pub fn html5_ask_leave_site(ask bool) {
// Metal: get ARC-bridged pointer to Metal device object
[inline]
pub fn metal_get_device() voidptr {
return C.sapp_metal_get_device()
return voidptr(C.sapp_metal_get_device())
}
// Metal: get ARC-bridged pointer to this frame's renderpass descriptor
[inline]
pub fn metal_get_renderpass_descriptor() voidptr {
return C.sapp_metal_get_renderpass_descriptor()
return voidptr(C.sapp_metal_get_renderpass_descriptor())
}
// Metal: get ARC-bridged pointer to current drawable
[inline]
pub fn metal_get_drawable() voidptr {
return C.sapp_metal_get_drawable()
return voidptr(C.sapp_metal_get_drawable())
}
// macOS: get ARC-bridged pointer to macOS NSWindow
[inline]
pub fn macos_get_window() voidptr {
return C.sapp_macos_get_window()
return voidptr(C.sapp_macos_get_window())
}
// iOS: get ARC-bridged pointer to iOS UIWindow
[inline]
pub fn ios_get_window() voidptr {
return C.sapp_ios_get_window()
return voidptr(C.sapp_ios_get_window())
}
// D3D11: get pointer to ID3D11Device object
[inline]
pub fn d3d11_get_device() voidptr {
return C.sapp_d3d11_get_device()
return voidptr(C.sapp_d3d11_get_device())
}
// D3D11: get pointer to ID3D11DeviceContext object
[inline]
pub fn d3d11_get_device_context() voidptr {
return C.sapp_d3d11_get_device_context()
return voidptr(C.sapp_d3d11_get_device_context())
}
// D3D11: get pointer to ID3D11RenderTargetView object
[inline]
pub fn d3d11_get_render_target_view() voidptr {
return C.sapp_d3d11_get_render_target_view()
return voidptr(C.sapp_d3d11_get_render_target_view())
}
// D3D11: get pointer to ID3D11DepthStencilView
[inline]
pub fn d3d11_get_depth_stencil_view() voidptr {
return C.sapp_d3d11_get_depth_stencil_view()
return voidptr(C.sapp_d3d11_get_depth_stencil_view())
}
// Win32: get the HWND window handle
[inline]
pub fn win32_get_hwnd() voidptr {
return C.sapp_win32_get_hwnd()
return voidptr(C.sapp_win32_get_hwnd())
}
// Android: get native activity handle
[inline]
pub fn android_get_native_activity() voidptr {
return C.sapp_android_get_native_activity()
return voidptr(C.sapp_android_get_native_activity())
}

View File

@ -68,7 +68,7 @@ fn C.sqlite3_free(voidptr)
// connect Opens the connection with a database.
pub fn connect(path string) ?DB {
db := &C.sqlite3(0)
if C.sqlite3_open(path.str, &db) != 0 {
if C.sqlite3_open(&char(path.str), &db) != 0 {
return error('sqlite db error')
}
return DB{
@ -93,7 +93,7 @@ pub fn (mut db DB) close() ?bool {
// Only for V ORM
fn (db DB) init_stmt(query string) &C.sqlite3_stmt {
stmt := &C.sqlite3_stmt(0)
C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0)
C.sqlite3_prepare_v2(db.conn, &char(query.str), query.len, &stmt, 0)
return stmt
}
@ -111,7 +111,7 @@ fn get_int_from_stmt(stmt &C.sqlite3_stmt) int {
// Returns a single cell with value int.
pub fn (db DB) q_int(query string) int {
stmt := &C.sqlite3_stmt(0)
C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0)
C.sqlite3_prepare_v2(db.conn, &char(query.str), query.len, &stmt, 0)
C.sqlite3_step(stmt)
res := C.sqlite3_column_int(stmt, 0)
C.sqlite3_finalize(stmt)
@ -121,9 +121,9 @@ pub fn (db DB) q_int(query string) int {
// Returns a single cell with value string.
pub fn (db DB) q_string(query string) string {
stmt := &C.sqlite3_stmt(0)
C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0)
C.sqlite3_prepare_v2(db.conn, &char(query.str), query.len, &stmt, 0)
C.sqlite3_step(stmt)
res := unsafe { tos_clone(C.sqlite3_column_text(stmt, 0)) }
res := unsafe { tos_clone(&byte(C.sqlite3_column_text(stmt, 0))) }
C.sqlite3_finalize(stmt)
return res
}
@ -132,7 +132,7 @@ pub fn (db DB) q_string(query string) string {
// Result codes: https://www.sqlite.org/rescode.html
pub fn (db DB) exec(query string) ([]Row, int) {
stmt := &C.sqlite3_stmt(0)
C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0)
C.sqlite3_prepare_v2(db.conn, &char(query.str), query.len, &stmt, 0)
nr_cols := C.sqlite3_column_count(stmt)
mut res := 0
mut rows := []Row{}
@ -145,7 +145,7 @@ pub fn (db DB) exec(query string) ([]Row, int) {
}
mut row := Row{}
for i in 0 .. nr_cols {
val := unsafe { tos_clone(C.sqlite3_column_text(stmt, i)) }
val := unsafe { tos_clone(&byte(C.sqlite3_column_text(stmt, i))) }
row.vals << val
}
rows << row

View File

@ -41,7 +41,7 @@ pub fn load(path string) ?Image {
}
// flag := if ext == 'png' { C.STBI_rgb_alpha } else { 0 }
desired_channels := if ext == 'png' { 4 } else { 0 }
res.data = C.stbi_load(path.str, &res.width, &res.height, &res.nr_channels, desired_channels)
res.data = C.stbi_load(&char(path.str), &res.width, &res.height, &res.nr_channels, desired_channels)
if desired_channels == 4 && res.nr_channels == 3 {
// Fix an alpha png bug
res.nr_channels = 4

View File

@ -53,7 +53,7 @@ fn test_float_to_str() {
1e23,
f32_from_bits1(0x0080_0000), // smallest float32
math.max_f32,
383260575764816448,
383260575764816448.,
]
exp_result_f32 := [

View File

@ -32,45 +32,45 @@ $if linux {
#include <atomic.h>
// add_u64 adds provided delta as an atomic operation
pub fn add_u64(ptr &u64, delta int) bool {
res := C.atomic_fetch_add_u64(ptr, delta)
res := C.atomic_fetch_add_u64(voidptr(ptr), delta)
return res == 0
}
// sub_u64 subtracts provided delta as an atomic operation
pub fn sub_u64(ptr &u64, delta int) bool {
res := C.atomic_fetch_sub_u64(ptr, delta)
res := C.atomic_fetch_sub_u64(voidptr(ptr), delta)
return res == 0
}
// add_i64 adds provided delta as an atomic operation
pub fn add_i64(ptr &i64, delta int) bool {
res := C.atomic_fetch_add_u64(ptr, delta)
res := C.atomic_fetch_add_u64(voidptr(ptr), delta)
return res == 0
}
// add_i64 subtracts provided delta as an atomic operation
pub fn sub_i64(ptr &i64, delta int) bool {
res := C.atomic_fetch_sub_u64(ptr, delta)
res := C.atomic_fetch_sub_u64(voidptr(ptr), delta)
return res == 0
}
// atomic store/load operations have to be used when there might be another concurrent access
// atomicall set a value
pub fn store_u64(ptr &u64, val u64) {
C.atomic_store_u64(ptr, val)
C.atomic_store_u64(voidptr(ptr), val)
}
// atomicall get a value
pub fn load_u64(ptr &u64) u64 {
return C.atomic_load_u64(ptr)
return C.atomic_load_u64(voidptr(ptr))
}
// atomicall set a value
pub fn store_i64(ptr &i64, val i64) {
C.atomic_store_u64(ptr, val)
C.atomic_store_u64(voidptr(ptr), val)
}
// atomicall get a value
pub fn load_i64(ptr &i64) i64 {
return i64(C.atomic_load_u64(ptr))
return i64(C.atomic_load_u64(voidptr(ptr)))
}

View File

@ -198,7 +198,7 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
if C.atomic_load_u16(&ch.closed) != 0 {
return .closed
}
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { sync.spinloops, sync.spinloops_sem }
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { spinloops, spinloops_sem }
mut have_swapped := false
for {
mut got_sem := false
@ -344,8 +344,8 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
status_adr += wr_idx * sizeof(u16)
}
mut expected_status := u16(BufferElemStat.unused)
for !C.atomic_compare_exchange_weak_u16(unsafe { &u16(status_adr) },
&expected_status, u16(BufferElemStat.writing)) {
for !C.atomic_compare_exchange_weak_u16(status_adr, &expected_status,
u16(BufferElemStat.writing)) {
expected_status = u16(BufferElemStat.unused)
}
unsafe {
@ -387,7 +387,7 @@ pub fn (mut ch Channel) try_pop(dest voidptr) ChanState {
}
fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { sync.spinloops, sync.spinloops_sem }
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { spinloops, spinloops_sem }
mut have_swapped := false
mut write_in_progress := false
for {
@ -466,8 +466,8 @@ fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
status_adr += rd_idx * sizeof(u16)
}
mut expected_status := u16(BufferElemStat.written)
for !C.atomic_compare_exchange_weak_u16(unsafe { &u16(status_adr) },
&expected_status, u16(BufferElemStat.reading)) {
for !C.atomic_compare_exchange_weak_u16(status_adr, &expected_status,
u16(BufferElemStat.reading)) {
expected_status = u16(BufferElemStat.written)
}
unsafe {
@ -580,8 +580,8 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo
}
subscr[i].prev = &ch.write_subscriber
unsafe {
subscr[i].nxt = &Subscription(C.atomic_exchange_ptr(&voidptr(&ch.write_subscriber),
&subscr[i]))
subscr[i].nxt = C.atomic_exchange_ptr(&voidptr(&ch.write_subscriber),
&subscr[i])
}
if voidptr(subscr[i].nxt) != voidptr(0) {
subscr[i].nxt.prev = &subscr[i].nxt
@ -594,8 +594,8 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo
}
subscr[i].prev = &ch.read_subscriber
unsafe {
subscr[i].nxt = &Subscription(C.atomic_exchange_ptr(&voidptr(&ch.read_subscriber),
&subscr[i]))
subscr[i].nxt = C.atomic_exchange_ptr(&voidptr(&ch.read_subscriber),
&subscr[i])
}
if voidptr(subscr[i].nxt) != voidptr(0) {
subscr[i].nxt.prev = &subscr[i].nxt

View File

@ -189,17 +189,41 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) {
mut debug_options := ['-g']
mut optimization_options := ['-O2']
// arguments for the C compiler
// TODO : activate -Werror once no warnings remain
// '-Werror',
// TODO : try and remove the below workaround options when the corresponding
// warnings are totally fixed/removed
ccoptions.args = [v.pref.cflags, '-std=gnu99']
ccoptions.wargs = ['-Wall', '-Wextra', '-Wno-unused', '-Wno-missing-braces', '-Walloc-zero',
'-Wcast-qual', '-Wdate-time', '-Wduplicated-branches', '-Wduplicated-cond', '-Wformat=2',
'-Winit-self', '-Winvalid-pch', '-Wjump-misses-init', '-Wlogical-op', '-Wmultichar',
'-Wnested-externs', '-Wnull-dereference', '-Wpacked', '-Wpointer-arith', '-Wshadow',
'-Wswitch-default', '-Wswitch-enum', '-Wno-unused-parameter', '-Wno-unknown-warning-option',
'-Wno-format-nonliteral',
ccoptions.wargs = [
'-Wall',
'-Wextra',
'-Werror',
// if anything, these should be a `v vet` warning instead:
'-Wno-unused-parameter',
'-Wno-unused',
'-Wno-type-limits',
'-Wno-tautological-compare',
'-Wno-tautological-bitwise-compare',
// these cause various issues:
'-Wno-enum-conversion' /* used in vlib/sokol, where C enums in C structs are typed as V structs instead */,
'-Wno-sometimes-uninitialized' /* produced after exhaustive matches */,
'-Wno-shadow' /* the V compiler already catches this for user code, and enabling this causes issues with e.g. the `it` variable */,
'-Wno-int-to-void-pointer-cast',
'-Wno-int-to-pointer-cast' /* gcc version of the above */,
'-Wno-trigraphs' /* see stackoverflow.com/a/8435413 */,
'-Wno-missing-braces' /* see stackoverflow.com/q/13746033 */,
'-Wno-unknown-warning' /* if a C compiler does not understand a certain flag, it should just ignore it */,
'-Wno-unknown-warning-option' /* clang equivalent of the above */,
// enable additional warnings:
'-Wdate-time',
'-Wduplicated-branches',
'-Wduplicated-cond',
'-Winit-self',
'-Winvalid-pch',
'-Wjump-misses-init',
'-Wlogical-op',
'-Wmultichar',
'-Wnested-externs',
'-Wnull-dereference',
'-Wpacked',
'-Wpointer-arith',
'-Wswitch-enum',
]
if v.pref.os == .ios {
ccoptions.args << '-fobjc-arc'

View File

@ -736,6 +736,14 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) ast.Type {
right_type := c.expr(infix_expr.right)
// right_type = c.unwrap_genric(c.expr(infix_expr.right))
infix_expr.right_type = right_type
if left_type.is_number() && !left_type.is_ptr()
&& right_type in [ast.int_literal_type, ast.float_literal_type] {
infix_expr.right_type = left_type
}
if right_type.is_number() && !right_type.is_ptr()
&& left_type in [ast.int_literal_type, ast.float_literal_type] {
infix_expr.left_type = right_type
}
mut right := c.table.get_type_symbol(right_type)
right_final := c.table.get_final_type_symbol(right_type)
mut left := c.table.get_type_symbol(left_type)
@ -2560,14 +2568,17 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) ast.Typ
field_name := selector_expr.field_name
utyp := c.unwrap_generic(typ)
sym := c.table.get_type_symbol(utyp)
if typ.has_flag(.variadic) || sym.kind == .array_fixed || sym.kind == .chan {
if field_name == 'len' || (sym.kind == .chan && field_name == 'cap') {
selector_expr.typ = ast.int_type
return ast.int_type
}
if sym.kind == .chan && field_name == 'closed' {
if (typ.has_flag(.variadic) || sym.kind == .array_fixed) && field_name == 'len' {
selector_expr.typ = ast.int_type
return ast.int_type
}
if sym.kind == .chan {
if field_name == 'closed' {
selector_expr.typ = ast.bool_type
return ast.bool_type
} else if field_name in ['len', 'cap'] {
selector_expr.typ = ast.u32_type
return ast.u32_type
}
}
mut unknown_field_msg := 'type `$sym.name` has no field or method `$field_name`'
@ -3691,6 +3702,12 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
} else if typ_idx == ast.string_type_idx || high_type_idx == ast.string_type_idx {
c.error('range type can not be string', node.cond.position())
}
if high_type in [ast.int_type, ast.int_literal_type] {
node.val_type = typ
} else {
node.val_type = high_type
}
node.scope.update_var_type(node.val_var, node.val_type)
} else {
sym := c.table.get_type_symbol(typ)
if sym.kind == .struct_ {

View File

@ -17,7 +17,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
if g.is_shared {
mut shared_typ := node.typ.set_flag(.shared_f)
shared_styp = g.typ(shared_typ)
g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.val = ')
g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.mtx = {0}, .val =')
} else if is_amp {
g.write('HEAP($styp, ')
}
@ -189,7 +189,7 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
}
}
g.writeln(';')
g.writeln('\tarray_push(&$tmp, &ti);')
g.writeln('\tarray_push((array*)&$tmp, &ti);')
g.writeln('}')
if !is_embed_map_filter {
g.stmt_path_pos << g.out.len
@ -259,7 +259,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
g.definitions.writeln('\tif (${styp}__lt(*b, *a)) { return -1; } else { return 1; }}')
} else {
g.definitions.writeln('if (*a < *b) return -1;')
g.definitions.writeln('if (*a > *b) return 1; return 0; }\n')
g.definitions.writeln('if (*a > *b) return 1; else return 0; }\n')
}
} else {
infix_expr := node.args[0].expr as ast.InfixExpr
@ -302,7 +302,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
}
}
g.definitions.writeln('if ($op1) return -1;')
g.definitions.writeln('if ($op2) return 1; return 0; }\n')
g.definitions.writeln('if ($op2) return 1; else return 0; }\n')
}
}
}
@ -382,7 +382,7 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
}
}
g.writeln(') {')
g.writeln('\t\tarray_push(&$tmp, &it); \n\t\t}')
g.writeln('\t\tarray_push((array*)&$tmp, &it); \n\t\t}')
g.writeln('}')
if !is_embed_map_filter {
g.stmt_path_pos << g.out.len

View File

@ -666,7 +666,7 @@ fn (mut g Gen) register_chan_pop_optional_call(opt_el_type string, styp string)
static inline $opt_el_type __Option_${styp}_popval($styp ch) {
$opt_el_type _tmp = {0};
if (sync__Channel_try_pop_priv(ch, _tmp.data, false)) {
return ($opt_el_type){ .state = 2, .err = v_error(_SLIT("channel closed")) };
return ($opt_el_type){ .state = 2, .err = v_error(_SLIT("channel closed")), .data = {0} };
}
return _tmp;
}')
@ -680,7 +680,7 @@ fn (mut g Gen) register_chan_push_optional_call(el_type string, styp string) {
g.channel_definitions.writeln('
static inline Option_void __Option_${styp}_pushval($styp ch, $el_type e) {
if (sync__Channel_try_push_priv(ch, &e, false)) {
return (Option_void){ .state = 2, .err = v_error(_SLIT("channel closed")) };
return (Option_void){ .state = 2, .err = v_error(_SLIT("channel closed")), .data = {0} };
}
return (Option_void){0};
}')
@ -1298,7 +1298,7 @@ fn (mut g Gen) write_defer_stmts() {
for i := g.defer_stmts.len - 1; i >= 0; i-- {
defer_stmt := g.defer_stmts[i]
g.writeln('// Defer begin')
g.writeln('if (${g.defer_flag_var(defer_stmt)} == true) {')
g.writeln('if (${g.defer_flag_var(defer_stmt)}) {')
g.indent++
if defer_stmt.ifdef.len > 0 {
g.writeln(defer_stmt.ifdef)
@ -1424,7 +1424,8 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) {
if node.is_range {
// `for x in 1..10 {`
i := if node.val_var == '_' { g.new_tmp_var() } else { c_name(node.val_var) }
g.write('for (int $i = ')
val_typ := g.table.mktyp(node.val_type)
g.write('for (${g.typ(val_typ)} $i = ')
g.expr(node.cond)
g.write('; $i < ')
g.expr(node.high)
@ -1770,11 +1771,11 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
g.error('cannot convert reference to `shared`', expr.position())
}
if exp_sym.kind == .array {
g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.val = ')
g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.mtx = {0}, .val =')
} else if exp_sym.kind == .map {
g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.val = ')
g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.mtx = {0}, .val =')
} else {
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.val = ')
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.mtx = {0}, .val =')
}
g.expr(expr)
g.writeln('}, sizeof($shared_styp))')
@ -1794,6 +1795,16 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
g.gen_optional_error(expected_type, expr)
return
}
if expr is ast.IntegerLiteral {
if expected_type in [ast.u64_type, ast.u32_type, ast.u16_type] && expr.val[0] != `-` {
g.expr(expr)
g.write('U')
return
}
}
if exp_sym.kind == .function {
g.write('(voidptr)')
}
// no cast
g.expr(expr)
}
@ -2910,11 +2921,11 @@ fn (mut g Gen) expr(node ast.Expr) {
shared_typ := ret_type.set_flag(.shared_f)
shared_styp = g.typ(shared_typ)
if ret_sym.kind == .array {
g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.val = ')
g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.mtx = {0}, .val =')
} else if ret_sym.kind == .map {
g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.val = ')
g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.mtx = {0}, .val =')
} else {
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.val = ')
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.mtx = {0}, .val =')
}
}
g.call_expr(node)
@ -3657,7 +3668,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
// push a single element
elem_type_str := g.typ(info.elem_type)
elem_sym := g.table.get_type_symbol(info.elem_type)
g.write('array_push(')
g.write('array_push((array*)')
if !left_type.is_ptr() {
g.write('&')
}
@ -3789,10 +3800,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
}
g.expr(node.left)
g.write(' $node.op.str() ')
if node.right_type.is_ptr() && node.right.is_auto_deref_var() {
g.write('*')
}
g.expr(node.right)
g.expr_with_cast(node.right, node.right_type, node.left_type)
if need_par {
g.write(')')
}
@ -4142,7 +4150,7 @@ fn (mut g Gen) map_init(node ast.MapInit) {
if g.is_shared {
mut shared_typ := node.typ.set_flag(.shared_f)
shared_styp = g.typ(shared_typ)
g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.val = ')
g.writeln('($shared_styp*)__dup_shared_map(&($shared_styp){.mtx = {0}, .val =')
} else if is_amp {
styp = g.typ(node.typ)
g.write('($styp*)memdup(ADDR($styp, ')
@ -4658,7 +4666,7 @@ fn (mut g Gen) gen_optional_error(target_type ast.Type, expr ast.Expr) {
styp := g.typ(target_type)
g.write('($styp){ .state=2, .err=')
g.expr(expr)
g.write(' }')
g.write(', .data={0} }')
}
fn (mut g Gen) return_stmt(node ast.Return) {
@ -5053,7 +5061,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
if g.is_shared && !g.inside_opt_data && !g.is_arraymap_set {
mut shared_typ := struct_init.typ.set_flag(.shared_f)
shared_styp = g.typ(shared_typ)
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.val = ($styp){')
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.mtx = {0}, .val =($styp){')
} else if is_amp {
g.write('($styp*)memdup(&($styp){')
} else if struct_init.typ.is_ptr() {
@ -5808,7 +5816,7 @@ fn (mut g Gen) type_default(typ_ ast.Type) string {
init_str := '__new_array${noscan}(0, 1, sizeof($elem_type_str))'
if typ.has_flag(.shared_f) {
atyp := '__shared__Array_${g.table.get_type_symbol(elem_typ).cname}'
return '($atyp*)__dup_shared_array(&($atyp){.val = $init_str}, sizeof($atyp))'
return '($atyp*)__dup_shared_array(&($atyp){.mtx = {0}, .val =$init_str}, sizeof($atyp))'
} else {
return init_str
}
@ -5820,7 +5828,7 @@ fn (mut g Gen) type_default(typ_ ast.Type) string {
init_str := 'new_map(sizeof(${g.typ(info.key_type)}), sizeof(${g.typ(info.value_type)}), $hash_fn, $key_eq_fn, $clone_fn, $free_fn)'
if typ.has_flag(.shared_f) {
mtyp := '__shared__Map_${key_typ.cname}_${g.table.get_type_symbol(info.value_type).cname}'
return '($mtyp*)__dup_shared_map(&($mtyp){.val = $init_str}, sizeof($mtyp))'
return '($mtyp*)__dup_shared_map(&($mtyp){.mtx = {0}, .val =$init_str}, sizeof($mtyp))'
} else {
return init_str
}
@ -5852,7 +5860,7 @@ fn (mut g Gen) type_default(typ_ ast.Type) string {
}
if typ.has_flag(.shared_f) {
styp := '__shared__${g.table.get_type_symbol(typ).cname}'
return '($styp*)__dup${styp}(&($styp){.val = $init_str}, sizeof($styp))'
return '($styp*)__dup${styp}(&($styp){.mtx = {0}, .val =$init_str}, sizeof($styp))'
} else {
return init_str
}

View File

@ -657,7 +657,7 @@ static voidptr memfreedup(voidptr ptr, voidptr src, int sz) {
#undef EMPTY_STRUCT_DECLARATION
#undef OPTION_CAST
#define EMPTY_STRUCT_DECLARATION int ____dummy_variable
#define EMPTY_STRUCT_DECLARATION char __pad
#define OPTION_CAST(x)
#undef __NOINLINE
#undef __IRQHANDLER

View File

@ -305,9 +305,9 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
g.write('map_set(')
} else {
if node.is_setter {
g.write('(*(($elem_type_str*)map_get_and_set(')
g.write('(*(($elem_type_str*)map_get_and_set((map*)')
} else {
g.write('(*(($elem_type_str*)map_get(')
g.write('(*(($elem_type_str*)map_get((map*)')
}
}
if !left_is_ptr || node.left_type.has_flag(.shared_f) {
@ -344,9 +344,9 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
|| (g.is_assign_lhs && !g.is_arraymap_set && get_and_set_types) {
zero := g.type_default(info.value_type)
if node.is_setter {
g.write('(*($elem_type_str*)map_get_and_set(')
g.write('(*($elem_type_str*)map_get_and_set((map*)')
} else {
g.write('(*($elem_type_str*)map_get(')
g.write('(*($elem_type_str*)map_get((map*)')
}
if !left_is_ptr {
g.write('&')

View File

@ -50,7 +50,7 @@ $dec_fn_dec {
if (error_ptr != NULL) {
// fprintf(stderr, "Error in decode() for $styp error_ptr=: %s\\n", error_ptr);
// printf("\\nbad js=%%s\\n", js.str);
return (Option_$styp){.state = 2,.err = v_error(tos2((byteptr)error_ptr))};
return (Option_$styp){.state = 2,.err = v_error(tos2((byteptr)error_ptr)),.data = {0}};
}
}
')
@ -153,7 +153,7 @@ fn (mut g Gen) gen_struct_enc_dec(type_info ast.TypeInfo, styp string, mut enc s
tmp := g.new_tmp_var()
dec.writeln('\tOption_$field_type $tmp = $dec_name (js_get(root,"$name"));')
dec.writeln('\tif(${tmp}.state != 0) {')
dec.writeln('\t\treturn *(Option_$styp*) &$tmp;')
dec.writeln('\t\treturn (Option_$styp){ .state = ${tmp}.state, .err = ${tmp}.err, .data = {0} };')
dec.writeln('\t}')
dec.writeln('\tres.${c_name(field.name)} = *($field_type*) ${tmp}.data;')
}
@ -162,7 +162,7 @@ fn (mut g Gen) gen_struct_enc_dec(type_info ast.TypeInfo, styp string, mut enc s
tmp := g.new_tmp_var()
dec.writeln('\tOption_$field_type $tmp = $dec_name (js_get(root,"$name"));')
dec.writeln('\tif(${tmp}.state != 0) {')
dec.writeln('\t\treturn *(Option_$styp*) &$tmp;')
dec.writeln('\t\treturn (Option_$styp){ .state = ${tmp}.state, .err = ${tmp}.err, .data = {0} };')
dec.writeln('\t}')
dec.writeln('\tres.${c_name(field.name)} = *($field_type*) ${tmp}.data;')
}
@ -225,14 +225,14 @@ fn (mut g Gen) decode_array(value_type ast.Type) string {
noscan := g.check_noscan(value_type)
return '
if(root && !cJSON_IsArray(root) && !cJSON_IsNull(root)) {
return (Option_Array_$styp){.state = 2, .err = v_error(string_add(_SLIT("Json element is not an array: "), tos2((byteptr)cJSON_PrintUnformatted(root))))};
return (Option_Array_$styp){.state = 2, .err = v_error(string_add(_SLIT("Json element is not an array: "), tos2((byteptr)cJSON_PrintUnformatted(root)))), .data = {0}};
}
res = __new_array${noscan}(0, 0, sizeof($styp));
const cJSON *jsval = NULL;
cJSON_ArrayForEach(jsval, root)
{
$s
array_push(&res, &val);
array_push((array*)&res, &val);
}
'
}
@ -269,7 +269,7 @@ fn (mut g Gen) decode_map(key_type ast.Type, value_type ast.Type) string {
}
return '
if(!cJSON_IsObject(root) && !cJSON_IsNull(root)) {
return (Option_Map_${styp}_$styp_v){ .state = 2, .err = v_error( string_add(_SLIT("Json element is not an object: "), tos2((byteptr)cJSON_PrintUnformatted(root))) )};
return (Option_Map_${styp}_$styp_v){ .state = 2, .err = v_error( string_add(_SLIT("Json element is not an object: "), tos2((byteptr)cJSON_PrintUnformatted(root)))), .data = {0}};
}
res = new_map(sizeof($styp), sizeof($styp_v), $hash_fn, $key_eq_fn, $clone_fn, $free_fn);
cJSON *jsval = NULL;

View File

@ -140,7 +140,7 @@ fn (mut g Gen) sqlite3_stmt(node ast.SqlStmt, typ SqlType) {
}
x := '${node.object_var_name}.$field.name'
if field.typ == ast.string_type {
g.writeln('sqlite3_bind_text($g.sql_stmt_name, ${i + 0}, ${x}.str, ${x}.len, 0);')
g.writeln('sqlite3_bind_text($g.sql_stmt_name, ${i + 0}, (char*)${x}.str, ${x}.len, 0);')
} else if g.table.type_symbols[int(field.typ)].kind == .struct_ {
// insert again
expr := node.sub_structs[int(field.typ)]
@ -267,7 +267,7 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_
if field.typ == ast.string_type {
func = 'sqlite3_column_text'
string_data := g.new_tmp_var()
g.writeln('byteptr $string_data = ${func}($g.sql_stmt_name, $i);')
g.writeln('byte* $string_data = (byte*)${func}($g.sql_stmt_name, $i);')
g.writeln('if ($string_data != NULL) {')
g.writeln('\t${tmp}.$field.name = tos_clone($string_data);')
g.writeln('}')
@ -299,7 +299,7 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_
}
}
if node.is_array {
g.writeln('\t array_push(&${tmp}_array, _MOV(($elem_type_str[]){ $tmp }));')
g.writeln('\t array_push((array*)&${tmp}_array, _MOV(($elem_type_str[]){ $tmp }));')
}
g.writeln('}')
g.writeln('sqlite3_finalize($g.sql_stmt_name);')
@ -347,7 +347,7 @@ fn (mut g Gen) sqlite3_bind_int(val string) {
}
fn (mut g Gen) sqlite3_bind_string(val string, len string) {
g.sql_buf.writeln('sqlite3_bind_text($g.sql_stmt_name, $g.sql_i, $val, $len, 0);')
g.sql_buf.writeln('sqlite3_bind_text($g.sql_stmt_name, $g.sql_i, (char*)$val, $len, 0);')
}
fn (mut g Gen) sqlite3_type_from_v(v_typ ast.Type) string {
@ -464,9 +464,9 @@ fn (mut g Gen) mysql_select_expr(node ast.SqlExpr, sub bool, line string, typ Sq
vals := g.new_tmp_var()
g.writeln('Array_string $vals = __new_array_with_default(0, 0, sizeof(string), 0);')
for i, ident in g.sql_idents {
g.writeln('array_push(&$vals, _MOV((string[]){string_clone(_SLIT("%${i + 1}"))}));')
g.writeln('array_push((array*)&$vals, _MOV((string[]){string_clone(_SLIT("%${i + 1}"))}));')
g.write('array_push(&$vals, _MOV((string[]){string_clone(')
g.write('array_push((array*)&$vals, _MOV((string[]){string_clone(')
if g.sql_idents_types[i] == ast.string_type {
g.write('_SLIT(')
} else {
@ -590,7 +590,7 @@ fn (mut g Gen) mysql_select_expr(node ast.SqlExpr, sub bool, line string, typ Sq
}
}
if node.is_array {
g.writeln('\t array_push(&${tmp}_array, _MOV(($elem_type_str[]) { $tmp }));')
g.writeln('\t array_push((array*)&${tmp}_array, _MOV(($elem_type_str[]) { $tmp }));')
g.writeln('}')
}
g.writeln('string_free(&$stmt_name);')

View File

@ -275,7 +275,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
g.write('($s)')
}
}
g.expr(expr)
g.expr_with_cast(expr, typ, typ)
if is_shared {
g.write('->val')
}
@ -287,7 +287,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
str_fn_name := g.gen_str_for_type(typ)
g.write('${str_fn_name}(')
if sym.kind != .function {
g.expr(expr)
g.expr_with_cast(expr, typ, typ)
}
g.write(')')
}

View File

@ -178,7 +178,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
field_start_pos := p.tok.position()
is_embed := ((p.tok.lit.len > 1 && p.tok.lit[0].is_capital())
|| p.peek_tok.kind == .dot) && language == .v && p.peek_tok.kind != .key_fn
is_on_top := ast_fields.len == 0 && !(is_field_mut || is_field_mut || is_field_global)
is_on_top := ast_fields.len == 0 && !(is_field_mut || is_field_global)
mut field_name := ''
mut typ := ast.Type(0)
mut type_pos := token.Position{}

View File

@ -236,10 +236,10 @@ fn test_array_init_inferred_from_optional() {
b := read() or {
match x {
1 {
[]
['1']
}
else {
[]
['2']
}
}
}

View File

@ -1,5 +1,5 @@
fn test_cstring() {
w := c'world'
w := &char(c'world')
hlen := unsafe { C.strlen(c'hello') }
hlen2 := unsafe { C.strlen('hello') }
wlen := unsafe { C.strlen(w) }
@ -9,7 +9,7 @@ fn test_cstring() {
}
fn test_cstring_with_zeros() {
rawbytes := c'\x00username\x00password'
rawbytes := &char(c'\x00username\x00password')
s := unsafe { rawbytes.vstring_with_len(18) }
h := s.bytes().hex()
assert h == '00757365726e616d650070617373776f7264'

View File

@ -29,7 +29,7 @@ static void __sleep_ms(int ms) {
#define __SLEEP_MS(n) __sleep_ms(n)
#endif
volatile static int** keep;
static volatile int** keep;
static int calc_expr_after_delay(int* a, int b, int* c) {
keep = malloc(1000000);

View File

@ -58,12 +58,12 @@ fn test_operator_overloading_with_string_interpolation() {
assert a.x % b.x == g.x
assert a.y % b.y == g.y
////// /////
assert b > a == true
assert a < b == true
assert b >= a == true
assert a <= b == true
assert (Vec{2, 3} == Vec{3, 2}) == true
assert (Vec{2, 3} != Vec{3, 2}) == false
assert b > a
assert a < b
assert b >= a
assert a <= b
assert Vec{2, 3} == Vec{3, 2}
assert !(Vec{2, 3} != Vec{3, 2})
////// /////
assert c.str() == '{6, 8}'
assert d.str() == '{-2, -2}'

View File

@ -127,7 +127,7 @@ pub fn (mut tf_skl TTF_render_Sokol) create_texture() {
// usage: .dynamic
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
label: &byte(0)
label: &char(0)
d3d11_texture: 0
}
// comment for dynamic

View File

@ -263,14 +263,14 @@ pub fn (mut ws Client) parse_frame_header() ?Frame {
frame.header_len += 8
// these shift operators needs 64 bit on clang with -prod flag
mut payload_len := u64(0)
payload_len |= buffer[2] << 56
payload_len |= buffer[3] << 48
payload_len |= buffer[4] << 40
payload_len |= buffer[5] << 32
payload_len |= buffer[6] << 24
payload_len |= buffer[7] << 16
payload_len |= buffer[8] << 8
payload_len |= buffer[9]
payload_len |= u64(buffer[2]) << 56
payload_len |= u64(buffer[3]) << 48
payload_len |= u64(buffer[4]) << 40
payload_len |= u64(buffer[5]) << 32
payload_len |= u64(buffer[6]) << 24
payload_len |= u64(buffer[7]) << 16
payload_len |= u64(buffer[8]) << 8
payload_len |= u64(buffer[9])
frame.payload_len = int(payload_len)
if !frame.has_mask {
break

View File

@ -250,7 +250,7 @@ pub fn (mut ws Client) write_ptr(bytes &byte, payload_len int, code OPCode) ?int
len16 := C.htons(payload_len)
header[1] = 126
unsafe { C.memcpy(&header[2], &len16, 2) }
} else if payload_len > 0xffff && payload_len <= 0xffffffffffffffff {
} else if payload_len > 0xffff && payload_len <= 0x7fffffff {
len_bytes := htonl64(u64(payload_len))
header[1] = 127
unsafe { C.memcpy(&header[2], len_bytes.data, 8) }
@ -270,7 +270,7 @@ pub fn (mut ws Client) write_ptr(bytes &byte, payload_len int, code OPCode) ?int
header[5] = masking_key[1]
header[6] = masking_key[2]
header[7] = masking_key[3]
} else if payload_len > 0xffff && payload_len <= 0xffffffffffffffff {
} else if payload_len > 0xffff && payload_len <= 0x7fffffff {
len64 := htonl64(u64(payload_len))
header[1] = (127 | 0x80)
unsafe { C.memcpy(&header[2], len64.data, 8) }