diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2022-05-31 13:53:18 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2022-05-31 13:53:18 +0200 |
commit | 56afb504c0b917a2563b44fabe2f1e92e4c14287 (patch) | |
tree | 73cca4ee011daee4ab40a7d19db2bb91b4307682 | |
parent | 5a0004b591e311cb840633144087dee6ecdade17 (diff) | |
parent | 3d1d65bfe6dad089b9c2a8d69f36ba5301a9509c (diff) | |
download | sparse-56afb504c0b917a2563b44fabe2f1e92e4c14287.tar.gz |
Merge branch 'fixes' into master
* fix zero/sign extension of integer character constants
* handle clang's option "-meabi gnu"
* fix infinite loop when expanding __builtin_object_size() with self-init vars
-rw-r--r-- | builtin.c | 8 | ||||
-rw-r--r-- | expression.c | 10 | ||||
-rw-r--r-- | options.c | 13 | ||||
-rw-r--r-- | validation/builtin-objsize-self-init.c | 11 | ||||
-rw-r--r-- | validation/char-constant-signed.c | 9 | ||||
-rw-r--r-- | validation/char-constant-unsigned.c | 9 |
6 files changed, 59 insertions, 1 deletions
@@ -546,11 +546,19 @@ static int expand_object_size(struct expression *expr, int cost) // a deref is just intermediate variable // and so the offset needs to be zeroed. if (arg->op == '*') { + struct expression *parent = arg; arg = arg->unop; off = 0; switch (arg->type) { case EXPR_SYMBOL: arg = arg->symbol->initializer; + if (arg == parent) { + // stop at self-initialized vars + // and do not expand them. + arg = NULL; + val = -1; + break; + } continue; default: break; diff --git a/expression.c b/expression.c index 221d7780..efdaa367 100644 --- a/expression.c +++ b/expression.c @@ -427,8 +427,16 @@ struct token *primary_expression(struct token *token, struct expression **tree) case TOKEN_CHAR ... TOKEN_WIDE_CHAR_EMBEDDED_3: expr = alloc_expression(token->pos, EXPR_VALUE); expr->flags = CEF_SET_CHAR; - expr->ctype = token_type(token) < TOKEN_WIDE_CHAR ? &int_ctype : &long_ctype; get_char_constant(token, &expr->value); + + // TODO: handle 'u8', 'u' & 'U' prefixes. + if (token_type(token) < TOKEN_WIDE_CHAR) { + expr->ctype = &char_ctype; + cast_value(expr, &int_ctype, expr, expr->ctype); + expr->ctype = &int_ctype; + } else { + expr->ctype = wchar_ctype; + } token = token->next; break; @@ -687,6 +687,19 @@ static const struct flag mflags[] = { static char **handle_switch_m(char *arg, char **next) { + if (!strcmp(arg, "meabi") && next[1] && next[1][0] != '-') { + // clang has such an option with syntax: -meabi <arg> + // It's used by the kernel for armv7. + // GCC has the same option but with no argument. + // Parse it here to consume the possible argument. + static const char *valid[] = { "gnu", "4", "5", "default", NULL }; + int i; + for (i = 0; valid[i]; i++) { + if (!strcmp(next[1], valid[i])) + return ++next; + } + } + if (!strcmp(arg, "multiarch-dir")) { return handle_multiarch_dir(arg, next); } else { diff --git a/validation/builtin-objsize-self-init.c b/validation/builtin-objsize-self-init.c new file mode 100644 index 00000000..77e3da43 --- /dev/null +++ b/validation/builtin-objsize-self-init.c @@ -0,0 +1,11 @@ +static void f(void) +{ + void *param = param; + __builtin_object_size(param, 0); +} + +/* + * check-name: builtin-objsize-self-init + * check-timeout: + * check-error-end + */ diff --git a/validation/char-constant-signed.c b/validation/char-constant-signed.c new file mode 100644 index 00000000..be0fd5ce --- /dev/null +++ b/validation/char-constant-signed.c @@ -0,0 +1,9 @@ +int test(void) { return '\377' == -1; } + +/* + * check-name: char-constant-signed + * check-command: test-linearize -Wno-decl -fsigned-char $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/char-constant-unsigned.c b/validation/char-constant-unsigned.c new file mode 100644 index 00000000..d5642b16 --- /dev/null +++ b/validation/char-constant-unsigned.c @@ -0,0 +1,9 @@ +int test(void) { return '\377' == 255; } + +/* + * check-name: char-constant-unsigned + * check-command: test-linearize -Wno-decl -funsigned-char $file + * + * check-output-ignore + * check-output-returns: 1 + */ |