aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--Documentation/TODO.md29
-rw-r--r--Documentation/release-notes/v0.6.3.rst5
-rw-r--r--Makefile2
-rw-r--r--builtin.c114
-rw-r--r--evaluate.c6
-rw-r--r--options.c3
-rw-r--r--options.h1
-rw-r--r--predefine.c7
-rw-r--r--sparse.16
-rw-r--r--symbol.c12
-rw-r--r--symbol.h2
-rw-r--r--validation/builtin-arith.c31
-rw-r--r--validation/builtin-atomic-clear.c15
-rw-r--r--validation/builtin-sync-fetch.c24
-rw-r--r--validation/crash-undef-in-parens.c9
-rw-r--r--validation/flex-array-nested.c4
-rw-r--r--validation/linear/bitfield-sign-default.c13
-rw-r--r--validation/linear/bitfield-sign-signed.c13
-rw-r--r--validation/linear/bitfield-sign-unsigned.c13
-rw-r--r--validation/linear/bitfield-size.c10
-rw-r--r--validation/optim/bitfield-size.c15
-rw-r--r--validation/optim/bitfield-store-loads.c4
-rw-r--r--validation/optim/sext.c7
-rw-r--r--validation/optim/trunc-or-shl.c6
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
diff --git a/Makefile b/Makefile
index f7da0ded..31366446 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.6.3-rc1
+VERSION=0.6.3
########################################################################
# The following variables can be overwritten from the command line
diff --git a/builtin.c b/builtin.c
index 26b612dc..acc49871 100644
--- a/builtin.c
+++ b/builtin.c
@@ -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 },
{ }
};
diff --git a/evaluate.c b/evaluate.c
index 3ff76fa8..43a61169 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -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");
diff --git a/options.c b/options.c
index e2a0717a..17da5f36 100644
--- a/options.c
+++ b/options.c
@@ -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, },
diff --git a/options.h b/options.h
index 70c6ce9b..0aec8764 100644
--- a/options.h
+++ b/options.h
@@ -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");
diff --git a/sparse.1 b/sparse.1
index ed528fd1..430b3710 100644
--- a/sparse.1
+++ b/sparse.1
@@ -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.
diff --git a/symbol.c b/symbol.c
index 5e7f0796..1a083fb8 100644
--- a/symbol.c
+++ b/symbol.c
@@ -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, }
};
diff --git a/symbol.h b/symbol.h
index e75ea3ab..5c5a7f12 100644
--- a/symbol.h
+++ b/symbol.h
@@ -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
*/