aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-01-26 01:32:35 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-27 02:17:31 +0200
commit62308ab6a6025f8df926b8af009f68fbebe040b6 (patch)
treeb10a0f0132827654957be3562495336142e4626a
parentd765800ade9ccb195c1b45033573dcaeec4e3f46 (diff)
downloadsparse-62308ab6a6025f8df926b8af009f68fbebe040b6.tar.gz
asm: add test evaluation, expansion & linearization of ASM operands
ASM statements are quite complex. Add some tests to catch some potential errors. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--validation/asm-bad0.c41
-rw-r--r--validation/eval/asm-degen.c37
-rw-r--r--validation/eval/asm-memop.c48
-rw-r--r--validation/expand/asm0.c24
-rw-r--r--validation/linear/asm-memop.c24
5 files changed, 174 insertions, 0 deletions
diff --git a/validation/asm-bad0.c b/validation/asm-bad0.c
new file mode 100644
index 00000000..fcd9b1c4
--- /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: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 )
+asm-bad0.c:6:9: error: need constant string for inline asm
+asm-bad0.c:11:32: error: asm output constraint is not a string
+asm-bad0.c:16:49: error: asm input constraint is not a string
+ * check-error-end
+ */
diff --git a/validation/eval/asm-degen.c b/validation/eval/asm-degen.c
new file mode 100644
index 00000000..5f319159
--- /dev/null
+++ b/validation/eval/asm-degen.c
@@ -0,0 +1,37 @@
+#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-known-to-fail
+ *
+ * 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..9bbb3a30
--- /dev/null
+++ b/validation/eval/asm-memop.c
@@ -0,0 +1,48 @@
+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-known-to-fail
+ *
+ * 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..0664b622
--- /dev/null
+++ b/validation/expand/asm0.c
@@ -0,0 +1,24 @@
+static void foo(void)
+{
+ asm("" :: "i" (42 & 3));
+ asm("" :: "i" (__builtin_constant_p(0)));
+}
+
+/*
+ * check-name: expand-asm0
+ * check-command: test-linearize $file
+ * check-known-to-fail
+ *
+ * check-output-start
+foo:
+.L0:
+ <entry-point>
+ asm ""
+ in: "i" ($2)
+ asm ""
+ in: "i" ($1)
+ ret
+
+
+ * check-output-end
+ */
diff --git a/validation/linear/asm-memop.c b/validation/linear/asm-memop.c
new file mode 100644
index 00000000..97df98e2
--- /dev/null
+++ b/validation/linear/asm-memop.c
@@ -0,0 +1,24 @@
+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-known-to-fail
+ *
+ * check-output-start
+foo:
+.L0:
+ <entry-point>
+ asm "op %0"
+ out: "=m" (%arg1)
+ load.32 %r4 <- 0[%arg1]
+ ret.32 %r4
+
+
+ * check-output-end
+ */