summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-29 17:08:10 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-30 03:44:50 +0200
commit0ca5ee15e9836fca976479fef8d90594d1e97adb (patch)
tree40aeffa8be7e45c377546786a4de6c859ca121df
parentf4a90f9a6f569904165d48464615bf60d188fba4 (diff)
parent2c80708a7c053671c344fc23e561621bdbcbae4d (diff)
downloadsparse-0ca5ee15e9836fca976479fef8d90594d1e97adb.tar.gz
Merge branch 'fix-bad-linear' into tip
Expressions without a valid type should never be linearized since they have no (valid) type and haven't been expanded. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--linearize.c8
-rw-r--r--validation/eval-bad-assign1.c14
-rw-r--r--validation/eval-bad-assign2.c22
3 files changed, 42 insertions, 2 deletions
diff --git a/linearize.c b/linearize.c
index 415bf7e5..9ed66737 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1764,7 +1764,7 @@ static pseudo_t linearize_cond_branch(struct entrypoint *ep, struct expression *
{
pseudo_t cond;
- if (!expr || !bb_reachable(ep->active))
+ if (!expr || !valid_type(expr->ctype) || !bb_reachable(ep->active))
return VOID;
switch (expr->type) {
@@ -1864,7 +1864,7 @@ static void linearize_argument(struct entrypoint *ep, struct symbol *arg, int nr
static pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
{
- if (!expr)
+ if (!expr || !valid_type(expr->ctype))
return VOID;
current_pos = expr->pos;
@@ -2417,6 +2417,10 @@ static pseudo_t linearize_statement(struct entrypoint *ep, struct statement *stm
bb_true = alloc_basic_block(ep, stmt->pos);
bb_false = endif = alloc_basic_block(ep, stmt->pos);
+ // If the condition is invalid, the following
+ // statement(s) are not evaluated.
+ if (!cond || !valid_type(cond->ctype))
+ return VOID;
linearize_cond_branch(ep, cond, bb_true, bb_false);
set_activeblock(ep, bb_true);
diff --git a/validation/eval-bad-assign1.c b/validation/eval-bad-assign1.c
new file mode 100644
index 00000000..57138c7a
--- /dev/null
+++ b/validation/eval-bad-assign1.c
@@ -0,0 +1,14 @@
+static void kos(int *r, int a)
+{
+ r = ({ __builtin_types_compatible_p(int, int); });
+}
+
+/*
+ * check-name: eval-bad-assign1
+ *
+ * check-error-start
+eval-bad-assign1.c:3:11: warning: incorrect type in assignment (different base types)
+eval-bad-assign1.c:3:11: expected int *r
+eval-bad-assign1.c:3:11: got int
+ * check-error-end
+ */
diff --git a/validation/eval-bad-assign2.c b/validation/eval-bad-assign2.c
new file mode 100644
index 00000000..4d08cb90
--- /dev/null
+++ b/validation/eval-bad-assign2.c
@@ -0,0 +1,22 @@
+struct s {
+ char c[1];
+};
+
+struct s fun(void);
+
+
+static void foo(void)
+{
+ char c[1];
+ c = fun().c;
+}
+
+/*
+ * check-name: eval-bad-assign2
+ *
+ * check-error-start
+eval-bad-assign2.c:11:11: warning: incorrect type in assignment (invalid types)
+eval-bad-assign2.c:11:11: expected char c[1]
+eval-bad-assign2.c:11:11: got char *
+ * check-error-end
+ */