diff options
| -rw-r--r-- | Documentation/TODO.md | 29 | ||||
| -rw-r--r-- | Documentation/release-notes/v0.6.3.rst | 5 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | builtin.c | 114 | ||||
| -rw-r--r-- | evaluate.c | 6 | ||||
| -rw-r--r-- | options.c | 3 | ||||
| -rw-r--r-- | options.h | 1 | ||||
| -rw-r--r-- | predefine.c | 7 | ||||
| -rw-r--r-- | sparse.1 | 6 | ||||
| -rw-r--r-- | symbol.c | 12 | ||||
| -rw-r--r-- | symbol.h | 2 | ||||
| -rw-r--r-- | validation/builtin-arith.c | 31 | ||||
| -rw-r--r-- | validation/builtin-atomic-clear.c | 15 | ||||
| -rw-r--r-- | validation/builtin-sync-fetch.c | 24 | ||||
| -rw-r--r-- | validation/crash-undef-in-parens.c | 9 | ||||
| -rw-r--r-- | validation/flex-array-nested.c | 4 | ||||
| -rw-r--r-- | validation/linear/bitfield-sign-default.c | 13 | ||||
| -rw-r--r-- | validation/linear/bitfield-sign-signed.c | 13 | ||||
| -rw-r--r-- | validation/linear/bitfield-sign-unsigned.c | 13 | ||||
| -rw-r--r-- | validation/linear/bitfield-size.c | 10 | ||||
| -rw-r--r-- | validation/optim/bitfield-size.c | 15 | ||||
| -rw-r--r-- | validation/optim/bitfield-store-loads.c | 4 | ||||
| -rw-r--r-- | validation/optim/sext.c | 7 | ||||
| -rw-r--r-- | validation/optim/trunc-or-shl.c | 6 |
24 files changed, 264 insertions, 87 deletions
diff --git a/Documentation/TODO.md b/Documentation/TODO.md index e2043e48..4dc9e63a 100644 --- a/Documentation/TODO.md +++ b/Documentation/TODO.md @@ -4,13 +4,13 @@ TODO Essential --------- * SSA is broken by simplify_loads() & branches rewriting/simplification -* attributes of struct, union & enums are ignored (and possibly in other - cases too). -* add support for bitwise enums +* attributes of struct, union & enums are ignored (and maybe others too). + This requires correct support for __packed which itself needs partial + and unaligned loads & stores (wip) +* add support for bitwise enums (wip) Documentation ------------- -* document the extensions * document the API * document the limitations of modifying ptrlists during list walking * document the data structures @@ -27,7 +27,7 @@ Core Testsuite --------- -* there are more than 50 failing tests. They should be fixed +* there are 60 failing tests. They should be fixed (but most are non-trivial to fix). Misc @@ -36,15 +36,26 @@ Misc * parse __attribute_((fallthrough)) * add support for format(printf()) (WIP by Ben Dooks) * make use of UNDEFs (issues warnings, simplification, ... ?) -* add a pass to inline small functions during simplification. +* make memory accesses more explicit: add EXPR_ACCESS (wip) +* it would be nice to do our own parsing of floating point (wip) +* some header files needed for crypto/ need __vector or __fp16 +* some even need __complex Optimization ------------ +* a lot of small simplifications are waiting to be upstreamed +* the domtree need to be rebuilt (or updated) +* critical edges need to be split * the current way of doing CSE uses a lot of time * add SSA based DCE * add SSA based PRE * Add SSA based SCCP +* add a pass to inline small functions during simplification. * use better/more systematic use of internal verification framework +* tracking of operands size should be improved (WIP) +* OP_INLINE is sometimes in the way +* would be nice to strictly separate phases that don't changes the + CFG and thus the dominance tree. IR -- @@ -60,13 +71,15 @@ LLVM Internal backends ----------------- -* add some basic register allocation +* it would be nice the upstream the code generator * add a pass to transform 3-addresses code to 2-addresses +* add some basic register allocation +* add a pass to order the BBs and changes 2-ways CBR into one-way branches * what can be done for x86? +* add support to add constraints in the MD rules Longer term/to investigate -------------------------- -* better architecture handling than current machine.h + target.c * attributes are represented as ctypes's alignment, modifiers & contexts but plenty of attributes doesn't fit, for example they need arguments. * format(printf, ...), diff --git a/Documentation/release-notes/v0.6.3.rst b/Documentation/release-notes/v0.6.3.rst index 521c0063..7ec59eff 100644 --- a/Documentation/release-notes/v0.6.3.rst +++ b/Documentation/release-notes/v0.6.3.rst @@ -1,5 +1,5 @@ -v0.6.3 (Fall 2020) -================== +v0.6.3 (2020-10-17) +=================== Bug fixes: * fix missing inlining of _Generic expression @@ -15,6 +15,7 @@ Bug fixes: * fix access to defining instruction in simplify_unop() * fix evaluation of pointer to bool conversions * fix usual conversion of integers + * fix null pointer deref on return expression with invalid type New features: * add support for arch specific asm constraints @@ -1,4 +1,4 @@ -VERSION=0.6.3-rc1 +VERSION=0.6.3 ######################################################################## # The following variables can be overwritten from the command line @@ -31,6 +31,14 @@ #include "compat/bswap.h" #include <stdarg.h> +#define dyntype incomplete_ctype +static bool is_dynamic_type(struct symbol *t) +{ + if (t->type == SYM_NODE) + t = t->ctype.base_type; + return t == &dyntype; +} + static int evaluate_to_int_const_expr(struct expression *expr) { expr->ctype = &int_ctype; @@ -83,6 +91,13 @@ error: return 0; } +static int args_prototype(struct expression *expr) +{ + struct symbol *fntype = expr->fn->ctype->ctype.base_type; + int n = symbol_list_size(fntype->arguments); + return eval_args(expr, n); +} + static int args_triadic(struct expression *expr) { return eval_args(expr, 3); @@ -355,29 +370,32 @@ static struct symbol_op overflow_p_op = { }; -static int eval_sync_compare_and_swap(struct expression *expr) +static int eval_atomic_common(struct expression *expr) { + struct symbol *fntype = expr->fn->ctype->ctype.base_type; struct symbol_list *types = NULL; struct symbol *ctype = NULL; + struct symbol *t; struct expression *arg; int n = 0; - /* the first arg is a pointer type; we'd already verified that */ + // The number of arguments has already be verified. + // The first arg must be a pointer to an integral type. + PREPARE_PTR_LIST(fntype->arguments, t); FOR_EACH_PTR(expr->args, arg) { - struct symbol *t = arg->ctype; + struct symbol *ptrtype = NULL; - if (!t) - return 0; - - // 2nd & 3rd args must be a basic integer type or a pointer - // 1st arg must be a pointer to such a type. if (++n == 1) { + t = arg->ctype; + if (!t) + return 0; if (t->type == SYM_NODE) t = t->ctype.base_type; if (!t) return 0; if (t->type != SYM_PTR) goto err; + ptrtype = t; t = t->ctype.base_type; if (!t) return 0; @@ -388,13 +406,18 @@ static int eval_sync_compare_and_swap(struct expression *expr) if (t->type != SYM_PTR && t->ctype.base_type != &int_type) goto err; ctype = t; - add_ptr_list(&types, arg->ctype); - } else { - add_ptr_list(&types, ctype); + t = ptrtype; + } else if (is_dynamic_type(t)) { + t = ctype; + } else if (t == &ptr_ctype) { + t = ptrtype; } + add_ptr_list(&types, t); + NEXT_PTR_LIST(t); } END_FOR_EACH_PTR(arg); + FINISH_PTR_LIST(t); - if (!expr->ctype) // __sync_val_compare_and_swap() + if (!expr->ctype) // set the return type, if needed expr->ctype = ctype; return evaluate_arguments(types, expr->args); @@ -405,9 +428,9 @@ err: return 0; } -static struct symbol_op sync_compare_and_swap_op = { - .args = args_triadic, - .evaluate = eval_sync_compare_and_swap, +static struct symbol_op atomic_op = { + .args = args_prototype, + .evaluate = eval_atomic_common, }; @@ -457,6 +480,33 @@ static void declare_builtins(int stream, const struct builtin_fn tbl[]) static const struct builtin_fn builtins_common[] = { #define size_t_ctype &size_t_alias #define va_list_ctype &ptr_ctype +#define vol_ptr &volatile_ptr_ctype + { "__atomic_add_fetch", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_always_lock_free", &bool_ctype, 0, { size_t_ctype, vol_ptr }}, + { "__atomic_and_fetch", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_clear", &void_ctype, 0, { &volatile_bool_ptr_ctype, &int_ctype }}, + { "__atomic_compare_exchange", &bool_ctype, 0, { vol_ptr, &ptr_ctype, &ptr_ctype, &bool_ctype, &int_ctype, &int_ctype }, .op = &atomic_op }, + { "__atomic_compare_exchange_n", &bool_ctype, 0, { vol_ptr, &ptr_ctype, &dyntype, &bool_ctype, &int_ctype, &int_ctype }, .op = &atomic_op }, + { "__atomic_exchange", &void_ctype, 0, { vol_ptr, &ptr_ctype, &ptr_ctype, &int_ctype }, .op = &atomic_op }, + { "__atomic_exchange_n", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_fetch_add", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_fetch_and", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_fetch_nand",NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_fetch_or", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_fetch_sub", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_fetch_xor", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_is_lock_free", &bool_ctype, 0, { size_t_ctype, vol_ptr }}, + { "__atomic_load", &void_ctype, 0, { vol_ptr, &ptr_ctype, &int_ctype }, .op = &atomic_op }, + { "__atomic_load_n", NULL, 0, { vol_ptr, &int_ctype }, .op = &atomic_op }, + { "__atomic_nand_fetch",NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_or_fetch", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_signal_fence", &void_ctype, 0, { &int_ctype }}, + { "__atomic_store", &void_ctype, 0, { vol_ptr, &ptr_ctype, &int_ctype }, .op = &atomic_op }, + { "__atomic_store_n", &void_ctype, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_sub_fetch", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, + { "__atomic_test_and_set", &bool_ctype, 0, { vol_ptr, &int_ctype }}, + { "__atomic_thread_fence", &void_ctype, 0, { &int_ctype }}, + { "__atomic_xor_fetch", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op }, { "__builtin_choose_expr", NULL, 1, .op = &choose_op }, { "__builtin_constant_p", NULL, 1, .op = &constant_p_op }, { "__builtin_expect", &long_ctype, 0, { &long_ctype ,&long_ctype }, .op = &expect_op }, @@ -605,23 +655,23 @@ static const struct builtin_fn builtins_common[] = { { "__builtin___vsnprintf_chk", &int_ctype, 0, { &string_ctype, size_t_ctype, &int_ctype, size_t_ctype, &const_string_ctype, va_list_ctype }}, { "__builtin___vsprintf_chk", &int_ctype, 0, { &string_ctype, &int_ctype, size_t_ctype, &const_string_ctype, va_list_ctype }}, - { "__sync_add_and_fetch", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_and_and_fetch", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_bool_compare_and_swap", &bool_ctype, 1, { &ptr_ctype }, .op = &sync_compare_and_swap_op}, - { "__sync_fetch_and_add", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_fetch_and_and", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_fetch_and_nand", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_fetch_and_or", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_fetch_and_sub", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_fetch_and_xor", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_lock_release", &void_ctype, 1, { &ptr_ctype }}, - { "__sync_lock_test_and_set", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_nand_and_fetch", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_or_and_fetch", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_sub_and_fetch", &int_ctype, 1, { &ptr_ctype }}, - { "__sync_synchronize", &void_ctype, 0 }, - { "__sync_val_compare_and_swap", NULL, 1, { &ptr_ctype }, .op = &sync_compare_and_swap_op }, - { "__sync_xor_and_fetch", &int_ctype, 1, { &ptr_ctype }}, + { "__sync_add_and_fetch", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_and_and_fetch", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_bool_compare_and_swap", &bool_ctype, 1, { vol_ptr, &dyntype, &dyntype }, .op = &atomic_op}, + { "__sync_fetch_and_add", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_fetch_and_and", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_fetch_and_nand", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_fetch_and_or", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_fetch_and_sub", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_fetch_and_xor", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_lock_release", &void_ctype, 1, { vol_ptr }, .op = &atomic_op }, + { "__sync_lock_test_and_set", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_nand_and_fetch", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_or_and_fetch", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_sub_and_fetch", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, + { "__sync_synchronize", &void_ctype, 1 }, + { "__sync_val_compare_and_swap", NULL, 1, { vol_ptr, &dyntype, &dyntype }, .op = &atomic_op }, + { "__sync_xor_and_fetch", NULL, 1, { vol_ptr, &dyntype }, .op = &atomic_op }, { } }; @@ -1787,6 +1787,8 @@ static struct symbol *degenerate(struct expression *expr) expression_error(expr, "strange non-value function or array"); return &bad_ctype; } + if (ctype->builtin) + sparse_error(expr->pos, "taking the address of built-in function '%s'", show_ident(ctype->ident)); *expr = *expr->unop; ctype = create_pointer(expr, ctype, 1); expr->ctype = ctype; @@ -1807,6 +1809,8 @@ static struct symbol *evaluate_addressof(struct expression *expr) return NULL; } ctype = op->ctype; + if (ctype->builtin) + sparse_error(expr->pos, "taking the address of built-in function '%s'", show_ident(ctype->ident)); *expr = *op->unop; mark_addressable(expr); @@ -3611,7 +3615,7 @@ static struct symbol *evaluate_return_expression(struct statement *stmt) fntype = current_fn->ctype.base_type; rettype = fntype->ctype.base_type; if (!rettype || rettype == &void_ctype) { - if (expr && !is_void_type(expr->ctype)) + if (expr && expr->ctype && !is_void_type(expr->ctype)) expression_error(expr, "return expression in %s function", rettype?"void":"typeless"); if (expr && Wreturn_void) warning(stmt->pos, "returning void-valued expression"); @@ -81,6 +81,7 @@ unsigned long fpasses = ~0UL; int fpic = 0; int fpie = 0; int fshort_wchar = 0; +int funsigned_bitfields = 0; int funsigned_char = 0; int Waddress = 0; @@ -528,6 +529,8 @@ static struct flag fflags[] = { { "PIC", &fpic, handle_switch_setval, 2 }, { "pie", &fpie, handle_switch_setval, 1 }, { "PIE", &fpie, handle_switch_setval, 2 }, + { "signed-bitfields", &funsigned_bitfields, NULL, OPT_INVERSE }, + { "unsigned-bitfields", &funsigned_bitfields, NULL, }, { "signed-char", &funsigned_char, NULL, OPT_INVERSE }, { "short-wchar", &fshort_wchar }, { "unsigned-char", &funsigned_char, NULL, }, @@ -80,6 +80,7 @@ extern unsigned long fpasses; extern int fpic; extern int fpie; extern int fshort_wchar; +extern int funsigned_bitfields; extern int funsigned_char; extern int Waddress; diff --git a/predefine.c b/predefine.c index f898cdfa..98e38a04 100644 --- a/predefine.c +++ b/predefine.c @@ -179,6 +179,13 @@ void predefined_macros(void) if (arch_target->has_int128) predefined_sizeof("INT128", "", 128); + predefine("__ATOMIC_RELAXED", 0, "0"); + predefine("__ATOMIC_CONSUME", 0, "1"); + predefine("__ATOMIC_ACQUIRE", 0, "3"); + predefine("__ATOMIC_RELEASE", 0, "4"); + predefine("__ATOMIC_ACQ_REL", 0, "7"); + predefine("__ATOMIC_SEQ_CST", 0, "8"); + predefine("__ORDER_LITTLE_ENDIAN__", 1, "1234"); predefine("__ORDER_BIG_ENDIAN__", 1, "4321"); predefine("__ORDER_PDP_ENDIAN__", 1, "3412"); @@ -548,6 +548,12 @@ column numbers in warnings or errors. If the value is less than 1 or greater than 100, the option is ignored. The default is 8. . .TP +.B \-f[no-]unsigned-bitfields, \-f[no-]signed-bitfields +Determine the signedness of bitfields declared without an +explicit sign ('signed' or 'unsigned'). +By default such bitfields are signed, like others plain integers. +. +.TP .B \-f[no-]unsigned-char, \-f[no-]signed-char Let plain 'char' be unsigned or signed. By default chars are signed. @@ -200,7 +200,7 @@ static struct symbol * examine_struct_union_type(struct symbol *sym, int advance if (has_flexible_array(member)) info.has_flex_array = 1; if (has_flexible_array(member) && Wflexible_array_nested) - warning(member->pos, "nested flexible arrays"); + warning(member->pos, "nested flexible array"); fn(member, &info); } END_FOR_EACH_PTR(member); @@ -298,8 +298,8 @@ static struct symbol *examine_bitfield_type(struct symbol *sym) sym->ctype.alignment = alignment; modifiers = base_type->ctype.modifiers; - /* Bitfields are unsigned, unless the base type was explicitly signed */ - if (!(modifiers & MOD_EXPLICITLY_SIGNED)) + /* use -funsigned-bitfields to determine the sign if not explicit */ + if (!(modifiers & MOD_EXPLICITLY_SIGNED) && funsigned_bitfields) modifiers = (modifiers & ~MOD_SIGNED) | MOD_UNSIGNED; sym->ctype.modifiers |= modifiers & MOD_SIGNEDNESS; return sym; @@ -805,6 +805,8 @@ struct symbol float128_ctype; struct symbol const_void_ctype, const_char_ctype; struct symbol const_ptr_ctype, const_string_ctype; struct symbol const_wchar_ctype, const_wstring_ctype; +struct symbol volatile_void_ctype, volatile_ptr_ctype; +struct symbol volatile_bool_ctype, volatile_bool_ptr_ctype; struct symbol zero_int; @@ -909,6 +911,10 @@ static const struct ctype_declare { { &const_void_ctype, T_CONST(&void_ctype, NULL, NULL) }, { &const_char_ctype, T_CONST(&char_ctype, &bits_in_char, &max_int_alignment)}, { &const_wchar_ctype, T_CONST(&int_ctype, NULL, NULL) }, + { &volatile_void_ctype,T_NODE(MOD_VOLATILE, &void_ctype, NULL, NULL) }, + { &volatile_ptr_ctype, T_PTR(&volatile_void_ctype) }, + { &volatile_bool_ctype,T_NODE(MOD_VOLATILE, &bool_ctype, NULL, NULL) }, + { &volatile_bool_ptr_ctype, T_PTR(&volatile_bool_ctype) }, { NULL, } }; @@ -310,6 +310,8 @@ extern struct symbol float128_ctype; extern struct symbol const_void_ctype, const_char_ctype; extern struct symbol const_ptr_ctype, const_string_ctype; extern struct symbol const_wchar_ctype, const_wstring_ctype; +extern struct symbol volatile_void_ctype, volatile_ptr_ctype; +extern struct symbol volatile_bool_ctype, volatile_bool_ptr_ctype; /* Special internal symbols */ extern struct symbol zero_int; diff --git a/validation/builtin-arith.c b/validation/builtin-arith.c index d08c93da..3ce59304 100644 --- a/validation/builtin-arith.c +++ b/validation/builtin-arith.c @@ -31,22 +31,27 @@ void test(void (*fun)(void)) /* * check-name: builtin arithmetic * check-command: sparse -Wno-decl $file - * check-known-to-fail * * check-error-start -builtin-arith.c:10:xx: error: ... -builtin-arith.c:11:xx: error: ... -builtin-arith.c:13:xx: error: arithmetics on pointers to functions -builtin-arith.c:14:xx: error: arithmetics on pointers to functions -builtin-arith.c:15:xx: error: arithmetics on pointers to functions -builtin-arith.c:18:xx: error: ... -builtin-arith.c:19:xx: error: ... -builtin-arith.c:21:xx: error: ... -builtin-arith.c:22:xx: error: ... -builtin-arith.c:23:xx: error: ... -builtin-arith.c:24:xx: error: ... -builtin-arith.c:25:xx: error: ... +builtin-arith.c:10:14: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:11:13: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:12:14: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:13:14: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:13:29: error: arithmetics on pointers to functions +builtin-arith.c:14:14: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:14:29: error: arithmetics on pointers to functions +builtin-arith.c:15:14: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:15:29: error: arithmetics on pointers to functions +builtin-arith.c:18:21: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:19:29: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:21:14: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:22:14: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:23:14: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:24:21: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:25:21: error: taking the address of built-in function '__builtin_trap' +builtin-arith.c:27:9: error: taking the address of built-in function '__builtin_trap' builtin-arith.c:27:24: error: subtraction of functions? Share your drugs +builtin-arith.c:28:15: error: taking the address of built-in function '__builtin_trap' builtin-arith.c:28:13: error: subtraction of functions? Share your drugs * check-error-end */ diff --git a/validation/builtin-atomic-clear.c b/validation/builtin-atomic-clear.c new file mode 100644 index 00000000..ef430c64 --- /dev/null +++ b/validation/builtin-atomic-clear.c @@ -0,0 +1,15 @@ +void foo(void *ptr, _Bool *bptr, volatile void *vptr, volatile _Bool *vbptr, int mo) +{ + __atomic_clear(ptr, mo); + __atomic_clear(bptr, mo); + __atomic_clear(vptr, mo); + __atomic_clear(vbptr, mo); +} + +/* + * check-name: builtin-atomic-clear + * + * check-error-start +builtin-atomic-clear.c:1:6: warning: symbol 'foo' was not declared. Should it be static? + * check-error-end + */ diff --git a/validation/builtin-sync-fetch.c b/validation/builtin-sync-fetch.c new file mode 100644 index 00000000..45139a3c --- /dev/null +++ b/validation/builtin-sync-fetch.c @@ -0,0 +1,24 @@ +static int ok_int(int *ptr, int val) +{ + return __sync_add_and_fetch(ptr, val); +} + +static long* ok_ptr(long **ptr, long *val) +{ + return __sync_add_and_fetch(ptr, val); +} + +static void chk_ret_ok(long *ptr, long val) +{ + _Static_assert([typeof(__sync_add_and_fetch(ptr, val))] == [long], ""); +} + +static int chk_val(int *ptr, long val) +{ + // OK: val is converted to an int + return __sync_add_and_fetch(ptr, val); +} + +/* + * check-name: builtin-sync-fetch + */ diff --git a/validation/crash-undef-in-parens.c b/validation/crash-undef-in-parens.c new file mode 100644 index 00000000..5f05f88a --- /dev/null +++ b/validation/crash-undef-in-parens.c @@ -0,0 +1,9 @@ +void foo(void) { return (UNDEF_STUFF_IN_PARENS); } + +/* + * check-name: crash-undef-in-parens + * + * check-error-start +crash-undef-in-parens.c:1:26: error: undefined identifier 'UNDEF_STUFF_IN_PARENS' + * check-error-end + */ diff --git a/validation/flex-array-nested.c b/validation/flex-array-nested.c index a82cbfc9..094de2fb 100644 --- a/validation/flex-array-nested.c +++ b/validation/flex-array-nested.c @@ -23,7 +23,7 @@ static int foo(struct s *s, union u *u) * check-command: sparse -Wflexible-array-nested $file * * check-error-start -flex-array-nested.c:7:18: warning: nested flexible arrays -flex-array-nested.c:11:18: warning: nested flexible arrays +flex-array-nested.c:7:18: warning: nested flexible array +flex-array-nested.c:11:18: warning: nested flexible array * check-error-end */ diff --git a/validation/linear/bitfield-sign-default.c b/validation/linear/bitfield-sign-default.c new file mode 100644 index 00000000..9a2854e6 --- /dev/null +++ b/validation/linear/bitfield-sign-default.c @@ -0,0 +1,13 @@ +struct s { + int f:2; +}; + +static int getf(struct s s) { return s.f; } + +/* + * check-name: bitfield-sign-default + * check-command: test-linearize -fdump-ir=linearize $file + * + * check-output-ignore + * check-output-contains: sext\\. + */ diff --git a/validation/linear/bitfield-sign-signed.c b/validation/linear/bitfield-sign-signed.c new file mode 100644 index 00000000..59a07ceb --- /dev/null +++ b/validation/linear/bitfield-sign-signed.c @@ -0,0 +1,13 @@ +struct s { + int f:2; +}; + +static int getf(struct s s) { return s.f; } + +/* + * check-name: bitfield-sign-signed + * check-command: test-linearize -fdump-ir=linearize -fsigned-bitfields $file + * + * check-output-ignore + * check-output-contains: sext\\. + */ diff --git a/validation/linear/bitfield-sign-unsigned.c b/validation/linear/bitfield-sign-unsigned.c new file mode 100644 index 00000000..099edaad --- /dev/null +++ b/validation/linear/bitfield-sign-unsigned.c @@ -0,0 +1,13 @@ +struct s { + int f:2; +}; + +static int getf(struct s s) { return s.f; } + +/* + * check-name: bitfield-sign-unsigned + * check-command: test-linearize -fdump-ir=linearize -funsigned-bitfields $file + * + * check-output-ignore + * check-output-contains: zext\\. + */ diff --git a/validation/linear/bitfield-size.c b/validation/linear/bitfield-size.c index dcda930d..719b0ab8 100644 --- a/validation/linear/bitfield-size.c +++ b/validation/linear/bitfield-size.c @@ -19,7 +19,7 @@ void ucpy(struct u *d, const struct u *s) struct s { - int f:3; + signed int f:3; }; int spostinc(struct s *x) @@ -118,7 +118,7 @@ spostinc: load.64 %r33 <- 0[x] load.32 %r34 <- 0[%r33] trunc.3 %r35 <- (32) %r34 - zext.32 %r36 <- (3) %r35 + sext.32 %r36 <- (3) %r35 add.32 %r37 <- %r36, $1 trunc.3 %r38 <- (32) %r37 load.32 %r39 <- 0[%r33] @@ -126,7 +126,7 @@ spostinc: and.32 %r41 <- %r39, $0xfffffff8 or.32 %r42 <- %r41, %r40 store.32 %r42 -> 0[%r33] - zext.32 %r43 <- (3) %r36 + sext.32 %r43 <- (3) %r36 phisrc.32 %phi3(return) <- %r43 br .L7 @@ -142,7 +142,7 @@ spreinc: load.64 %r45 <- 0[x] load.32 %r46 <- 0[%r45] trunc.3 %r47 <- (32) %r46 - zext.32 %r48 <- (3) %r47 + sext.32 %r48 <- (3) %r47 add.32 %r49 <- %r48, $1 trunc.3 %r50 <- (32) %r49 load.32 %r51 <- 0[%r45] @@ -150,7 +150,7 @@ spreinc: and.32 %r53 <- %r51, $0xfffffff8 or.32 %r54 <- %r53, %r52 store.32 %r54 -> 0[%r45] - zext.32 %r55 <- (3) %r50 + sext.32 %r55 <- (3) %r50 phisrc.32 %phi4(return) <- %r55 br .L9 diff --git a/validation/optim/bitfield-size.c b/validation/optim/bitfield-size.c index 0d2deeea..ea1ed57f 100644 --- a/validation/optim/bitfield-size.c +++ b/validation/optim/bitfield-size.c @@ -19,17 +19,6 @@ signed int get__bfs_b(struct bfs bf) { return bf.b; } signed int get_pbfs_a(struct bfs *bf) { return bf->a; } signed int get_pbfs_b(struct bfs *bf) { return bf->b; } - -struct bfi { - int a:4; - int :2; - int b:4; -}; -unsigned int get__bfi_a(struct bfi bf) { return bf.a; } -unsigned int get__bfi_b(struct bfi bf) { return bf.b; } -unsigned int get_pbfi_a(struct bfi *bf) { return bf->a; } -unsigned int get_pbfi_b(struct bfi *bf) { return bf->b; } - /* * check-name: bitfield size * check-command: test-linearize -Wno-decl $file @@ -37,8 +26,8 @@ unsigned int get_pbfi_b(struct bfi *bf) { return bf->b; } * * check-output-excludes: and\\..*\\$960 * check-output-excludes: zext\\. - * check-output-pattern(8): and\\..*\\$15 + * check-output-pattern(4): and\\..*\\$15 * check-output-pattern(4): sext\\. * check-output-pattern(4): trunc\\.4 - * check-output-pattern(6): lsr\\..*\\$6 + * check-output-pattern(4): lsr\\..*\\$6 */ diff --git a/validation/optim/bitfield-store-loads.c b/validation/optim/bitfield-store-loads.c index dc625131..f946715b 100644 --- a/validation/optim/bitfield-store-loads.c +++ b/validation/optim/bitfield-store-loads.c @@ -1,6 +1,6 @@ struct s { - char :2; - char f:3; + unsigned char :2; + unsigned char f:3; }; int foo(struct s s, int a) diff --git a/validation/optim/sext.c b/validation/optim/sext.c index 719730d5..3769a05c 100644 --- a/validation/optim/sext.c +++ b/validation/optim/sext.c @@ -6,10 +6,9 @@ int sext(int x) /* * check-name: sext * check-command: test-linearize -Wno-decl $file - * check-known-to-fail * * check-output-ignore - * check-output-contains: sext\\.$27 - * check-output-excludes: asr\\. - * check-output-excludes: shl\\. + * check-output-excludes: sext\\. + * check-output-contains: asr\\.32 + * check-output-contains: shl\\.32 */ diff --git a/validation/optim/trunc-or-shl.c b/validation/optim/trunc-or-shl.c index 70d8bd1d..8660d0f0 100644 --- a/validation/optim/trunc-or-shl.c +++ b/validation/optim/trunc-or-shl.c @@ -1,3 +1,6 @@ +// because of the cast to char, the fist arg should be eliminated +// and the whole reduced to TRUNC(%arg2, 8) + char foo(int a, int b) { return (a << 8) | b; @@ -9,5 +12,6 @@ char foo(int a, int b) * check-known-to-fail * * check-output-ignore - * check-output-contains: ret\\..*%arg2 + * check-output-excludes: %arg1 + * check-output-contains: trunc\\..*%arg2 */ |
