Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+37 −11
Original line number Diff line number Diff line
@@ -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);
		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);
}