diff --git a/config.d/compiling.m4 b/config.d/compiling.m4 index f5603bd25..0ce257f7b 100644 --- a/config.d/compiling.m4 +++ b/config.d/compiling.m4 @@ -111,6 +111,20 @@ if test "x$CLANG" = xyes -a "x$leave_cflags_alone" != xyes; then CFLAGS="$CFLAGS -Wno-misleading-indentation" fi +AC_ARG_ENABLE(ubsan, + AS_HELP_STRING([--enable-ubsan], + [compile with ubsan (for development)]), + ubsan=$enable_ubsan, + ubsan=no +) +if test "x$ubsan" = xyes -a "x$leave_cflags_alone" != "xyes"; then + QF_CC_OPTION(-fsanitize=undefined) + QF_CC_OPTION_TEST([-fsanitize=undefined], [ + CFLAGS="$CFLAGS -fsanitize=undefined" + CXXFLAGS="$CXXFLAGS -fsanitize=undefined" + ]) +fi + AC_ARG_ENABLE(optimize, AS_HELP_STRING([--disable-optimize], [compile without optimizations (for development)]), diff --git a/libs/ruamoko/rua_runtime.c b/libs/ruamoko/rua_runtime.c index ea0c7a9bf..2427acc11 100644 --- a/libs/ruamoko/rua_runtime.c +++ b/libs/ruamoko/rua_runtime.c @@ -63,9 +63,9 @@ bi_va_copy (progs_t *pr, void *data) if (size) { dst_list_block = PR_AllocTempBlock (pr, size); dst_list = (pr_type_t *) PR_GetString (pr, dst_list_block); + memcpy (dst_list, src_list, size); } - memcpy (dst_list, src_list, size); R_PACKED (pr, pr_va_list_t).count = src_args->count; R_PACKED (pr, pr_va_list_t).list = PR_SetPointer (pr, dst_list); } diff --git a/libs/util/set.c b/libs/util/set.c index 71f1a82e9..45376fc07 100644 --- a/libs/util/set.c +++ b/libs/util/set.c @@ -191,6 +191,11 @@ _set_remove (set_t *set, unsigned x) SET_REMOVE(set, x); } +#define START_MASK(start) \ + ((~SET_ZERO) << (start % SET_BITS)) +#define END_MASK(end) \ + ((~SET_ZERO) >> ((SET_BITS - ((end + 1) % SET_BITS)) % SET_BITS)) + static inline void _set_add_range (set_t *set, unsigned start, unsigned count) { @@ -201,8 +206,8 @@ _set_add_range (set_t *set, unsigned start, unsigned count) set_expand (set, start + count); } unsigned end = start + count - 1; - set_bits_t start_mask = (~SET_ZERO) << (start % SET_BITS); - set_bits_t end_mask = (~SET_ZERO) >> (SET_BITS - ((end + 1) % SET_BITS)); + set_bits_t start_mask = START_MASK (start); + set_bits_t end_mask = END_MASK (end); unsigned start_ind = start / SET_BITS; unsigned end_ind = end / SET_BITS; if (start_ind == end_ind) { @@ -229,8 +234,8 @@ _set_remove_range (set_t *set, unsigned start, unsigned count) count = set->size - start; } unsigned end = start + count - 1; - set_bits_t start_mask = (~SET_ZERO) << (start % SET_BITS); - set_bits_t end_mask = (~SET_ZERO) >> (SET_BITS - ((end + 1) % SET_BITS)); + set_bits_t start_mask = START_MASK (start); + set_bits_t end_mask = END_MASK (end); unsigned start_ind = start / SET_BITS; unsigned end_ind = end / SET_BITS; if (start_ind == end_ind) { diff --git a/libs/util/test/test-set.c b/libs/util/test/test-set.c index 4e214cae8..acbf133c4 100644 --- a/libs/util/test/test-set.c +++ b/libs/util/test/test-set.c @@ -85,6 +85,22 @@ make_range_0_SIZE (void) return set; } +static set_t * +make_range_0_SIZEm1 (void) +{ + set_t *set = set_new (); + set_add_range (set, 0, SIZE - 1); + return set; +} + +static set_t * +make_range_0_SIZEx2 (void) +{ + set_t *set = set_new (); + set_add_range (set, 0, SIZE*2); + return set; +} + static set_t * make_range_1_SIZE (void) { @@ -302,6 +318,22 @@ struct { " 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47" " 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63}" }, + {make_range_0_SIZEm1, 0, 0, check_size, SIZE, + "{0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" + " 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31" + " 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47" + " 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62}" + }, + {make_range_0_SIZEx2, 0, 0, check_size, SIZE*2, + "{0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" + " 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31" + " 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47" + " 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63" + " 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79" + " 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95" + " 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111" + " 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127}" + }, {make_range_1_SIZE, 0, 0, check_size, SIZE + SET_BITS, "{1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" " 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31" diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 92c78f433..bd529b8b2 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2105,7 +2105,7 @@ build_function_call (const expr_t *fexpr, const type_t *ftype, const expr_t *par const expr_t *err = 0; int arg_count = params ? list_count (¶ms->list) :0; - const expr_t *arguments[arg_count]; + const expr_t *arguments[arg_count + 1]; if (params) { list_scatter_rev (¶ms->list, arguments); } @@ -2145,7 +2145,7 @@ build_function_call (const expr_t *fexpr, const type_t *ftype, const expr_t *par param_count = ftype->t.func.num_params; } - const type_t *arg_types[arg_count]; + const type_t *arg_types[arg_count + 1]; // params is reversed (a, b, c) -> c, b, a for (int i = 0; i < arg_count; i++) { auto e = arguments[i]; @@ -2224,7 +2224,7 @@ build_function_call (const expr_t *fexpr, const type_t *ftype, const expr_t *par call = new_block_expr (0); call->block.is_call = 1; int arg_expr_count = 0; - const expr_t *arg_exprs[arg_count][2]; + const expr_t *arg_exprs[arg_count + 1][2]; expr_t *args = new_list_expr (0); // args is built in reverse order so it matches params for (int i = 0; i < arg_count; i++) { diff --git a/tools/qfcc/source/flow.c b/tools/qfcc/source/flow.c index 835700dd8..2441511ac 100644 --- a/tools/qfcc/source/flow.c +++ b/tools/qfcc/source/flow.c @@ -1279,10 +1279,12 @@ flow_build_chains (flowgraph_t *graph) set_delete (reach.stdef); graph->func->du_chains = malloc (num_ud_chains * sizeof (udchain_t)); - memcpy (graph->func->du_chains, graph->func->ud_chains, - num_ud_chains * sizeof (udchain_t)); - heapsort (graph->func->du_chains, num_ud_chains, sizeof (udchain_t), - duchain_cmp); + if (num_ud_chains) { + memcpy (graph->func->du_chains, graph->func->ud_chains, + num_ud_chains * sizeof (udchain_t)); + heapsort (graph->func->du_chains, num_ud_chains, sizeof (udchain_t), + duchain_cmp); + } for (int i = 0; i < num_ud_chains; i++) { udchain_t du = graph->func->du_chains[i]; diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 3dc725cca..fd6ca53f1 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -373,7 +373,7 @@ find_function (const expr_t *fexpr, const expr_t *params) type.type = ev_func; type.t.func.num_params = params ? list_count (¶ms->list) : 0; - const expr_t *args[type.t.func.num_params]; + const expr_t *args[type.t.func.num_params + 1]; if (params) { list_scatter_rev (¶ms->list, args); } @@ -384,7 +384,7 @@ find_function (const expr_t *fexpr, const expr_t *params) return e; } } - const type_t *arg_types[type.t.func.num_params]; + const type_t *arg_types[type.t.func.num_params + 1]; type.t.func.param_types = arg_types; for (int i = 0; i < type.t.func.num_params; i++) { auto e = args[i]; diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index f3447c5fb..31603c38b 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -1183,8 +1183,10 @@ qfo_to_progs (qfo_t *in_qfo, int *size) // clear locals data memset (locals, 0, globals_info.locals_size * sizeof (pr_type_t)); // copy far data - memcpy (far_data, qfo->spaces[qfo_far_data_space].data, - qfo->spaces[qfo_far_data_space].data_size * sizeof (pr_type_t)); + if (qfo->spaces[qfo_far_data_space].data_size) { + memcpy (far_data, qfo->spaces[qfo_far_data_space].data, + qfo->spaces[qfo_far_data_space].data_size * sizeof (pr_type_t)); + } qfo->spaces[qfo_far_data_space].data = far_data; // copy type data memcpy (type_data, qfo->spaces[qfo_type_space].data, diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index b15ccc3e2..24a17491b 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -1174,7 +1174,7 @@ expr_call (sblock_t *sblock, const expr_t *call, operand_t **op) scoped_src_loc (call); int num_args = list_count (&call->branch.args->list); - const expr_t *args[num_args]; + const expr_t *args[num_args + 1]; list_scatter_rev (&call->branch.args->list, args); int arg_num = 0; for (int i = 0; i < num_args; i++) { diff --git a/tools/qfcc/source/struct.c b/tools/qfcc/source/struct.c index 80e6b81a0..e2438127b 100644 --- a/tools/qfcc/source/struct.c +++ b/tools/qfcc/source/struct.c @@ -284,7 +284,7 @@ add_enum (symbol_t *enm, symbol_t *name, const expr_t *val) name->type = enum_type; value = 0; if (enum_tab->symbols) - value = ((symbol_t *)(enum_tab->symtail))->s.value->v.int_val + 1; + value = ((symbol_t *)(enum_tab->symtail))->s.value->v.uint_val + 1; if (val) { val = convert_name (val); if (!is_constant (val))