aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2022-05-31 13:53:18 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2022-05-31 13:53:18 +0200
commit56afb504c0b917a2563b44fabe2f1e92e4c14287 (patch)
tree73cca4ee011daee4ab40a7d19db2bb91b4307682
parent5a0004b591e311cb840633144087dee6ecdade17 (diff)
parent3d1d65bfe6dad089b9c2a8d69f36ba5301a9509c (diff)
downloadsparse-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.c8
-rw-r--r--expression.c10
-rw-r--r--options.c13
-rw-r--r--validation/builtin-objsize-self-init.c11
-rw-r--r--validation/char-constant-signed.c9
-rw-r--r--validation/char-constant-unsigned.c9
6 files changed, 59 insertions, 1 deletions
diff --git a/builtin.c b/builtin.c
index 8e1d2d7e..3a29c3ae 100644
--- a/builtin.c
+++ b/builtin.c
@@ -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;
diff --git a/options.c b/options.c
index b4684357..6ee4d878 100644
--- a/options.c
+++ b/options.c
@@ -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
+ */