History

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.

Russell King committed 17 years ago

Commit eedc9d81 parent 67b7ebe1 file · +37 −11Browse files

Unified · Split

scripts/unifdef.c+37−11
@@ -678,8 +678,10 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) · 677 unmodified lines
678 if (*cp == '!') {678 if (*cp == '!') {
679 debug("eval%d !", ops - eval_ops);679 debug("eval%d !", ops - eval_ops);
680 cp++;680 cp++;
681 if (eval_unary(ops, valp, &cp) == LT_IF)681 if (eval_unary(ops, valp, &cp) == LT_IF) {
682 *cpp = cp;
682 return (LT_IF);683 return (LT_IF);
684 }
683 *valp = !*valp;685 *valp = !*valp;
684 } else if (*cp == '(') {686 } else if (*cp == '(') {
685 cp++;687 cp++;
@@ -700,13 +702,16 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) · 14 unmodified lines
700 return (LT_IF);702 return (LT_IF);
701 cp = skipcomment(cp);703 cp = skipcomment(cp);
702 sym = findsym(cp);704 sym = findsym(cp);
703 if (sym < 0)
704 return (LT_IF);
705 *valp = (value[sym] != NULL);
706 cp = skipsym(cp);705 cp = skipsym(cp);
707 cp = skipcomment(cp);706 cp = skipcomment(cp);
708 if (*cp++ != ')')707 if (*cp++ != ')')
709 return (LT_IF);708 return (LT_IF);
709 if (sym >= 0)
710 *valp = (value[sym] != NULL);
711 else {
712 *cpp = cp;
713 return (LT_IF);
714 }
710 keepthis = false;715 keepthis = false;
711 } else if (!endsym(*cp)) {716 } else if (!endsym(*cp)) {
712 debug("eval%d symbol", ops - eval_ops);717 debug("eval%d symbol", ops - eval_ops);
@@ -741,11 +746,11 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) · 28 unmodified lines
741 const struct op *op;746 const struct op *op;
742 const char *cp;747 const char *cp;
743 int val;748 int val;
749 Linetype lhs, rhs;
744 750
745 debug("eval%d", ops - eval_ops);751 debug("eval%d", ops - eval_ops);
746 cp = *cpp;752 cp = *cpp;
747 if (ops->inner(ops+1, valp, &cp) == LT_IF)753 lhs = ops->inner(ops+1, valp, &cp);
748 return (LT_IF);
749 for (;;) {754 for (;;) {
750 cp = skipcomment(cp);755 cp = skipcomment(cp);
751 for (op = ops->op; op->str != NULL; op++)756 for (op = ops->op; op->str != NULL; op++)
@@ -755,14 +760,32 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) · 3 unmodified lines
755 break;760 break;
756 cp += strlen(op->str);761 cp += strlen(op->str);
757 debug("eval%d %s", ops - eval_ops, op->str);762 debug("eval%d %s", ops - eval_ops, op->str);
758 if (ops->inner(ops+1, &val, &cp) == LT_IF)763 rhs = ops->inner(ops+1, &val, &cp);
759 return (LT_IF);764 if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) {
760 *valp = op->fn(*valp, val);765 debug("eval%d: and always false", ops - eval_ops);
766 if (lhs == LT_IF)
767 *valp = val;
768 lhs = LT_FALSE;
769 continue;
770 }
771 if (op->fn == op_or && (lhs == LT_TRUE || rhs == LT_TRUE)) {
772 debug("eval%d: or always true", ops - eval_ops);
773 if (lhs == LT_IF)
774 *valp = val;
775 lhs = LT_TRUE;
776 continue;
777 }
778 if (rhs == LT_IF)
779 lhs = LT_IF;
780 if (lhs != LT_IF)
781 *valp = op->fn(*valp, val);
761 }782 }
762 783
763 *cpp = cp;784 *cpp = cp;
764 debug("eval%d = %d", ops - eval_ops, *valp);785 debug("eval%d = %d", ops - eval_ops, *valp);
765 return (*valp ? LT_TRUE : LT_FALSE);786 if (lhs != LT_IF)
787 lhs = (*valp ? LT_TRUE : LT_FALSE);
788 return lhs;
766}789}
767 790
768/*791/*
@@ -773,12 +796,15 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) · 4 unmodified lines
773static Linetype796static Linetype
774ifeval(const char **cpp)797ifeval(const char **cpp)
775{798{
799 const char *cp = *cpp;
776 int ret;800 int ret;
777 int val;801 int val;
778 802
779 debug("eval %s", *cpp);803 debug("eval %s", *cpp);
780 keepthis = killconsts ? false : true;804 keepthis = killconsts ? false : true;
781 ret = eval_table(eval_ops, &val, cpp);805 ret = eval_table(eval_ops, &val, &cp);
806 if (ret != LT_IF)
807 *cpp = cp;
782 debug("eval = %d", val);808 debug("eval = %d", val);
783 return (keepthis ? LT_IF : ret);809 return (keepthis ? LT_IF : ret);
784}810}