diff options
| author | Christopher Li <sparse@chrisli.org> | 2017-08-28 21:30:38 -0400 |
|---|---|---|
| committer | Christopher Li <sparse@chrisli.org> | 2017-08-28 21:30:38 -0400 |
| commit | 958c11c35d98417eb6b948bffe2dffed14eb3320 (patch) | |
| tree | e375d1d9411afd3a6ee3fe88a56eb73d0d7b53b1 /validation | |
| parent | 9151ef493c72dde543cc14ee09da212be04e6f4b (diff) | |
| parent | 4d963a28d371ce75f65a70aa29f14cec5f08d8ff (diff) | |
| download | sparse-dev-958c11c35d98417eb6b948bffe2dffed14eb3320.tar.gz | |
Merge remote-tracking branch 'luc/constexpr-v4' into master
Diffstat (limited to 'validation')
| -rw-r--r-- | validation/constexpr-addr-of-static-member.c | 26 | ||||
| -rw-r--r-- | validation/constexpr-addr-of-static.c | 36 | ||||
| -rw-r--r-- | validation/constexpr-binop.c | 33 | ||||
| -rw-r--r-- | validation/constexpr-cast.c | 25 | ||||
| -rw-r--r-- | validation/constexpr-compound-literal.c | 19 | ||||
| -rw-r--r-- | validation/constexpr-conditional.c | 34 | ||||
| -rw-r--r-- | validation/constexpr-init.c | 60 | ||||
| -rw-r--r-- | validation/constexpr-labelref.c | 14 | ||||
| -rw-r--r-- | validation/constexpr-offsetof.c | 21 | ||||
| -rw-r--r-- | validation/constexpr-pointer-arith.c | 28 | ||||
| -rw-r--r-- | validation/constexpr-pointer-cast.c | 13 | ||||
| -rw-r--r-- | validation/constexpr-preop.c | 29 | ||||
| -rw-r--r-- | validation/constexpr-pure-builtin.c | 23 | ||||
| -rw-r--r-- | validation/constexpr-string.c | 9 | ||||
| -rw-r--r-- | validation/constexpr-types-compatible-p.c | 8 |
15 files changed, 378 insertions, 0 deletions
diff --git a/validation/constexpr-addr-of-static-member.c b/validation/constexpr-addr-of-static-member.c new file mode 100644 index 00000000..f944f213 --- /dev/null +++ b/validation/constexpr-addr-of-static-member.c @@ -0,0 +1,26 @@ +struct A { + int a; + int b[2]; +}; + +struct B { + int c; + struct A d; +}; + +static struct B a= {1, {1, {1, 1}}}; + +static int *b = &a.d.a; // OK +static int *c = &(&a.d)->a; // OK +static int *d = a.d.b; // OK +static int *e = (&a.d)->b; // OK +static int *f = &a.d.b[1]; // OK +static int *g = &(&a.d)->b[1]; // OK + +/* + * check-name: address of static object's member constness verification. + * check-command: sparse -Wconstexpr-not-const $file + * + * check-error-start + * check-error-end + */ diff --git a/validation/constexpr-addr-of-static.c b/validation/constexpr-addr-of-static.c new file mode 100644 index 00000000..a3af99ae --- /dev/null +++ b/validation/constexpr-addr-of-static.c @@ -0,0 +1,36 @@ +static int a = 1; +static int b[2] = {1, 1}; +static void c(void) {} + +static int *d = &a; // OK +static int *e = d; // KO +static int *f = b; // OK + +static void (*g)(void) = c; // OK +static void (*h)(void) = &c; // OK + +static int *i = &*&a; // OK +static int *j = &*b; // OK +static int *k = &*d; // KO + + +static void l(void) { + int a = 1; + static int *b = &a; // KO +} + +static void m(void) { + static int a = 1; + static int *b = &a; // OK +} + +/* + * check-name: address of static object constness verification. + * check-command: sparse -Wconstexpr-not-const $file + * + * check-error-start +constexpr-addr-of-static.c:6:17: warning: non-constant initializer for static object +constexpr-addr-of-static.c:14:19: warning: non-constant initializer for static object +constexpr-addr-of-static.c:19:26: warning: non-constant initializer for static object + * check-error-end + */ diff --git a/validation/constexpr-binop.c b/validation/constexpr-binop.c new file mode 100644 index 00000000..85a88e3c --- /dev/null +++ b/validation/constexpr-binop.c @@ -0,0 +1,33 @@ +static int a[] = { + [0 + 0] = 0, // OK + [0 + 0.] = 0, // KO + [(void*)0 + 0] = 0, // KO + [0 + __builtin_choose_expr(0, 0, 0)] = 0, // OK + [0 + __builtin_choose_expr(0, 0., 0)] = 0, // OK + [0 + __builtin_choose_expr(0, 0, 0.)] = 0, // KO + [0 < 0] = 0, // OK + [0 < 0.] = 0, // KO + [0 < __builtin_choose_expr(0, 0, 0)] = 0, // OK + [0 < __builtin_choose_expr(0, 0., 0)] = 0, // OK + [0 < __builtin_choose_expr(0, 0, 0.)] = 0, // KO + [0 && 0] = 0, // OK + [0 && 0.] = 0, // KO + [0 && __builtin_choose_expr(0, 0, 0)] = 0, // OK + [0 && __builtin_choose_expr(0, 0., 0)] = 0, // OK + [0 && __builtin_choose_expr(0, 0, 0.)] = 0, // KO + [0 + __builtin_types_compatible_p(int, float)] = 0, // OK +}; + +/* + * check-name: Expression constness propagation in binops and alike + * + * check-error-start +constexpr-binop.c:3:12: error: bad constant expression +constexpr-binop.c:4:19: error: bad integer constant expression +constexpr-binop.c:7:12: error: bad constant expression +constexpr-binop.c:9:12: error: bad integer constant expression +constexpr-binop.c:12:12: error: bad integer constant expression +constexpr-binop.c:14:12: error: bad integer constant expression +constexpr-binop.c:17:12: error: bad integer constant expression + * check-error-end + */ diff --git a/validation/constexpr-cast.c b/validation/constexpr-cast.c new file mode 100644 index 00000000..27069614 --- /dev/null +++ b/validation/constexpr-cast.c @@ -0,0 +1,25 @@ +static int a[] = { + [(int)0] = 0, // OK + [(int)(int)0] = 0, // OK + [(int)0.] = 0, // OK + [(int)(int)0.] = 0, // OK + [(int)__builtin_choose_expr(0, 0, 0)] = 0, // OK + [(int)__builtin_choose_expr(0, 0, 0.)] = 0, // OK + + [(int)(float)0] = 0, // KO + [(int)(float)0.] = 0, // KO + + [(int)(void*)0] = 0, // KO + [(int)(void*)0.] = 0, // KO + +}; +/* + * check-name: Expression constness propagation in casts + * + * check-error-start +constexpr-cast.c:9:11: error: bad integer constant expression +constexpr-cast.c:10:11: error: bad integer constant expression +constexpr-cast.c:12:11: error: bad integer constant expression +constexpr-cast.c:13:11: error: bad integer constant expression + * check-error-end + */ diff --git a/validation/constexpr-compound-literal.c b/validation/constexpr-compound-literal.c new file mode 100644 index 00000000..d7f21ad7 --- /dev/null +++ b/validation/constexpr-compound-literal.c @@ -0,0 +1,19 @@ +static int *a = &(int){ 1 }; // OK +static int *b = &(int){ *a }; // KO + +static void foo(void) +{ + int *b = &(int){ 1 }; // OK + int *c = &(int){ *a }; // OK + static int *d = &(int){ 1 }; // KO +} + +/* + * check-name: compound literal address constness verification + * check-command: sparse -Wconstexpr-not-const $file + * + * check-error-start +constexpr-compound-literal.c:2:25: warning: non-constant initializer for static object +constexpr-compound-literal.c:8:27: warning: non-constant initializer for static object + * check-error-end + */ diff --git a/validation/constexpr-conditional.c b/validation/constexpr-conditional.c new file mode 100644 index 00000000..a3331b3e --- /dev/null +++ b/validation/constexpr-conditional.c @@ -0,0 +1,34 @@ +static int a[] = { + [0 ? : 0] = 0, // OK + [1 ? : 0] = 0, // OK + [0 ? 0 : 0] = 0, // OK + [1 ? 0 : 0] = 0, // OK + [0 ? 0 : __builtin_choose_expr(0, 0, 0)] = 0, // OK + [1 ? __builtin_choose_expr(0, 0, 0) : 0] = 0, // OK + [0 ? __builtin_choose_expr(0, 0, 0) : 0] = 0, // OK + [1 ? 1 : __builtin_choose_expr(0, 0, 0)] = 0, // OK + [__builtin_choose_expr(0, 0, 0) ? : 0] = 0, // OK + [__builtin_choose_expr(0, 0, 1) ? : 0] = 0, // OK + [0. ? : 0] = 0, // KO + [0 ? 0. : 0] = 0, // KO + [1 ? : 0.] = 0, // KO + [__builtin_choose_expr(0, 0., 0) ? : 0] = 0, // OK + [__builtin_choose_expr(0, 0, 0.) ? : 0] = 0, // KO + [0 ? __builtin_choose_expr(0, 0., 0) : 0] = 0, // OK + [0 ? __builtin_choose_expr(0, 0, 0.) : 0] = 0, // KO + [1 ? 0 : __builtin_choose_expr(0, 0., 0)] = 0, // OK + [1 ? 0 : __builtin_choose_expr(0, 0, 0.)] = 0, // KO +}; + +/* + * check-name: Expression constness propagation in conditional expressions + * + * check-error-start +constexpr-conditional.c:12:13: error: bad constant expression +constexpr-conditional.c:13:19: error: bad constant expression +constexpr-conditional.c:14:12: error: bad constant expression +constexpr-conditional.c:16:42: error: bad constant expression +constexpr-conditional.c:18:48: error: bad constant expression +constexpr-conditional.c:20:14: error: bad constant expression + * check-error-end + */ diff --git a/validation/constexpr-init.c b/validation/constexpr-init.c new file mode 100644 index 00000000..d7e7a450 --- /dev/null +++ b/validation/constexpr-init.c @@ -0,0 +1,60 @@ +static int a = 1; // OK +static int b[2] = {1, 1}; // OK +static void c(void) {} + +struct A { + int a; + int b[2]; +}; + +struct B { + int c; + struct A d; +}; + +static struct B d= {1, {1, {1, 1}}}; // OK +static struct B e= {a, {1, {1, 1}}}; // KO +static struct B f= {1, {a, {1, 1}}}; // KO +static struct B g= {1, {1, {a, 1}}}; // KO +static struct B h= {1, {1, {1, a}}}; // KO +static struct B i= {.c = 1, .d = {.a = 1, .b = {1, 1}}}; // OK +static struct B j= {.c = a, .d = {.a = 1, .b = {1, 1}}}; // KO +static struct B k= {.c = 1, .d = {.a = a, .b = {1, 1}}}; // KO +static struct B l= {.c = 1, .d = {.a = 1, .b = {a, 1}}}; // KO +static struct B m= {.c = 1, .d = {.a = 1, .b = {1, a}}}; // KO + +static int n[] = {a, 1}; // KO +static int o[] = {1, a}; // KO +static int p[] = {[0] = a, [1] = 1}; // KO +static int q[] = {[0] = 1, [1] = a}; // KO + +static void r(void) { + int a = 0; + int b = a; // OK +} + +static void s(void) { + int a = 1; + static int b = a; // KO +} + +/* + * check-name: static storage object initializer constness verification. + * check-command: sparse -Wconstexpr-not-const $file + * + * check-error-start +constexpr-init.c:16:21: warning: non-constant initializer for static object +constexpr-init.c:17:25: warning: non-constant initializer for static object +constexpr-init.c:18:29: warning: non-constant initializer for static object +constexpr-init.c:19:32: warning: non-constant initializer for static object +constexpr-init.c:21:26: warning: non-constant initializer for static object +constexpr-init.c:22:40: warning: non-constant initializer for static object +constexpr-init.c:23:49: warning: non-constant initializer for static object +constexpr-init.c:24:52: warning: non-constant initializer for static object +constexpr-init.c:26:19: warning: non-constant initializer for static object +constexpr-init.c:27:22: warning: non-constant initializer for static object +constexpr-init.c:28:25: warning: non-constant initializer for static object +constexpr-init.c:29:34: warning: non-constant initializer for static object +constexpr-init.c:38:24: warning: non-constant initializer for static object + * check-error-end + */ diff --git a/validation/constexpr-labelref.c b/validation/constexpr-labelref.c new file mode 100644 index 00000000..15b5293a --- /dev/null +++ b/validation/constexpr-labelref.c @@ -0,0 +1,14 @@ +static void a(void) +{ +label1: + ; + static void *b = &&label1; +} + +/* + * check-name: label reference constness verification. + * check-command: sparse -Wconstexpr-not-const $file + * + * check-error-start + * check-error-end + */ diff --git a/validation/constexpr-offsetof.c b/validation/constexpr-offsetof.c new file mode 100644 index 00000000..d1697b0c --- /dev/null +++ b/validation/constexpr-offsetof.c @@ -0,0 +1,21 @@ +struct A { + int a[1]; + int b; +}; + +extern int c; + +static int o[] = { + [__builtin_offsetof(struct A, b)] = 0, // OK + [__builtin_offsetof(struct A, a[0])] = 0, // OK + [__builtin_offsetof(struct A, a[0*0])] = 0, // OK + [__builtin_offsetof(struct A, a[c])] = 0 // KO +}; + +/* + * check-name: __builtin_offsetof() constness verification. + * + * check-error-start +constexpr-offsetof.c:12:39: error: bad constant expression + * check-error-end + */ diff --git a/validation/constexpr-pointer-arith.c b/validation/constexpr-pointer-arith.c new file mode 100644 index 00000000..a9220280 --- /dev/null +++ b/validation/constexpr-pointer-arith.c @@ -0,0 +1,28 @@ +static int a = 1; +static int b[2] = {1, 1}; + +static int *c = &b[1]; // OK +static int *d = (int*)0 + 1; // OK +static int *e = &b[1] + 1; // OK +static int *f = b + 1; // OK +static int *g = d + 1; // KO +static int *h = &a + 1; // OK +static int *i = &b[1] + 1; // OK +static int *j = b + 1; // OK +static int *k = d + 1; // KO +static int *l = &*&b[1]; // OK +static int *m = &*(&a + 1); // OK +static int *n = &*(&b[1] + 1); // OK +static int *o = &*(b + 1); // OK +static int *p = &*(d + 1); // KO + +/* + * check-name: pointer arithmetic constness verification. + * check-command: sparse -Wconstexpr-not-const $file + * + * check-error-start +constexpr-pointer-arith.c:8:19: warning: non-constant initializer for static object +constexpr-pointer-arith.c:12:19: warning: non-constant initializer for static object +constexpr-pointer-arith.c:17:22: warning: non-constant initializer for static object + * check-error-end + */ diff --git a/validation/constexpr-pointer-cast.c b/validation/constexpr-pointer-cast.c new file mode 100644 index 00000000..d19c1082 --- /dev/null +++ b/validation/constexpr-pointer-cast.c @@ -0,0 +1,13 @@ +static int *a = (int*)0; // OK +static int b = 0; +static int *c = (int*)b; // KO + + +/* + * check-name: integer literal cast to pointer type constness verification. + * check-command: sparse -Wconstexpr-not-const $file + * + * check-error-start +constexpr-pointer-cast.c:3:18: warning: non-constant initializer for static object + * check-error-end + */ diff --git a/validation/constexpr-preop.c b/validation/constexpr-preop.c new file mode 100644 index 00000000..5d869da4 --- /dev/null +++ b/validation/constexpr-preop.c @@ -0,0 +1,29 @@ +static int a[] = { + [+0] = 0, // OK + [+__builtin_choose_expr(0, 0, 0)] = 0, // OK + [+0.] = 0, // KO + [+__builtin_choose_expr(0, 0, 0.)] = 0, // KO + [-0] = 0, // OK + [-__builtin_choose_expr(0, 0, 0)] = 0, // OK + [-0.] = 0, // KO + [-__builtin_choose_expr(0, 0, 0.)] = 0, // KO + [~0] = 0, // OK + [~__builtin_choose_expr(0, 0, 0)] = 0, // OK + [!0] = 0, // OK + [!__builtin_choose_expr(0, 0, 0)] = 0, // OK + [!0.] = 0, // KO + [!__builtin_choose_expr(0, 0, 0.)] = 0, // KO +}; + +/* + * check-name: Expression constness propagation in preops + * + * check-error-start +constexpr-preop.c:4:5: error: bad constant expression +constexpr-preop.c:5:33: error: bad constant expression +constexpr-preop.c:8:4: error: bad constant expression +constexpr-preop.c:9:4: error: bad constant expression +constexpr-preop.c:14:4: error: bad integer constant expression +constexpr-preop.c:15:4: error: bad integer constant expression + * check-error-end + */ diff --git a/validation/constexpr-pure-builtin.c b/validation/constexpr-pure-builtin.c new file mode 100644 index 00000000..f4cd67ed --- /dev/null +++ b/validation/constexpr-pure-builtin.c @@ -0,0 +1,23 @@ +// requires constant integer expressions +static int bar[] = { + [__builtin_bswap16(0x1234)] = 0, // OK + [__builtin_bswap32(0x1234)] = 0, // OK + [__builtin_bswap64(0x1234)] = 0, // OK +}; + +// requires constant integers +static int foo(unsigned long long a) +{ + switch (a) { + case __builtin_bswap16(1 << 8): + case __builtin_bswap32(2L << 24): + case __builtin_bswap64(3LL << 56): + return 0; + default: + return 1; + } +} + +/* + * check-name: constness of pure/const builtins + */ diff --git a/validation/constexpr-string.c b/validation/constexpr-string.c new file mode 100644 index 00000000..e641a83e --- /dev/null +++ b/validation/constexpr-string.c @@ -0,0 +1,9 @@ +static char *a = "foobar"; // OK + +/* + * check-name: string literal constness verification. + * check-command: sparse -Wconstexpr-not-const $file + * + * check-error-start + * check-error-end + */ diff --git a/validation/constexpr-types-compatible-p.c b/validation/constexpr-types-compatible-p.c new file mode 100644 index 00000000..1969bf3b --- /dev/null +++ b/validation/constexpr-types-compatible-p.c @@ -0,0 +1,8 @@ +static int a[] = {[__builtin_types_compatible_p(int, int)] = 0}; + +/* + * check-name: __builtin_types_compatible_p() constness verification. + * + * check-error-start + * check-error-end + */ |
