Commit eedc9d83 authored by Russell King's avatar Russell King Committed by Sam Ravnborg

kbuild: fix headers_exports with boolean expression

When we had code like this in a header unifdef failed to
deduct that the expression was always false - and we had code exported
that was not intended for userspace.

#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
  int a;
#endif

This commit implment support in unidef which allows it to work out if
an #if expression always evaluates true or false for symbols which
are being undefined/always defined.

The patch is slightly more complicated than I'd hoped because unifdef
needs to see lines fully evaluated - doing otherwise causes it to
mark the line as "dirty" and copy it over no matter what.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent 67b7ebe0
...@@ -678,8 +678,10 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) ...@@ -678,8 +678,10 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp)
if (*cp == '!') { if (*cp == '!') {
debug("eval%d !", ops - eval_ops); debug("eval%d !", ops - eval_ops);
cp++; cp++;
if (eval_unary(ops, valp, &cp) == LT_IF) if (eval_unary(ops, valp, &cp) == LT_IF) {
*cpp = cp;
return (LT_IF); return (LT_IF);
}
*valp = !*valp; *valp = !*valp;
} else if (*cp == '(') { } else if (*cp == '(') {
cp++; cp++;
...@@ -700,13 +702,16 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) ...@@ -700,13 +702,16 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp)
return (LT_IF); return (LT_IF);
cp = skipcomment(cp); cp = skipcomment(cp);
sym = findsym(cp); sym = findsym(cp);
if (sym < 0)
return (LT_IF);
*valp = (value[sym] != NULL);
cp = skipsym(cp); cp = skipsym(cp);
cp = skipcomment(cp); cp = skipcomment(cp);
if (*cp++ != ')') if (*cp++ != ')')
return (LT_IF); return (LT_IF);
if (sym >= 0)
*valp = (value[sym] != NULL);
else {
*cpp = cp;
return (LT_IF);
}
keepthis = false; keepthis = false;
} else if (!endsym(*cp)) { } else if (!endsym(*cp)) {
debug("eval%d symbol", ops - eval_ops); debug("eval%d symbol", ops - eval_ops);
...@@ -741,11 +746,11 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) ...@@ -741,11 +746,11 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
const struct op *op; const struct op *op;
const char *cp; const char *cp;
int val; int val;
Linetype lhs, rhs;
debug("eval%d", ops - eval_ops); debug("eval%d", ops - eval_ops);
cp = *cpp; cp = *cpp;
if (ops->inner(ops+1, valp, &cp) == LT_IF) lhs = ops->inner(ops+1, valp, &cp);
return (LT_IF);
for (;;) { for (;;) {
cp = skipcomment(cp); cp = skipcomment(cp);
for (op = ops->op; op->str != NULL; op++) for (op = ops->op; op->str != NULL; op++)
...@@ -755,14 +760,32 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) ...@@ -755,14 +760,32 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
break; break;
cp += strlen(op->str); cp += strlen(op->str);
debug("eval%d %s", ops - eval_ops, op->str); debug("eval%d %s", ops - eval_ops, op->str);
if (ops->inner(ops+1, &val, &cp) == LT_IF) rhs = ops->inner(ops+1, &val, &cp);
return (LT_IF); if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) {
*valp = op->fn(*valp, val); debug("eval%d: and always false", ops - eval_ops);
if (lhs == LT_IF)
*valp = val;
lhs = LT_FALSE;
continue;
}
if (op->fn == op_or && (lhs == LT_TRUE || rhs == LT_TRUE)) {
debug("eval%d: or always true", ops - eval_ops);
if (lhs == LT_IF)
*valp = val;
lhs = LT_TRUE;
continue;
}
if (rhs == LT_IF)
lhs = LT_IF;
if (lhs != LT_IF)
*valp = op->fn(*valp, val);
} }
*cpp = cp; *cpp = cp;
debug("eval%d = %d", ops - eval_ops, *valp); debug("eval%d = %d", ops - eval_ops, *valp);
return (*valp ? LT_TRUE : LT_FALSE); if (lhs != LT_IF)
lhs = (*valp ? LT_TRUE : LT_FALSE);
return lhs;
} }
/* /*
...@@ -773,12 +796,15 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) ...@@ -773,12 +796,15 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
static Linetype static Linetype
ifeval(const char **cpp) ifeval(const char **cpp)
{ {
const char *cp = *cpp;
int ret; int ret;
int val; int val;
debug("eval %s", *cpp); debug("eval %s", *cpp);
keepthis = killconsts ? false : true; keepthis = killconsts ? false : true;
ret = eval_table(eval_ops, &val, cpp); ret = eval_table(eval_ops, &val, &cp);
if (ret != LT_IF)
*cpp = cp;
debug("eval = %d", val); debug("eval = %d", val);
return (keepthis ? LT_IF : ret); return (keepthis ? LT_IF : ret);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment