aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-01-29 12:34:09 +0100
committerChristopher Li <sparse@chrisli.org>2017-02-13 09:34:45 +0800
commit7e9d18754cf8ebc6bc24f4d744720282d62531ad (patch)
tree850ccf8465e50ac50a23d776a62d4f74159a6105 /validation
parent05adbae426c87e6f644ebb7eca95a2d66a190048 (diff)
downloadsparse-dev-7e9d18754cf8ebc6bc24f4d744720282d62531ad.tar.gz
validate expression's type in conditionals
This wasn't done yet, in particular void values was accepted inside if statements, which lead to strange situations after linearization. Implement this simply by calling the newly created is_scalar_type() in evaluate_conditional() and issuing an appropriate diagnostic when the check fail. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
Diffstat (limited to 'validation')
-rw-r--r--validation/conditional-type.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/validation/conditional-type.c b/validation/conditional-type.c
new file mode 100644
index 00000000..a14c05ec
--- /dev/null
+++ b/validation/conditional-type.c
@@ -0,0 +1,99 @@
+extern void afun(void);
+extern void vcond(void);
+static int array[3];
+
+struct state {
+ int nr:2;
+};
+
+enum number {
+ zero,
+ one,
+ two,
+ many,
+};
+
+static int bad_if(struct state s)
+{
+ if (vcond()) return 1;
+ if (s) return 1;
+ return 0;
+}
+static void bad_if2(int *a, int *b)
+{
+ if (vcond()) *a = 1;
+ *b = 0;
+}
+static int bad_sel(struct state s)
+{
+ return vcond() ? 1 : 0;
+ return s ? 1 : 0;
+}
+static int bad_loop_void(void)
+{
+ while (vcond())
+ ;
+ for (;vcond();)
+ ;
+ do
+ ;
+ while (vcond());
+ return 0;
+}
+
+
+static int good_if_int(int a, _Bool b, long c, unsigned char d)
+{
+ if (a) return 1;
+ if (b) return 1;
+ if (c) return 1;
+ if (d) return 1;
+ return 0;
+}
+static int good_if_float(float a, double b)
+{
+ if (a) return 1;
+ if (b) return 1;
+ return 0;
+}
+static int good_if_enum(void)
+{
+ if (many) return 1;
+ return 0;
+}
+static int good_if_bitfield(struct state s, struct state *p)
+{
+ if (s.nr) return 1;
+ if (p->nr) return 1;
+ return 0;
+}
+static int good_if_ptr(void *ptr)
+{
+ if (ptr) return 1;
+ if (array) return 1;
+ if (afun) return 1;
+ return 0;
+}
+
+/*
+ * check-name: conditional-type
+ *
+ * check-error-start
+conditional-type.c:18:18: error: incorrect type in conditional
+conditional-type.c:18:18: got void
+conditional-type.c:19:13: error: incorrect type in conditional
+conditional-type.c:19:13: got struct state s
+conditional-type.c:24:18: error: incorrect type in conditional
+conditional-type.c:24:18: got void
+conditional-type.c:29:21: error: incorrect type in conditional
+conditional-type.c:29:21: got void
+conditional-type.c:30:16: error: incorrect type in conditional
+conditional-type.c:30:16: got struct state s
+conditional-type.c:34:21: error: incorrect type in conditional
+conditional-type.c:34:21: got void
+conditional-type.c:36:20: error: incorrect type in conditional
+conditional-type.c:36:20: got void
+conditional-type.c:40:21: error: incorrect type in conditional
+conditional-type.c:40:21: got void
+ * check-error-end
+ */