I'm investigating some sparse's "warning: unknown expression (4 0)" on the current kernel. They are a few distinct cases but all of them are caused by some __builtin_types_compatible_p() not being expanded. In some of these cases the statement is not expanded because of an earlier error, for example in compatible_assignment_types(), but this statement is then linearized anyway. This needs to be be fixed but is not really a problem. Another case, much more annoying, is because input & output operands of ASM statements are not expanded. This is very easy to fix (see patch here below) but once fixed and used on the kernel, sparse then issues many thousands of "warning: dereference of noderef expression" (in fact, more than one million on defconfig + allyesconfig). These warnings are perfectly correct: a lot of ASM operands are indeed noderef variables or expressions (most warnings seem to come from put_user(), get_user() or one of the percpu operations). I'm quite reluctant to commit a patch that will add so much warnings. On the other hand, properly silenting these warnings in the kernel is a non-obvious job, especially given the fact that __force can't simply be used to 'ignore' __noderef (because the dereferencing kinda happens before the cast), you need to act via a pointer with something like: *(typeof(X) __kernel __force *) &(X); The only simple temporary 'solution' is see for the moment would be to disable 'noderef' warnings while expanding ASM. -- Luc Van Oostenryck >From 89e3ba40948c9c98ada673f3451be0b11b5740c3 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> Date: Mon, 14 Jan 2019 16:02:06 +0100 Subject: [PATCH] fix expansion of asm statements --- expand.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/expand.c b/expand.c index e8e50b080..fa410f39f 100644 --- a/expand.c +++ b/expand.c @@ -1155,6 +1155,22 @@ static int expand_if_statement(struct statement *stmt) return SIDE_EFFECTS; } +static int expand_asm_statement(struct statement *stmt) +{ + struct expression *op; + int cost = 0; + + FOR_EACH_PTR(stmt->asm_outputs, op) { + cost += expand_expression(op->expr); + } END_FOR_EACH_PTR(op); + + FOR_EACH_PTR(stmt->asm_inputs, op) { + cost += expand_expression(op->expr); + } END_FOR_EACH_PTR(op); + + return cost; +} + /* * Expanding a compound statement is really just * about adding up the costs of each individual @@ -1245,7 +1261,7 @@ static int expand_statement(struct statement *stmt) case STMT_NONE: break; case STMT_ASM: - /* FIXME! Do the asm parameter evaluation! */ + expand_asm_statement(stmt); break; case STMT_CONTEXT: expand_expression(stmt->expression); -- 2.20.0