aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation
diff options
authorChristopher Li <sparse@chrisli.org>2017-08-28 21:30:38 -0400
committerChristopher Li <sparse@chrisli.org>2017-08-28 21:30:38 -0400
commit958c11c35d98417eb6b948bffe2dffed14eb3320 (patch)
treee375d1d9411afd3a6ee3fe88a56eb73d0d7b53b1 /validation
parent9151ef493c72dde543cc14ee09da212be04e6f4b (diff)
parent4d963a28d371ce75f65a70aa29f14cec5f08d8ff (diff)
downloadsparse-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.c26
-rw-r--r--validation/constexpr-addr-of-static.c36
-rw-r--r--validation/constexpr-binop.c33
-rw-r--r--validation/constexpr-cast.c25
-rw-r--r--validation/constexpr-compound-literal.c19
-rw-r--r--validation/constexpr-conditional.c34
-rw-r--r--validation/constexpr-init.c60
-rw-r--r--validation/constexpr-labelref.c14
-rw-r--r--validation/constexpr-offsetof.c21
-rw-r--r--validation/constexpr-pointer-arith.c28
-rw-r--r--validation/constexpr-pointer-cast.c13
-rw-r--r--validation/constexpr-preop.c29
-rw-r--r--validation/constexpr-pure-builtin.c23
-rw-r--r--validation/constexpr-string.c9
-rw-r--r--validation/constexpr-types-compatible-p.c8
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
+ */