aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--lib.h5
-rw-r--r--linearize.c21
-rw-r--r--parse.c10
-rw-r--r--simplify.c57
-rw-r--r--validation/asm-bad0.c2
-rw-r--r--validation/bad-type-twice0.c3
-rw-r--r--validation/badtype2.c1
-rw-r--r--validation/badtype3.c1
-rw-r--r--validation/implicit-KR-arg-type1.c11
-rw-r--r--validation/linear/inline-definition.c30
10 files changed, 71 insertions, 70 deletions
diff --git a/lib.h b/lib.h
index 0b1d4492..b4c3db93 100644
--- a/lib.h
+++ b/lib.h
@@ -204,6 +204,11 @@ static inline pseudo_t first_pseudo(struct pseudo_list *head)
return first_ptr_list((struct ptr_list *)head);
}
+static inline struct symbol *first_symbol(struct symbol_list *head)
+{
+ return first_ptr_list((struct ptr_list *)head);
+}
+
static inline void concat_symbol_list(struct symbol_list *from, struct symbol_list **to)
{
concat_ptr_list((struct ptr_list *)from, (struct ptr_list **)to);
diff --git a/linearize.c b/linearize.c
index b7da35fa..d9a3ac49 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1520,8 +1520,6 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
}
ctype = &fntype->ctype;
- if (fntype->type == SYM_NODE)
- fntype = fntype->ctype.base_type;
add_symbol(&insn->fntypes, fntype);
FOR_EACH_PTR(expr->args, arg) {
@@ -1795,37 +1793,30 @@ static pseudo_t linearize_cond_branch(struct entrypoint *ep, struct expression *
case EXPR_STRING:
case EXPR_VALUE:
add_goto(ep, expr->value ? bb_true : bb_false);
- return VOID;
-
+ break;
case EXPR_FVALUE:
add_goto(ep, expr->fvalue ? bb_true : bb_false);
- return VOID;
-
+ break;
case EXPR_LOGICAL:
linearize_logical_branch(ep, expr, bb_true, bb_false);
- return VOID;
-
+ break;
case EXPR_COMPARE:
cond = linearize_compare(ep, expr);
add_branch(ep, cond, bb_true, bb_false);
break;
-
case EXPR_PREOP:
if (expr->op == '!')
return linearize_cond_branch(ep, expr->unop, bb_false, bb_true);
/* fall through */
- default: {
+ default:
cond = linearize_expression_to_bool(ep, expr);
add_branch(ep, cond, bb_true, bb_false);
-
- return VOID;
- }
+ break;
}
return VOID;
}
-
static pseudo_t linearize_logical_branch(struct entrypoint *ep, struct expression *expr, struct basic_block *bb_true, struct basic_block *bb_false)
{
struct basic_block *next = alloc_basic_block(ep, expr->pos);
@@ -2065,7 +2056,7 @@ static pseudo_t linearize_inlined_call(struct entrypoint *ep, struct statement *
pseudo = linearize_fn_statement(ep, stmt);
insn->target = pseudo;
- use_pseudo(insn, symbol_pseudo(ep, stmt->inline_fn), &insn->func);
+ insn->func = symbol_pseudo(ep, stmt->inline_fn);
bb = ep->active;
if (!bb->insns)
bb->pos = stmt->pos;
diff --git a/parse.c b/parse.c
index b6090d38..0b268570 100644
--- a/parse.c
+++ b/parse.c
@@ -2718,6 +2718,14 @@ static void declare_argument(struct symbol *sym, struct symbol *fn)
sparse_error(sym->pos, "no identifier for function argument");
return;
}
+ if (sym->ctype.base_type == &incomplete_ctype) {
+ sym->ctype.base_type = &int_ctype;
+
+ if (Wimplicit_int) {
+ sparse_error(sym->pos, "missing type declaration for parameter '%s'",
+ show_ident(sym->ident));
+ }
+ }
bind_symbol(sym, sym->ident, NS_SYMBOL);
}
@@ -2809,7 +2817,7 @@ static void apply_k_r_types(struct symbol_list *argtypes, struct symbol *fn)
goto match;
} END_FOR_EACH_PTR(type);
if (Wimplicit_int) {
- sparse_error(arg->pos, "missing type declaration for parameter '%s'",
+ warning(arg->pos, "missing type declaration for parameter '%s'",
show_ident(arg->ident));
}
type = alloc_symbol(arg->pos, SYM_NODE);
diff --git a/simplify.c b/simplify.c
index 7588e420..307787d0 100644
--- a/simplify.c
+++ b/simplify.c
@@ -351,9 +351,9 @@ int kill_insn(struct instruction *insn, int force)
case OP_CALL:
if (!force) {
/* a "pure" function can be killed too */
- if (!(insn->func->type == PSEUDO_SYM))
- return 0;
- if (!(insn->func->sym->ctype.modifiers & MOD_PURE))
+ struct symbol *fntype = first_symbol(insn->fntypes);
+
+ if (!(fntype->ctype.modifiers & MOD_PURE))
return 0;
}
kill_use_list(insn->arguments);
@@ -388,20 +388,6 @@ int kill_insn(struct instruction *insn, int force)
return repeat_phase |= REPEAT_CSE;
}
-///
-// kill trivially dead instructions
-static int dead_insn(struct instruction *insn, pseudo_t *src1, pseudo_t *src2, pseudo_t *src3)
-{
- if (has_users(insn->target))
- return 0;
-
- insn->bb = NULL;
- kill_use(src1);
- kill_use(src2);
- kill_use(src3);
- return REPEAT_CSE;
-}
-
static inline bool has_target(struct instruction *insn)
{
return opcode_table[insn->opcode].flags & OPF_TARGET;
@@ -1300,8 +1286,6 @@ static int simplify_binop_same_args(struct instruction *insn, pseudo_t arg)
static int simplify_binop(struct instruction *insn)
{
- if (dead_insn(insn, &insn->src1, &insn->src2, NULL))
- return REPEAT_CSE;
if (constant(insn->src1)) {
if (constant(insn->src2))
return simplify_constant_binop(insn);
@@ -1484,8 +1468,6 @@ static int simplify_unop(struct instruction *insn)
struct instruction *def;
pseudo_t src = insn->src;
- if (dead_insn(insn, &insn->src1, NULL, NULL))
- return REPEAT_CSE;
if (constant(src))
return simplify_constant_unop(insn);
@@ -1616,16 +1598,11 @@ static int simplify_cast(struct instruction *insn)
{
unsigned long long mask;
struct instruction *def;
- pseudo_t src;
+ pseudo_t src = insn->src;
pseudo_t val;
int osize;
int size;
- if (dead_insn(insn, &insn->src, NULL, NULL))
- return REPEAT_CSE;
-
- src = insn->src;
-
/* A cast of a constant? */
if (constant(src))
return simplify_constant_unop(insn);
@@ -1760,9 +1737,6 @@ static int simplify_select(struct instruction *insn)
{
pseudo_t cond, src1, src2;
- if (dead_insn(insn, &insn->src1, &insn->src2, &insn->src3))
- return REPEAT_CSE;
-
cond = insn->src1;
src1 = insn->src2;
src2 = insn->src3;
@@ -1934,6 +1908,10 @@ int simplify_instruction(struct instruction *insn)
return 0;
flags = opcode_table[insn->opcode].flags;
+ if (flags & OPF_TARGET) {
+ if (!has_users(insn->target))
+ return kill_instruction(insn);
+ }
if (flags & OPF_COMMU)
canonicalize_commutative(insn) ;
if (flags & OPF_COMPARE)
@@ -1979,14 +1957,9 @@ int simplify_instruction(struct instruction *insn)
case OP_SET_AE:
break;
case OP_LOAD:
- if (!has_users(insn->target))
- return kill_instruction(insn);
- /* fall-through */
case OP_STORE:
return simplify_memop(insn);
case OP_SYMADDR:
- if (dead_insn(insn, &insn->src, NULL, NULL))
- return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
return replace_with_pseudo(insn, insn->src);
case OP_SEXT: case OP_ZEXT:
case OP_TRUNC:
@@ -1996,30 +1969,18 @@ int simplify_instruction(struct instruction *insn)
case OP_UCVTF: case OP_SCVTF:
case OP_FCVTF:
case OP_PTRCAST:
- if (dead_insn(insn, &insn->src, NULL, NULL))
- return REPEAT_CSE;
break;
case OP_UTPTR:
case OP_PTRTU:
return replace_with_pseudo(insn, insn->src);
case OP_SLICE:
- if (dead_insn(insn, &insn->src, NULL, NULL))
- return REPEAT_CSE;
break;
case OP_SETVAL:
case OP_SETFVAL:
- if (dead_insn(insn, NULL, NULL, NULL))
- return REPEAT_CSE;
break;
case OP_PHI:
- if (dead_insn(insn, NULL, NULL, NULL)) {
- kill_use_list(insn->phi_list);
- return REPEAT_CSE;
- }
return clean_up_phi(insn);
case OP_PHISOURCE:
- if (dead_insn(insn, &insn->phi_src, NULL, NULL))
- return REPEAT_CSE;
break;
case OP_SEL:
return simplify_select(insn);
@@ -2033,8 +1994,6 @@ int simplify_instruction(struct instruction *insn)
case OP_FSUB:
case OP_FMUL:
case OP_FDIV:
- if (dead_insn(insn, &insn->src1, &insn->src2, NULL))
- return REPEAT_CSE;
break;
}
return 0;
diff --git a/validation/asm-bad0.c b/validation/asm-bad0.c
index aa9bf28d..4ba78575 100644
--- a/validation/asm-bad0.c
+++ b/validation/asm-bad0.c
@@ -16,7 +16,7 @@ static void icons(void)
asm("template" : [out] "=r" (var): [in] string (0));
}
-static void oexpr(oid)
+static void oexpr(void)
{
asm("template" : [out] "=" (var[) : [in] "r" (0));
}
diff --git a/validation/bad-type-twice0.c b/validation/bad-type-twice0.c
index 9e834d47..e7ec7b75 100644
--- a/validation/bad-type-twice0.c
+++ b/validation/bad-type-twice0.c
@@ -7,7 +7,6 @@ static int foo(a)
* check-name: bad-type-twice0
*
* check-error-start
-bad-type-twice0.c:3:16: error: non-scalar type in conditional:
-bad-type-twice0.c:3:16: incomplete type a
+bad-type-twice0.c:1:16: error: missing type declaration for parameter 'a'
* check-error-end
*/
diff --git a/validation/badtype2.c b/validation/badtype2.c
index 49fec87c..173dbfda 100644
--- a/validation/badtype2.c
+++ b/validation/badtype2.c
@@ -18,6 +18,7 @@ badtype2.c:2:14: error: got bar
badtype2.c:3:14: error: Expected ; at end of declaration
badtype2.c:3:14: error: got foo
badtype2.c:6:3: error: Trying to use reserved word 'switch' as identifier
+badtype2.c:6:11: error: missing type declaration for parameter 'p'
badtype2.c:7:3: error: not in switch scope
badtype2.c:10:1: error: Expected ; at the end of type declaration
badtype2.c:10:1: error: got }
diff --git a/validation/badtype3.c b/validation/badtype3.c
index 20f346c5..c111d94e 100644
--- a/validation/badtype3.c
+++ b/validation/badtype3.c
@@ -16,6 +16,7 @@ badtype3.c:2:18: warning: identifier list not in definition
badtype3.c:2:24: error: Expected ) in function declarator
badtype3.c:2:24: error: got ,
badtype3.c:5:3: error: Trying to use reserved word 'while' as identifier
+badtype3.c:5:10: error: missing type declaration for parameter 'cur'
badtype3.c:7:7: error: break/continue not in iterator scope
badtype3.c:9:3: error: Trying to use reserved word 'return' as identifier
badtype3.c:9:10: error: Expected ; at end of declaration
diff --git a/validation/implicit-KR-arg-type1.c b/validation/implicit-KR-arg-type1.c
index fe199ef5..c7eb39ae 100644
--- a/validation/implicit-KR-arg-type1.c
+++ b/validation/implicit-KR-arg-type1.c
@@ -1,16 +1,23 @@
-int foo(a, b)
+static int foo(a, b)
int a;
{
if (b)
return a;
}
+static int bar(a)
+{
+ if (a)
+ return a;
+}
+
/*
* check-name: implicit-KR-arg-type1
* check-command: sparse -Wold-style-definition -Wimplicit-int $file
*
* check-error-start
implicit-KR-arg-type1.c:2:9: warning: non-ANSI definition of function 'foo'
-implicit-KR-arg-type1.c:1:12: error: missing type declaration for parameter 'b'
+implicit-KR-arg-type1.c:1:19: warning: missing type declaration for parameter 'b'
+implicit-KR-arg-type1.c:8:16: error: missing type declaration for parameter 'a'
* check-error-end
*/
diff --git a/validation/linear/inline-definition.c b/validation/linear/inline-definition.c
new file mode 100644
index 00000000..2918bd5d
--- /dev/null
+++ b/validation/linear/inline-definition.c
@@ -0,0 +1,30 @@
+extern void use(void *);
+
+static inline int inl0(int a);
+static inline int inl1(int a);
+
+static inline int inl0(int a)
+{
+ return a;
+}
+
+void foo(void)
+{
+ use(inl0);
+ use(inl1);
+}
+
+static inline int inl1(int a)
+{
+ return a;
+}
+
+/*
+ * check-name: inline-definition
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-contains: inl0:
+ * check-output-contains: inl1:
+ */