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

Showing the changes to scripts (1 of 1 file). Show all

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
678678 if (*cp == '!') {
679679 debug("eval%d !", ops - eval_ops);
680680 cp++;
681− if (eval_unary(ops, valp, &cp) == LT_IF)
681+ if (eval_unary(ops, valp, &cp) == LT_IF) {
682+ *cpp = cp;
682683 return (LT_IF);
684+ }
683685 *valp = !*valp;
684686 } else if (*cp == '(') {
685687 cp++;
@@ -700,13 +702,16 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) · 14 unmodified lines
700702 return (LT_IF);
701703 cp = skipcomment(cp);
702704 sym = findsym(cp);
703− if (sym < 0)
704− return (LT_IF);
705− *valp = (value[sym] != NULL);
706705 cp = skipsym(cp);
707706 cp = skipcomment(cp);
708707 if (*cp++ != ')')
709708 return (LT_IF);
709+ if (sym >= 0)
710+ *valp = (value[sym] != NULL);
711+ else {
712+ *cpp = cp;
713+ return (LT_IF);
714+ }
710715 keepthis = false;
711716 } else if (!endsym(*cp)) {
712717 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
741746 const struct op *op;
742747 const char *cp;
743748 int val;
749+ Linetype lhs, rhs;
744750
745751 debug("eval%d", ops - eval_ops);
746752 cp = *cpp;
747− if (ops->inner(ops+1, valp, &cp) == LT_IF)
748− return (LT_IF);
753+ lhs = ops->inner(ops+1, valp, &cp);
749754 for (;;) {
750755 cp = skipcomment(cp);
751756 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
755760 break;
756761 cp += strlen(op->str);
757762 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);
761782 }
762783
763784 *cpp = cp;
764785 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;
766789 }
767790
768791 /*
@@ -773,12 +796,15 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) · 4 unmodified lines
773796 static Linetype
774797 ifeval(const char **cpp)
775798 {
799+ const char *cp = *cpp;
776800 int ret;
777801 int val;
778802
779803 debug("eval %s", *cpp);
780804 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;
782808 debug("eval = %d", val);
783809 return (keepthis ? LT_IF : ret);
784810 }