diff options
| -rw-r--r-- | evaluate.c | 32 | ||||
| -rw-r--r-- | validation/vla-sizeof-ice.c | 19 | ||||
| -rw-r--r-- | validation/vla-sizeof0.c | 20 | ||||
| -rw-r--r-- | validation/vla-sizeof1.c | 21 | ||||
| -rw-r--r-- | validation/vla-sizeof2.c | 21 | ||||
| -rw-r--r-- | validation/vla-sizeof3.c | 21 | ||||
| -rw-r--r-- | validation/vla-sizeof4.c | 22 |
7 files changed, 156 insertions, 0 deletions
@@ -2211,6 +2211,38 @@ static struct symbol *evaluate_sizeof(struct expression *expr) size = bits_in_char; } + if (is_array_type(type) && size < 0) { // VLA, 1-dimension only + struct expression *base, *size; + struct symbol *base_type; + + if (type->type == SYM_NODE) + type = type->ctype.base_type; // strip the SYM_NODE + base_type = get_base_type(type); + if (!base_type) + goto error; + if (base_type->bit_size <= 0) { + base = alloc_expression(expr->pos, EXPR_SIZEOF); + base->cast_type = base_type; + if (!evaluate_sizeof(base)) + goto error; + } else { + base = alloc_expression(expr->pos, EXPR_VALUE); + base->value = bits_to_bytes(base_type->bit_size); + base->ctype = size_t_ctype; + } + size = alloc_expression(expr->pos, EXPR_CAST); + size->cast_type = size_t_ctype; + size->cast_expression = type->array_size; + if (!evaluate_expression(size)) + goto error; + expr->left = size; + expr->right = base; + expr->type = EXPR_BINOP; + expr->op = '*'; + return expr->ctype = size_t_ctype; + } + +error: if ((size < 0) || (size & (bits_in_char - 1))) expression_error(expr, "cannot size expression"); diff --git a/validation/vla-sizeof-ice.c b/validation/vla-sizeof-ice.c new file mode 100644 index 00000000..472da6a4 --- /dev/null +++ b/validation/vla-sizeof-ice.c @@ -0,0 +1,19 @@ +// credit goes to Martin Uecker for the awesome ICE_P macro + +#define ICE_P(x) \ + (__builtin_types_compatible_p(typeof(0?((void*)((long)(x)*0l)):(int*)1),int*)) + +#define T(x) __builtin_choose_expr(ICE_P(x), 1, 0) +#define TEST(x, r) _Static_assert(T(x) == r, #x " => " #r) + +static void test(int n) +{ + char foo[n++]; + + TEST(sizeof(foo), 0); +} + +/* + * check-name: vla-sizeof-ice + * check-command: sparse -Wno-vla $file + */ diff --git a/validation/vla-sizeof0.c b/validation/vla-sizeof0.c new file mode 100644 index 00000000..a58fd300 --- /dev/null +++ b/validation/vla-sizeof0.c @@ -0,0 +1,20 @@ +#define N 2 +#define T int + +static unsigned int foo(int x) +{ + T a[(1,N)]; + + return sizeof(a) == (N * sizeof(T)); +} + +/* + * check-name: vla-sizeof cte,cte + * check-command: test-linearize -Wvla $file + * + * check-output-ignore + * check-output-contains: ret\\.32 *\\$1 + * + * check-error-start + * check-error-end + */ diff --git a/validation/vla-sizeof1.c b/validation/vla-sizeof1.c new file mode 100644 index 00000000..ed7f5d4e --- /dev/null +++ b/validation/vla-sizeof1.c @@ -0,0 +1,21 @@ +#define N 2 +#define T int + +static unsigned int foo(int x) +{ + T a[(x,N)]; + + return sizeof(a) == (N * sizeof(T)); +} + +/* + * check-name: vla-sizeof var,cte + * check-command: test-linearize -Wvla $file + * + * check-output-ignore + * check-output-contains: ret\\.32 *\\$1 + * + * check-error-start +vla-sizeof1.c:6:15: warning: Variable length array is used. + * check-error-end + */ diff --git a/validation/vla-sizeof2.c b/validation/vla-sizeof2.c new file mode 100644 index 00000000..57927d16 --- /dev/null +++ b/validation/vla-sizeof2.c @@ -0,0 +1,21 @@ +#define N 2 +#define T int + +static unsigned long foo(int x) +{ + T a[x]; + + return sizeof(a) == (x * sizeof(T)); +} + +/* + * check-name: vla-sizeof var + * check-command: test-linearize -Wvla $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + * + * check-error-start +vla-sizeof2.c:6:13: warning: Variable length array is used. + * check-error-end + */ diff --git a/validation/vla-sizeof3.c b/validation/vla-sizeof3.c new file mode 100644 index 00000000..21edb007 --- /dev/null +++ b/validation/vla-sizeof3.c @@ -0,0 +1,21 @@ +#define N 2UL +#define T int + +static unsigned long foo(int x) +{ + T a[x][N]; + + return sizeof(a) == (N * x * sizeof(T)); +} + +/* + * check-name: vla-sizeof var X cte + * check-command: test-linearize -Wvla $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + * + * check-error-start +vla-sizeof3.c:6:13: warning: Variable length array is used. + * check-error-end + */ diff --git a/validation/vla-sizeof4.c b/validation/vla-sizeof4.c new file mode 100644 index 00000000..e7478613 --- /dev/null +++ b/validation/vla-sizeof4.c @@ -0,0 +1,22 @@ +#define N 2 +#define T int + +static unsigned long foo(int x, int y) +{ + T a[x][y]; + + return sizeof(a) == (x * (y * sizeof(T))); +} + +/* + * check-name: vla-sizeof var X var + * check-command: test-linearize -Wvla $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + * + * check-error-start +vla-sizeof4.c:6:16: warning: Variable length array is used. +vla-sizeof4.c:6:13: warning: Variable length array is used. + * check-error-end + */ |
