aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--cse.c4
-rw-r--r--expand.c2
-rw-r--r--expression.c6
-rw-r--r--linearize.c2
-rw-r--r--memops.c2
-rw-r--r--validation/Waddress-weak.c2
-rw-r--r--validation/Waddress.c4
-rw-r--r--validation/bug-bad-type.c18
-rw-r--r--validation/empty-expr.c26
-rw-r--r--validation/linear/bitfield-expand-deref.c27
-rw-r--r--validation/linear/degen-function.c13
-rw-r--r--validation/optim/cse-fcmp.c19
12 files changed, 124 insertions, 1 deletions
diff --git a/cse.c b/cse.c
index d5da26fb..6987645c 100644
--- a/cse.c
+++ b/cse.c
@@ -71,7 +71,8 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
case OP_SET_B: case OP_SET_A:
case OP_SET_BE: case OP_SET_AE:
- /* floating-point arithmetic */
+ /* floating-point arithmetic & comparison */
+ case OP_FPCMP ... OP_FPCMP_END:
case OP_FADD:
case OP_FSUB:
case OP_FMUL:
@@ -214,6 +215,7 @@ static int insn_compare(const void *_i1, const void *_i2)
case OP_SET_BE: case OP_SET_AE:
/* floating-point arithmetic */
+ case OP_FPCMP ... OP_FPCMP_END:
case OP_FADD:
case OP_FSUB:
case OP_FMUL:
diff --git a/expand.c b/expand.c
index f1aa838d..d44aec24 100644
--- a/expand.c
+++ b/expand.c
@@ -644,6 +644,8 @@ static int expand_dereference(struct expression *expr)
if (value) {
/* FIXME! We should check that the size is right! */
if (value->type == EXPR_VALUE) {
+ if (is_bitfield_type(value->ctype))
+ return UNSAFE;
expr->type = EXPR_VALUE;
expr->value = value->value;
expr->taint = 0;
diff --git a/expression.c b/expression.c
index e5ebad65..6f4300b9 100644
--- a/expression.c
+++ b/expression.c
@@ -62,7 +62,10 @@ static struct token *comma_expression(struct token *, struct expression **);
struct token *parens_expression(struct token *token, struct expression **expr, const char *where)
{
+ struct token *p;
+
token = expect(token, '(', where);
+ p = token;
if (match_op(token, '{')) {
struct expression *e = alloc_expression(token->pos, EXPR_STATEMENT);
struct statement *stmt = alloc_statement(token->pos, STMT_COMPOUND);
@@ -74,6 +77,9 @@ struct token *parens_expression(struct token *token, struct expression **expr, c
token = expect(token, '}', "at end of statement expression");
} else
token = parse_expression(token, expr);
+
+ if (token == p)
+ sparse_error(token->pos, "an expression is expected before ')'");
return expect(token, ')', where);
}
diff --git a/linearize.c b/linearize.c
index 2e146de7..deed3ca2 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1945,6 +1945,8 @@ static pseudo_t linearize_switch(struct entrypoint *ep, struct statement *stmt)
pseudo_t pseudo;
pseudo = linearize_expression(ep, expr);
+ if (pseudo == VOID)
+ return pseudo;
active = ep->active;
if (!bb_reachable(active))
diff --git a/memops.c b/memops.c
index 137e851e..788ed2f2 100644
--- a/memops.c
+++ b/memops.c
@@ -160,6 +160,8 @@ static void kill_dominated_stores(struct basic_block *bb)
pseudo_t pseudo = insn->src;
int local;
+ if (!insn->type)
+ continue;
if (insn->type->ctype.modifiers & MOD_VOLATILE)
continue;
diff --git a/validation/Waddress-weak.c b/validation/Waddress-weak.c
index 1fe8d33c..ad2cb13a 100644
--- a/validation/Waddress-weak.c
+++ b/validation/Waddress-weak.c
@@ -9,11 +9,13 @@ int test_addr_weak_fun(void)
if ( &arr) return 1;
if ( fun) return 1;
if ( &fun) return 1;
+ if ( *fun) return 1;
if (!&var) return 0;
if (! arr) return 0;
if (!&arr) return 0;
if (! fun) return 0;
if (!&fun) return 0;
+ if (!*fun) return 0;
return -1;
}
diff --git a/validation/Waddress.c b/validation/Waddress.c
index 10556c3a..441cdb1c 100644
--- a/validation/Waddress.c
+++ b/validation/Waddress.c
@@ -15,6 +15,7 @@ lab:
if (&arr) return 1;
if (fun) return 1;
if (&fun) return 1;
+ if (*fun) return 1;
if (&var) return 1;
if (&arg) return 1;
if (&&lab) return 1;
@@ -35,6 +36,7 @@ lab:
if (!&arr) return 0;
if (!fun) return 0;
if (!&fun) return 0;
+ if (!*fun) return 0;
if (!&var) return 0;
if (!&arg) return 0;
if (!&&lab) return 0;
@@ -62,6 +64,8 @@ lab:
if (0 == fun) return 0;
if (&fun == 0) return 0;
if (0 == &fun) return 0;
+ if (*fun == 0) return 0;
+ if (0 == *fun) return 0;
if (&var == 0) return 0;
if (0 == &var) return 0;
if (&arg == 0) return 0;
diff --git a/validation/bug-bad-type.c b/validation/bug-bad-type.c
new file mode 100644
index 00000000..0e00efef
--- /dev/null
+++ b/validation/bug-bad-type.c
@@ -0,0 +1,18 @@
+struct s {
+ int i;
+};
+
+long a;
+void foo(void)
+{
+ (struct s) { .i = (foo - a), };
+}
+
+/*
+ * check-name: bug-bad-type
+ *
+ * check-error-start
+bug-bad-type.c:5:6: warning: symbol 'a' was not declared. Should it be static?
+bug-bad-type.c:8:32: error: arithmetics on pointers to functions
+ * check-error-end
+ */
diff --git a/validation/empty-expr.c b/validation/empty-expr.c
new file mode 100644
index 00000000..61decf73
--- /dev/null
+++ b/validation/empty-expr.c
@@ -0,0 +1,26 @@
+static int foo(void)
+{
+ switch () {
+ case 0:
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+static int bar(void)
+{
+ if ()
+ return 0;
+ else
+ return 1;
+}
+
+/*
+ * check-name: empty expression
+ *
+ * check-error-start
+empty-expr.c:3:17: error: an expression is expected before ')'
+empty-expr.c:13:13: error: an expression is expected before ')'
+ * check-error-end
+ */
diff --git a/validation/linear/bitfield-expand-deref.c b/validation/linear/bitfield-expand-deref.c
new file mode 100644
index 00000000..7748725f
--- /dev/null
+++ b/validation/linear/bitfield-expand-deref.c
@@ -0,0 +1,27 @@
+struct s {
+ int a:8;
+ int b:8;
+};
+
+int foo(void)
+{
+ struct s x = { .a = 12, .b = 34, };
+
+ return x.b;
+}
+
+int bar(int a)
+{
+ struct s x = { .a = 12, .b = a, };
+
+ return x.b;
+}
+
+/*
+ * check-name: bitfield expand deref
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-excludes: ret\..*\$12
+ * check-output-contains: ret\..*\$34
+ */
diff --git a/validation/linear/degen-function.c b/validation/linear/degen-function.c
index 6dd3123b..4fb2d564 100644
--- a/validation/linear/degen-function.c
+++ b/validation/linear/degen-function.c
@@ -4,6 +4,7 @@ typedef int (*fun_t)(int);
fun_t fa(void) { return &fun; }
fun_t f0(void) { return fun; }
+fun_t f1(void) { return *fun; }
/*
* check-name: degen-function
@@ -34,5 +35,17 @@ f0:
ret.64 %r3
+f1:
+.L4:
+ <entry-point>
+ symaddr.64 %r5 <- fun
+ phisrc.64 %phi3(return) <- %r5
+ br .L5
+
+.L5:
+ phi.64 %r6 <- %phi3(return)
+ ret.64 %r5
+
+
* check-output-end
*/
diff --git a/validation/optim/cse-fcmp.c b/validation/optim/cse-fcmp.c
new file mode 100644
index 00000000..f2a73f57
--- /dev/null
+++ b/validation/optim/cse-fcmp.c
@@ -0,0 +1,19 @@
+extern void fun(void);
+
+int foo(double a, double b)
+{
+ if (a < b)
+ fun();
+ if (a < b)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * check-name: cse-fcmp
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-pattern(1): fcmp
+ */