mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-29 17:22:07 +00:00
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: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
This commit is contained in:
parent
67b7ebe091
commit
eedc9d83ea
@ -678,8 +678,10 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp)
|
||||
if (*cp == '!') {
|
||||
debug("eval%d !", ops - eval_ops);
|
||||
cp++;
|
||||
if (eval_unary(ops, valp, &cp) == LT_IF)
|
||||
if (eval_unary(ops, valp, &cp) == LT_IF) {
|
||||
*cpp = cp;
|
||||
return (LT_IF);
|
||||
}
|
||||
*valp = !*valp;
|
||||
} else if (*cp == '(') {
|
||||
cp++;
|
||||
@ -700,13 +702,16 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp)
|
||||
return (LT_IF);
|
||||
cp = skipcomment(cp);
|
||||
sym = findsym(cp);
|
||||
if (sym < 0)
|
||||
return (LT_IF);
|
||||
*valp = (value[sym] != NULL);
|
||||
cp = skipsym(cp);
|
||||
cp = skipcomment(cp);
|
||||
if (*cp++ != ')')
|
||||
return (LT_IF);
|
||||
if (sym >= 0)
|
||||
*valp = (value[sym] != NULL);
|
||||
else {
|
||||
*cpp = cp;
|
||||
return (LT_IF);
|
||||
}
|
||||
keepthis = false;
|
||||
} else if (!endsym(*cp)) {
|
||||
debug("eval%d symbol", ops - eval_ops);
|
||||
@ -741,11 +746,11 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
|
||||
const struct op *op;
|
||||
const char *cp;
|
||||
int val;
|
||||
Linetype lhs, rhs;
|
||||
|
||||
debug("eval%d", ops - eval_ops);
|
||||
cp = *cpp;
|
||||
if (ops->inner(ops+1, valp, &cp) == LT_IF)
|
||||
return (LT_IF);
|
||||
lhs = ops->inner(ops+1, valp, &cp);
|
||||
for (;;) {
|
||||
cp = skipcomment(cp);
|
||||
for (op = ops->op; op->str != NULL; op++)
|
||||
@ -755,14 +760,32 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
|
||||
break;
|
||||
cp += strlen(op->str);
|
||||
debug("eval%d %s", ops - eval_ops, op->str);
|
||||
if (ops->inner(ops+1, &val, &cp) == LT_IF)
|
||||
return (LT_IF);
|
||||
*valp = op->fn(*valp, val);
|
||||
rhs = ops->inner(ops+1, &val, &cp);
|
||||
if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) {
|
||||
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;
|
||||
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)
|
||||
static Linetype
|
||||
ifeval(const char **cpp)
|
||||
{
|
||||
const char *cp = *cpp;
|
||||
int ret;
|
||||
int val;
|
||||
|
||||
debug("eval %s", *cpp);
|
||||
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);
|
||||
return (keepthis ? LT_IF : ret);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user