diff options
author | Russell King <rmk+lkml@arm.linux.org.uk> | 2009-06-06 17:47:11 -0400 |
---|---|---|
committer | Sam Ravnborg <sam@ravnborg.org> | 2009-06-09 16:37:57 -0400 |
commit | eedc9d83eaab2d35fb9dd1ec25b765dec964e26c (patch) | |
tree | 0ac52787334de2da7852f70a4d6822e6cb291a68 | |
parent | 67b7ebe091cd92fd69f732da3170720d79c4e632 (diff) |
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>
-rw-r--r-- | scripts/unifdef.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/scripts/unifdef.c b/scripts/unifdef.c index 05a31a6c7e1b..30d459fb0709 100644 --- a/scripts/unifdef.c +++ b/scripts/unifdef.c | |||
@@ -678,8 +678,10 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) | |||
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) | |||
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) | |||
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) | |||
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) | |||
773 | static Linetype | 796 | static Linetype |
774 | ifeval(const char **cpp) | 797 | ifeval(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 | } |