all: fix most C warnings (#6758)

pull/6768/head
spaceface777 2020-11-06 15:26:59 +01:00 committed by GitHub
parent 98e8894d90
commit a9e9554b11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 89 additions and 90 deletions

View File

@ -88,7 +88,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
return false return false
} }
buffer := [100]byteptr{} buffer := [100]byteptr{}
nr_ptrs := C.backtrace(buffer, 100) nr_ptrs := C.backtrace(voidptr(buffer), 100)
if nr_ptrs < 2 { if nr_ptrs < 2 {
eprintln('C.backtrace returned less than 2 frames') eprintln('C.backtrace returned less than 2 frames')
return false return false
@ -96,7 +96,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
nr_actual_frames := nr_ptrs - skipframes nr_actual_frames := nr_ptrs - skipframes
mut sframes := []string{} mut sframes := []string{}
//////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames) //////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames)
csymbols := C.backtrace_symbols(&buffer[skipframes], nr_actual_frames) csymbols := C.backtrace_symbols(voidptr(&buffer[skipframes]), nr_actual_frames)
for i in 0 .. nr_actual_frames { for i in 0 .. nr_actual_frames {
sframes << unsafe {tos2( byteptr(csymbols[i]) )} sframes << unsafe {tos2( byteptr(csymbols[i]) )}
} }

View File

@ -153,7 +153,7 @@ fn (d DenseArray) get(i int) voidptr {
fn (mut d DenseArray) zeros_to_end() { fn (mut d DenseArray) zeros_to_end() {
mut tmp_value := malloc(d.value_bytes) mut tmp_value := malloc(d.value_bytes)
mut count := u32(0) mut count := u32(0)
for i in 0 .. d.len { for i in 0 .. int(d.len) {
if unsafe {d.keys[i]}.str != 0 { if unsafe {d.keys[i]}.str != 0 {
// swap keys // swap keys
unsafe { unsafe {

View File

@ -19,7 +19,7 @@ struct OptionBase {
ecode int ecode int
// Data is trailing after ecode // Data is trailing after ecode
// and is not included in here but in the // and is not included in here but in the
// derived Option_xxx types // derived Option_xxx types
} }
@ -51,13 +51,11 @@ struct Option {
is_none bool is_none bool
error string error string
ecode int ecode int
data [400]byte
} }
pub fn (o Option) str() string { pub fn (o Option) str() string {
if o.ok && !o.is_none { if o.ok && !o.is_none {
return 'Option{ data: ' + o.data[0..32].hex() + ' }' return 'Option{ ok }'
} }
if o.is_none { if o.is_none {
return 'Option{ none }' return 'Option{ none }'
@ -65,20 +63,6 @@ pub fn (o Option) str() string {
return 'Option{ error: "${o.error}" }' return 'Option{ error: "${o.error}" }'
} }
// `fn foo() ?Foo { return foo }` => `fn foo() ?Foo { return opt_ok(foo); }`
fn opt_ok(data voidptr, size int) Option {
if size >= 400 {
panic('option size too big: $size (max is 400), this is a temporary limit')
}
res := Option{
ok: true
}
unsafe {
C.memcpy(res.data, data, size)
}
return res
}
// used internally when returning `none` // used internally when returning `none`
fn opt_none() Option { fn opt_none() Option {
return Option{ return Option{

View File

@ -142,7 +142,7 @@ pub fn (mut f File) get_line() ?string {
mut zblen := size_t(0) mut zblen := size_t(0)
mut zx := 0 mut zx := 0
unsafe { unsafe {
zx = C.getline(&zbuf, &zblen, f.cfile) zx = C.getline(&charptr(&zbuf), &zblen, f.cfile)
if zx == -1 { if zx == -1 {
C.free(zbuf) C.free(zbuf)
if C.errno == 0 { if C.errno == 0 {
@ -160,7 +160,7 @@ pub fn (mut f File) get_line() ?string {
// //
buf := [4096]byte{} buf := [4096]byte{}
mut res := strings.new_builder(1024) mut res := strings.new_builder(1024)
mut x := 0 mut x := charptr(0)
for { for {
unsafe { unsafe {
x = C.fgets(charptr(buf), 4096, f.cfile) x = C.fgets(charptr(buf), 4096, f.cfile)

View File

@ -252,7 +252,7 @@ pub fn is_writable_folder(folder string) ?bool {
} }
tmp_perm_check := os.join_path(folder, 'XXXXXX') tmp_perm_check := os.join_path(folder, 'XXXXXX')
unsafe { unsafe {
x := C.mkstemp(tmp_perm_check.str) x := C.mkstemp(charptr(tmp_perm_check.str))
if -1 == x { if -1 == x {
return error('folder `$folder` is not writable') return error('folder `$folder` is not writable')
} }

View File

@ -439,7 +439,6 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
mut len1 := -1 // decimal part for floats mut len1 := -1 // decimal part for floats
def_len1 := 6 // default value for len1 def_len1 := 6 // default value for len1
mut pad_ch := byte(` `) // pad char mut pad_ch := byte(` `) // pad char
mut th_separator := false // thousands separator flag
// prefix chars for Length field // prefix chars for Length field
mut ch1 := `0` // +1 char if present else `0` mut ch1 := `0` // +1 char if present else `0`
@ -453,7 +452,6 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
len0 = -1 len0 = -1
len1 = -1 len1 = -1
pad_ch = ` ` pad_ch = ` `
th_separator = false
status = .norm_char status = .norm_char
ch1 = `0` ch1 = `0`
ch2 = `0` ch2 = `0`
@ -518,7 +516,6 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
i++ i++
continue continue
} else if ch == `'` { } else if ch == `'` {
th_separator = true
i++ i++
continue continue
} else if ch == `.` && fc_ch1 >= `1` && fc_ch1 <= `9` { } else if ch == `.` && fc_ch1 >= `1` && fc_ch1 <= `9` {

View File

@ -66,7 +66,7 @@ pub fn parse_iso8601(s string) ?Time {
offset_hour := 0 offset_hour := 0
offset_min := 0 offset_min := 0
count := unsafe {C.sscanf(charptr(s.str), '%4d-%2d-%2d%c%2d:%2d:%2d.%6d%c%2d:%2d', count := unsafe {C.sscanf(charptr(s.str), '%4d-%2d-%2d%c%2d:%2d:%2d.%6d%c%2d:%2d',
&year, &month, &day, &time_char, &hour, &minute, &second, &mic_second, &plus_min, &offset_hour, &year, &month, &day, charptr(&time_char), &hour, &minute, &second, &mic_second, charptr(&plus_min), &offset_hour,
&offset_min)} &offset_min)}
if count != 11 { if count != 11 {
return error('Invalid 8601 format') return error('Invalid 8601 format')

View File

@ -76,6 +76,12 @@ fn (mut v Builder) find_win_cc() ? {
v.pref.ccompiler_type = pref.cc_from_string(v.pref.ccompiler) v.pref.ccompiler_type = pref.cc_from_string(v.pref.ccompiler)
} }
fn (mut v Builder) show_c_compiler_output(res os.Result) {
println('======== C Compiler output ========')
println(res.output)
println('=================================')
}
fn (mut v Builder) post_process_c_compiler_output(res os.Result) { fn (mut v Builder) post_process_c_compiler_output(res os.Result) {
if res.exit_code == 0 { if res.exit_code == 0 {
if v.pref.reuse_tmpc { if v.pref.reuse_tmpc {
@ -545,6 +551,9 @@ fn (mut v Builder) cc() {
} }
diff := time.ticks() - ticks diff := time.ticks() - ticks
v.timing_message('C ${ccompiler:3}', diff) v.timing_message('C ${ccompiler:3}', diff)
if v.pref.show_c_output {
v.show_c_compiler_output(res)
}
if res.exit_code == 127 { if res.exit_code == 127 {
// the command could not be found by the system // the command could not be found by the system
$if linux { $if linux {
@ -559,7 +568,9 @@ fn (mut v Builder) cc() {
'-----------------------------------------------------------\n' + 'Probably your C compiler is missing. \n' + '-----------------------------------------------------------\n' + 'Probably your C compiler is missing. \n' +
'Please reinstall it, or make it available in your PATH.\n\n' + missing_compiler_info()) 'Please reinstall it, or make it available in your PATH.\n\n' + missing_compiler_info())
} }
v.post_process_c_compiler_output(res) if !v.pref.show_c_output {
v.post_process_c_compiler_output(res)
}
// Print the C command // Print the C command
if v.pref.is_verbose { if v.pref.is_verbose {
println('$ccompiler took $diff ms') println('$ccompiler took $diff ms')

View File

@ -303,7 +303,11 @@ pub fn (mut v Builder) cc_msvc() {
} }
diff := time.ticks() - ticks diff := time.ticks() - ticks
v.timing_message('C msvc', diff) v.timing_message('C msvc', diff)
v.post_process_c_compiler_output(res) if v.pref.show_c_output {
v.show_c_compiler_output(res)
} else {
v.post_process_c_compiler_output(res)
}
// println(res) // println(res)
// println('C OUTPUT:') // println('C OUTPUT:')
// Always remove the object file - it is completely unnecessary // Always remove the object file - it is completely unnecessary

View File

@ -1440,7 +1440,6 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
// return; // return;
// } // }
// int pos = *(int*)_t190.data; // int pos = *(int*)_t190.data;
mut gen_or := false
mut tmp_opt := '' mut tmp_opt := ''
is_optional := g.pref.autofree && is_optional := g.pref.autofree &&
(assign_stmt.op in [.decl_assign, .assign]) && assign_stmt.left_types.len == 1 && assign_stmt.right[0] is (assign_stmt.op in [.decl_assign, .assign]) && assign_stmt.left_types.len == 1 && assign_stmt.right[0] is
@ -1453,7 +1452,6 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
tmp_opt = g.new_tmp_var() tmp_opt = g.new_tmp_var()
g.write('/*AF opt*/$styp $tmp_opt = ') g.write('/*AF opt*/$styp $tmp_opt = ')
g.expr(assign_stmt.right[0]) g.expr(assign_stmt.right[0])
gen_or = true
g.or_block(tmp_opt, call_expr.or_block, call_expr.return_type) g.or_block(tmp_opt, call_expr.or_block, call_expr.return_type)
g.writeln('/*=============ret*/') g.writeln('/*=============ret*/')
// if af && is_optional { // if af && is_optional {
@ -2128,7 +2126,11 @@ fn (mut g Gen) expr(node ast.Expr) {
g.write('))') g.write('))')
} }
ast.CharLiteral { ast.CharLiteral {
g.write("'$node.val'") if node.val == r'\`' {
g.write("'`'")
} else {
g.write("'$node.val'")
}
} }
ast.AtExpr { ast.AtExpr {
g.comp_at(node) g.comp_at(node)
@ -4662,7 +4664,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
g.expr(node.left) g.expr(node.left)
g.write('${deref}len, ') g.write('${deref}len, ')
g.expr(node.left) g.expr(node.left)
g.writeln('${deref}element_size, $compare_fn);') g.writeln('${deref}element_size, (int (*)(const void *, const void *))&$compare_fn);')
} }
// `nums.filter(it % 2 == 0)` // `nums.filter(it % 2 == 0)`
@ -5060,7 +5062,15 @@ fn c_name(name_ string) string {
return name return name
} }
fn (mut g Gen) type_default(typ table.Type) string { fn (mut g Gen) type_default(typ_ table.Type) string {
typ := g.unwrap_generic(typ_)
if typ.has_flag(.optional) {
return '{0}'
}
// Always set pointers to 0
if typ.is_ptr() {
return '0'
}
sym := g.table.get_type_symbol(typ) sym := g.table.get_type_symbol(typ)
if sym.kind == .array { if sym.kind == .array {
elem_sym := g.typ(sym.array_info().elem_type) elem_sym := g.typ(sym.array_info().elem_type)
@ -5074,10 +5084,6 @@ fn (mut g Gen) type_default(typ table.Type) string {
value_type_str := g.typ(sym.map_info().value_type) value_type_str := g.typ(sym.map_info().value_type)
return 'new_map_1(sizeof($value_type_str))' return 'new_map_1(sizeof($value_type_str))'
} }
// Always set pointers to 0
if typ.is_ptr() {
return '0'
}
// User struct defined in another module. // User struct defined in another module.
// if typ.contains('__') { // if typ.contains('__') {
if sym.kind == .struct_ { if sym.kind == .struct_ {
@ -5105,7 +5111,8 @@ fn (mut g Gen) type_default(typ table.Type) string {
else {} else {}
} }
return match sym.kind { return match sym.kind {
.interface_, .sum_type, .array_fixed { '{0}' } .interface_, .sum_type, .array_fixed, .multi_return { '{0}' }
.alias { g.type_default((sym.info as table.Alias).parent_type) }
else { '0' } else { '0' }
} }
// TODO this results in // TODO this results in

View File

@ -67,6 +67,10 @@ const (
#undef TCCSKIP #undef TCCSKIP
#define TCCSKIP(x) #define TCCSKIP(x)
// #include <byteswap.h> // #include <byteswap.h>
#ifndef _WIN32
#include <execinfo.h>
int tcc_backtrace(const char *fmt, ...);
#endif
#endif #endif
// for __offset_of // for __offset_of
@ -431,20 +435,7 @@ typedef double any_float;
typedef unsigned char* byteptr; typedef unsigned char* byteptr;
typedef void* voidptr; typedef void* voidptr;
typedef char* charptr; typedef char* charptr;
typedef struct array array;
typedef struct map map;
typedef array array_int;
typedef array array_f32;
typedef array array_f64;
typedef array array_u16;
typedef array array_u32;
typedef array array_u64;
//typedef map map_int;
//typedef map map_string;
//typedef array array_string;
//typedef array array_byte;
typedef byte array_fixed_byte_300 [300]; typedef byte array_fixed_byte_300 [300];
typedef byte array_fixed_byte_400 [400];
typedef struct sync__Channel* chan; typedef struct sync__Channel* chan;

View File

@ -158,6 +158,15 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
// TODO: remove this, when g.write_autofree_stmts_when_needed works properly // TODO: remove this, when g.write_autofree_stmts_when_needed works properly
g.autofree_scope_vars(it.body_pos.pos) g.autofree_scope_vars(it.body_pos.pos)
} }
if it.return_type != table.void_type {
mut default_expr := g.type_default(it.return_type)
// TODO: perf?
if default_expr == '{0}' {
g.writeln('\treturn ($type_name)$default_expr;')
} else {
g.writeln('\treturn $default_expr;')
}
}
g.writeln('}') g.writeln('}')
g.defer_stmts = [] g.defer_stmts = []
if g.pref.printfn_list.len > 0 && g.last_fn_c_name in g.pref.printfn_list { if g.pref.printfn_list.len > 0 && g.last_fn_c_name in g.pref.printfn_list {
@ -240,15 +249,7 @@ fn (mut g Gen) fn_args(args []table.Param, is_variadic bool) ([]string, []string
g.definitions.write(')') g.definitions.write(')')
} }
} else { } else {
mut nr_muls := arg.typ.nr_muls()
s := arg_type_name + ' ' + caname s := arg_type_name + ' ' + caname
if arg.is_mut {
// mut arg needs one *
nr_muls = 1
}
// if nr_muls > 0 && !is_varg {
// s = arg_type_name + strings.repeat(`*`, nr_muls) + ' ' + caname
// }
g.write(s) g.write(s)
g.definitions.write(s) g.definitions.write(s)
fargs << caname fargs << caname

View File

@ -6,6 +6,10 @@ import v.ast
import v.table import v.table
import strings import strings
const (
invalid_escapes = ['(', '{', '$', '`', '.']
)
fn smart_quote(str string, raw bool) string { fn smart_quote(str string, raw bool) string {
len := str.len len := str.len
if len == 0 { if len == 0 {
@ -14,6 +18,7 @@ fn smart_quote(str string, raw bool) string {
mut result := strings.new_builder(0) mut result := strings.new_builder(0)
mut pos := -1 mut pos := -1
mut last := '' mut last := ''
// TODO: This should be a single char?
mut next := '' mut next := ''
mut skip_next := false mut skip_next := false
for { for {
@ -43,45 +48,43 @@ fn smart_quote(str string, raw bool) string {
toadd = '\\"' toadd = '\\"'
current = '' current = ''
} }
if raw && current == '\\' { if current == '\\' {
toadd = '\\\\' if raw {
}
// keep newlines in string
if current == '\n' {
toadd = '\\n'
current = ''
}
if current == '\r' && next == '\n' {
toadd = '\r\n'
current = ''
skip_next = true
}
// backslash
if !raw && current == '\\' {
// escaped backslash - keep as is
if next == '\\' {
toadd = '\\\\' toadd = '\\\\'
skip_next = true } else {
} // escaped backslash - keep as is
// keep raw escape squence if next == '\\' {
else { toadd = '\\\\'
if next != '' { skip_next = true
} else if next != '' {
if raw { if raw {
toadd = '\\\\' + next toadd = '\\\\' + next
skip_next = true skip_next = true
} }
// escape it // keep all valid escape sequences
else { else if next !in invalid_escapes {
toadd = '\\' + next toadd = '\\' + next
skip_next = true skip_next = true
} else {
toadd = next
skip_next = true
} }
} }
} }
} }
// keep newlines in string
if current == '\n' {
toadd = '\\n'
current = ''
} else if current == '\r' && next == '\n' {
toadd = '\r\n'
current = ''
skip_next = true
}
// Dolar sign // Dolar sign
if !raw && current == '$' { if !raw && current == '$' {
if last == '\\' { if last == '\\' {
toadd = '\\$' toadd = r'\$'
} }
} }
// Windows style new line \r\n // Windows style new line \r\n

View File

@ -922,6 +922,7 @@ pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident {
} else { } else {
p.error('unexpected token `$p.tok.lit`') p.error('unexpected token `$p.tok.lit`')
} }
return ast.Ident{}
} }
pub fn (mut p Parser) name_expr() ast.Expr { pub fn (mut p Parser) name_expr() ast.Expr {

View File

@ -73,6 +73,7 @@ pub mut:
is_debug bool // false by default, turned on by -g or -cg, it tells v to pass -g to the C backend compiler. is_debug bool // false by default, turned on by -g or -cg, it tells v to pass -g to the C backend compiler.
is_vlines bool // turned on by -g, false by default (it slows down .tmp.c generation slightly). is_vlines bool // turned on by -g, false by default (it slows down .tmp.c generation slightly).
show_cc bool // -showcc, print cc command show_cc bool // -showcc, print cc command
show_c_output bool // -show-c-output, print all cc output even if the code was compiled correctly
// NB: passing -cg instead of -g will set is_vlines to false and is_debug to true, thus making v generate cleaner C files, // NB: passing -cg instead of -g will set is_vlines to false and is_debug to true, thus making v generate cleaner C files,
// which are sometimes easier to debug / inspect manually than the .tmp.c files by plain -g (when/if v line number generation breaks). // which are sometimes easier to debug / inspect manually than the .tmp.c files by plain -g (when/if v line number generation breaks).
use_cache bool // turns on v usage of the module cache to speed up compilation. use_cache bool // turns on v usage of the module cache to speed up compilation.
@ -243,6 +244,9 @@ pub fn parse_args(args []string) (&Preferences, string) {
'-showcc' { '-showcc' {
res.show_cc = true res.show_cc = true
} }
'-show-c-output' {
res.show_c_output = true
}
'-experimental' { '-experimental' {
res.experimental = true res.experimental = true
} }
@ -253,9 +257,6 @@ pub fn parse_args(args []string) (&Preferences, string) {
res.prealloc = true res.prealloc = true
res.build_options << arg res.build_options << arg
} }
'-keepc' {
eprintln('-keepc is deprecated. V always keeps the generated .tmp.c files now.')
}
'-parallel' { '-parallel' {
res.is_parallel = true res.is_parallel = true
} }

View File

@ -865,7 +865,6 @@ pub fn (table &Table) type_to_str(t Type) string {
res += table.type_to_str(typ) res += table.type_to_str(typ)
} }
res += ')' res += ')'
res = res
} }
.void { .void {
if t.has_flag(.optional) { if t.has_flag(.optional) {