Commit eedc9d83eaab2d35fb9dd1ec25b765dec964e26c

Authored by Russell King
Committed by Sam Ravnborg
1 parent 67b7ebe091

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>

Showing 1 changed file with 37 additions and 11 deletions Side-by-side Diff

... ... @@ -678,8 +678,10 @@
678 678 if (*cp == '!') {
679 679 debug("eval%d !", ops - eval_ops);
680 680 cp++;
681   - if (eval_unary(ops, valp, &cp) == LT_IF)
  681 + if (eval_unary(ops, valp, &cp) == LT_IF) {
  682 + *cpp = cp;
682 683 return (LT_IF);
  684 + }
683 685 *valp = !*valp;
684 686 } else if (*cp == '(') {
685 687 cp++;
686 688  
... ... @@ -700,13 +702,16 @@
700 702 return (LT_IF);
701 703 cp = skipcomment(cp);
702 704 sym = findsym(cp);
703   - if (sym < 0)
704   - return (LT_IF);
705   - *valp = (value[sym] != NULL);
706 705 cp = skipsym(cp);
707 706 cp = skipcomment(cp);
708 707 if (*cp++ != ')')
709 708 return (LT_IF);
  709 + if (sym >= 0)
  710 + *valp = (value[sym] != NULL);
  711 + else {
  712 + *cpp = cp;
  713 + return (LT_IF);
  714 + }
710 715 keepthis = false;
711 716 } else if (!endsym(*cp)) {
712 717 debug("eval%d symbol", ops - eval_ops);
713 718  
... ... @@ -741,11 +746,11 @@
741 746 const struct op *op;
742 747 const char *cp;
743 748 int val;
  749 + Linetype lhs, rhs;
744 750  
745 751 debug("eval%d", ops - eval_ops);
746 752 cp = *cpp;
747   - if (ops->inner(ops+1, valp, &cp) == LT_IF)
748   - return (LT_IF);
  753 + lhs = ops->inner(ops+1, valp, &cp);
749 754 for (;;) {
750 755 cp = skipcomment(cp);
751 756 for (op = ops->op; op->str != NULL; op++)
752 757  
... ... @@ -755,14 +760,32 @@
755 760 break;
756 761 cp += strlen(op->str);
757 762 debug("eval%d %s", ops - eval_ops, op->str);
758   - if (ops->inner(ops+1, &val, &cp) == LT_IF)
759   - return (LT_IF);
760   - *valp = op->fn(*valp, val);
  763 + rhs = ops->inner(ops+1, &val, &cp);
  764 + if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) {
  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 784 *cpp = cp;
764 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 /*
769 792  
... ... @@ -773,12 +796,15 @@
773 796 static Linetype
774 797 ifeval(const char **cpp)
775 798 {
  799 + const char *cp = *cpp;
776 800 int ret;
777 801 int val;
778 802  
779 803 debug("eval %s", *cpp);
780 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 808 debug("eval = %d", val);
783 809 return (keepthis ? LT_IF : ret);
784 810 }