aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-29 17:09:10 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-30 03:45:53 +0200
commitd466a02815b8109ea007736590bdd97f5d0aeb2f (patch)
tree5dd27f9401831f45ab77c6c31591327ec52c45a5 /validation
parentfded889cd4b3e0b5eef95440d3f96723e76a78e9 (diff)
parent5d0c4d96bdf4ab5df4ef0e31ab433e605299aabd (diff)
downloadsparse-dev-d466a02815b8109ea007736590bdd97f5d0aeb2f.tar.gz
Merge branch 'fix-expand-asm' into tip
Currently, ASM operands aren't expanded or even evaluated. This causes Sparse to emit warnings about 'unknown expression' during the linearization of these operands if they contains, for example, calls to __builtin_compatible_types_p(). Note: the correct handling of ASM operands needs to make the distinction between 'memory' operands and 'normal' operands. For this, it is needed to look at the constraints and these are architecture specific. The patches in this series only consider the constraints m, v, o & Q as being for memory operands and, happily, these seems to cover most usage for the most common architectures. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'validation')
-rw-r--r--validation/asm-bad0.c41
-rw-r--r--validation/bad-type-twice0.c4
-rw-r--r--validation/bad-type-twice1.c6
-rw-r--r--validation/compare-null-to-int.c6
-rw-r--r--validation/cond_expr.c4
-rw-r--r--validation/conditional-type.c32
-rw-r--r--validation/enum-mismatch.c6
-rw-r--r--validation/eval/asm-degen.c36
-rw-r--r--validation/eval/asm-memop.c47
-rw-r--r--validation/expand/asm0.c23
-rw-r--r--validation/expand/compound-literal.c26
-rw-r--r--validation/linear/asm-memop.c23
-rw-r--r--validation/linear/compound-literal02.c1
-rw-r--r--validation/static_assert.c6
14 files changed, 228 insertions, 33 deletions
diff --git a/validation/asm-bad0.c b/validation/asm-bad0.c
new file mode 100644
index 00000000..aa9bf28d
--- /dev/null
+++ b/validation/asm-bad0.c
@@ -0,0 +1,41 @@
+extern char string[];
+extern int *var;
+
+static void templ(void)
+{
+ asm(string);
+}
+
+static void ocons(void)
+{
+ asm("template" : [out] string (var) : [in] "r" (0));
+}
+
+static void icons(void)
+{
+ asm("template" : [out] "=r" (var): [in] string (0));
+}
+
+static void oexpr(oid)
+{
+ asm("template" : [out] "=" (var[) : [in] "r" (0));
+}
+
+static void iexpr(void)
+{
+ asm("template" : [out] "=r" (var) : [in] "r" (var[));
+}
+
+/*
+ * check-name: asm-bad0
+ *
+ * check-error-start
+asm-bad0.c:6:13: error: string literal expected for inline asm
+asm-bad0.c:11:32: error: string literal expected for asm constraint
+asm-bad0.c:16:49: error: string literal expected for asm constraint
+asm-bad0.c:21:41: error: Expected ] at end of array dereference
+asm-bad0.c:21:41: error: got )
+asm-bad0.c:26:59: error: Expected ] at end of array dereference
+asm-bad0.c:26:59: error: got )
+ * check-error-end
+ */
diff --git a/validation/bad-type-twice0.c b/validation/bad-type-twice0.c
index 5d107a62..9e834d47 100644
--- a/validation/bad-type-twice0.c
+++ b/validation/bad-type-twice0.c
@@ -7,7 +7,7 @@ static int foo(a)
* check-name: bad-type-twice0
*
* check-error-start
-bad-type-twice0.c:3:16: error: incorrect type in conditional (non-scalar type)
-bad-type-twice0.c:3:16: got incomplete type a
+bad-type-twice0.c:3:16: error: non-scalar type in conditional:
+bad-type-twice0.c:3:16: incomplete type a
* check-error-end
*/
diff --git a/validation/bad-type-twice1.c b/validation/bad-type-twice1.c
index cc81662a..a9ba182c 100644
--- a/validation/bad-type-twice1.c
+++ b/validation/bad-type-twice1.c
@@ -9,8 +9,8 @@ static unsigned long foo(unsigned long val, void *ref)
* check-name: bad-type-twice1
*
* check-error-start
-bad-type-twice1.c:3:17: error: incompatible types for operation (>=)
-bad-type-twice1.c:3:17: left side has type unsigned long val
-bad-type-twice1.c:3:17: right side has type void *ref
+bad-type-twice1.c:3:17: error: incompatible types for operation (>=):
+bad-type-twice1.c:3:17: unsigned long val
+bad-type-twice1.c:3:17: void *ref
* check-error-end
*/
diff --git a/validation/compare-null-to-int.c b/validation/compare-null-to-int.c
index 08e556b3..336c724d 100644
--- a/validation/compare-null-to-int.c
+++ b/validation/compare-null-to-int.c
@@ -4,8 +4,8 @@ static unsigned int comparison = (void *)0 == 1;
* check-description: Sparse used to allow this.
*
* check-error-start
-compare-null-to-int.c:1:44: error: incompatible types for operation (==)
-compare-null-to-int.c:1:44: left side has type void *
-compare-null-to-int.c:1:44: right side has type int
+compare-null-to-int.c:1:44: error: incompatible types for operation (==):
+compare-null-to-int.c:1:44: void *
+compare-null-to-int.c:1:44: int
* check-error-end
*/
diff --git a/validation/cond_expr.c b/validation/cond_expr.c
index e55711cc..9b8105c1 100644
--- a/validation/cond_expr.c
+++ b/validation/cond_expr.c
@@ -13,7 +13,7 @@ int a(void)
* check-name: Two-argument conditional expression types
*
* check-error-start
-cond_expr.c:10:16: error: incompatible types for operation (~)
-cond_expr.c:10:16: argument has type double
+cond_expr.c:10:16: error: incompatible type for operation (~):
+cond_expr.c:10:16: double
* check-error-end
*/
diff --git a/validation/conditional-type.c b/validation/conditional-type.c
index 91267212..6e2da9b5 100644
--- a/validation/conditional-type.c
+++ b/validation/conditional-type.c
@@ -79,21 +79,21 @@ static int good_if_ptr(void *ptr)
* check-name: conditional-type
*
* check-error-start
-conditional-type.c:18:18: error: incorrect type in conditional (non-scalar type)
-conditional-type.c:18:18: got void
-conditional-type.c:19:13: error: incorrect type in conditional (non-scalar type)
-conditional-type.c:19:13: got struct state s
-conditional-type.c:24:18: error: incorrect type in conditional (non-scalar type)
-conditional-type.c:24:18: got void
-conditional-type.c:29:21: error: incorrect type in conditional (non-scalar type)
-conditional-type.c:29:21: got void
-conditional-type.c:30:16: error: incorrect type in conditional (non-scalar type)
-conditional-type.c:30:16: got struct state s
-conditional-type.c:34:21: error: incorrect type in conditional (non-scalar type)
-conditional-type.c:34:21: got void
-conditional-type.c:36:20: error: incorrect type in conditional (non-scalar type)
-conditional-type.c:36:20: got void
-conditional-type.c:40:21: error: incorrect type in conditional (non-scalar type)
-conditional-type.c:40:21: got void
+conditional-type.c:18:18: error: non-scalar type in conditional:
+conditional-type.c:18:18: void
+conditional-type.c:19:13: error: non-scalar type in conditional:
+conditional-type.c:19:13: struct state s
+conditional-type.c:24:18: error: non-scalar type in conditional:
+conditional-type.c:24:18: void
+conditional-type.c:29:21: error: non-scalar type in conditional:
+conditional-type.c:29:21: void
+conditional-type.c:30:16: error: non-scalar type in conditional:
+conditional-type.c:30:16: struct state s
+conditional-type.c:34:21: error: non-scalar type in conditional:
+conditional-type.c:34:21: void
+conditional-type.c:36:20: error: non-scalar type in conditional:
+conditional-type.c:36:20: void
+conditional-type.c:40:21: error: non-scalar type in conditional:
+conditional-type.c:40:21: void
* check-error-end
*/
diff --git a/validation/enum-mismatch.c b/validation/enum-mismatch.c
index 1bdb1d6c..a6e5d72d 100644
--- a/validation/enum-mismatch.c
+++ b/validation/enum-mismatch.c
@@ -12,8 +12,8 @@ static enum eb foo(enum ea a)
* check-command: sparse -Wenum-mismatch $file
*
* check-error-start
-enum-mismatch.c:7:16: warning: mixing different enum types
-enum-mismatch.c:7:16: unsigned int enum ea versus
-enum-mismatch.c:7:16: unsigned int enum eb
+enum-mismatch.c:7:16: warning: mixing different enum types:
+enum-mismatch.c:7:16: unsigned int enum ea
+enum-mismatch.c:7:16: unsigned int enum eb
* check-error-end
*/
diff --git a/validation/eval/asm-degen.c b/validation/eval/asm-degen.c
new file mode 100644
index 00000000..7bbed925
--- /dev/null
+++ b/validation/eval/asm-degen.c
@@ -0,0 +1,36 @@
+#ifdef __CHECKER__
+#define __percpu __attribute__((noderef))
+#else
+#define __percpu
+#endif
+
+static __percpu int var;
+static __percpu int arr[4];
+
+static void foo(void)
+{
+ asm("" :: "r" (var));
+}
+
+static void bar(void)
+{
+ asm("" :: "r" (arr));
+}
+
+static void baz(void)
+{
+ asm("" :: "m" (var));
+}
+
+static void qux(void)
+{
+ asm("" :: "m" (arr));
+}
+
+/*
+ * check-name: asm-degen
+ *
+ * check-error-start
+eval/asm-degen.c:12:24: warning: dereference of noderef expression
+ * check-error-end
+ */
diff --git a/validation/eval/asm-memop.c b/validation/eval/asm-memop.c
new file mode 100644
index 00000000..33ba0e5a
--- /dev/null
+++ b/validation/eval/asm-memop.c
@@ -0,0 +1,47 @@
+extern int g;
+
+void fo0(int *p) { asm volatile ("op %0" :: "p" (&g)); }
+void fo1(int *p) { asm volatile ("op %0" :: "m" (g)); }
+
+void fo2(int *p) { asm volatile ("op %0" :: "p" (p)); }
+void fo3(int *p) { asm volatile ("op %0" :: "m" (*p)); }
+
+/*
+ * check-name: eval-asm-memop
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+fo0:
+.L0:
+ <entry-point>
+ asm "op %0"
+ in: "p" (g)
+ ret
+
+
+fo1:
+.L2:
+ <entry-point>
+ asm "op %0"
+ in: "m" (g)
+ ret
+
+
+fo2:
+.L4:
+ <entry-point>
+ asm "op %0"
+ in: "p" (%arg1)
+ ret
+
+
+fo3:
+.L6:
+ <entry-point>
+ asm "op %0"
+ in: "m" (%arg1)
+ ret
+
+
+ * check-output-end
+ */
diff --git a/validation/expand/asm0.c b/validation/expand/asm0.c
new file mode 100644
index 00000000..568a4d19
--- /dev/null
+++ b/validation/expand/asm0.c
@@ -0,0 +1,23 @@
+static void foo(void)
+{
+ asm("" :: "i" (42 & 3));
+ asm("" :: "i" (__builtin_constant_p(0)));
+}
+
+/*
+ * check-name: expand-asm0
+ * check-command: test-linearize $file
+ *
+ * check-output-start
+foo:
+.L0:
+ <entry-point>
+ asm ""
+ in: "i" ($2)
+ asm ""
+ in: "i" ($1)
+ ret
+
+
+ * check-output-end
+ */
diff --git a/validation/expand/compound-literal.c b/validation/expand/compound-literal.c
new file mode 100644
index 00000000..034164bc
--- /dev/null
+++ b/validation/expand/compound-literal.c
@@ -0,0 +1,26 @@
+#define SAME_TYPE(A, B) \
+ __builtin_types_compatible_p(A, B)
+
+struct s {
+ int i;
+};
+
+static void foo(struct s *p)
+{
+ *p = (struct s) { .i = SAME_TYPE(int, int), };
+}
+
+/*
+ * check-name: compound-literal
+ * check-command: test-linearize $file
+ *
+ * check-output-start
+foo:
+.L0:
+ <entry-point>
+ store.32 $1 -> 0[%arg1]
+ ret
+
+
+ * check-output-end
+ */
diff --git a/validation/linear/asm-memop.c b/validation/linear/asm-memop.c
new file mode 100644
index 00000000..245c8d0f
--- /dev/null
+++ b/validation/linear/asm-memop.c
@@ -0,0 +1,23 @@
+static int foo(int *p)
+{
+ asm("op %0" : "=m" (p[0]));
+
+ return p[0];
+}
+
+/*
+ * check-name: linear-asm-memop
+ * check-command: test-linearize $file
+ *
+ * check-output-start
+foo:
+.L0:
+ <entry-point>
+ asm "op %0"
+ out: "=m" (%arg1)
+ load.32 %r4 <- 0[%arg1]
+ ret.32 %r4
+
+
+ * check-output-end
+ */
diff --git a/validation/linear/compound-literal02.c b/validation/linear/compound-literal02.c
index 87b98d76..6ed5809e 100644
--- a/validation/linear/compound-literal02.c
+++ b/validation/linear/compound-literal02.c
@@ -13,7 +13,6 @@ int bar(void)
* check-name: compound-literal02.c
* check-command: test-linearize -Wno-decl $file
*
- * check-known-to-fail
* check-output-ignore
* check-output-contains: ret\\..*\\$6
*/
diff --git a/validation/static_assert.c b/validation/static_assert.c
index d9e96294..dd5e0c08 100644
--- a/validation/static_assert.c
+++ b/validation/static_assert.c
@@ -61,11 +61,11 @@ static_assert.c:19:16: error: static assertion failed: "expected assertion failu
static_assert.c:22:16: error: bad constant expression
static_assert.c:25:16: error: bad constant expression
static_assert.c:27:16: error: bad constant expression
-static_assert.c:35:19: error: bad or missing string literal
+static_assert.c:35:19: error: string literal expected for _Static_assert()
static_assert.c:37:18: error: bad constant expression
-static_assert.c:52:19: error: bad or missing string literal
+static_assert.c:52:19: error: string literal expected for _Static_assert()
static_assert.c:53:16: error: Expected constant expression
static_assert.c:54:16: error: Expected constant expression
-static_assert.c:54:17: error: bad or missing string literal
+static_assert.c:54:17: error: string literal expected for _Static_assert()
* check-error-end
*/