diff options
Diffstat (limited to 'src/opt.c')
-rw-r--r-- | src/opt.c | 69 |
1 files changed, 28 insertions, 41 deletions
@@ -122,7 +122,7 @@ static const char *const pred_names[] = { }; /** - * A contrained integer range. + * A constrained integer range. */ struct df_range { /** The (inclusive) minimum value. */ @@ -737,9 +737,7 @@ static struct bfs_expr *visit_and(struct bfs_opt *opt, struct bfs_expr *expr, co df_init_bottom(&opt->after_false); struct bfs_opt nested = *opt; - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (SLIST_EMPTY(&children)) { nested.ignore_result = opt->ignore_result; } else { @@ -771,9 +769,7 @@ static struct bfs_expr *visit_or(struct bfs_opt *opt, struct bfs_expr *expr, con df_init_bottom(&opt->after_true); struct bfs_opt nested = *opt; - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (SLIST_EMPTY(&children)) { nested.ignore_result = opt->ignore_result; } else { @@ -803,9 +799,7 @@ static struct bfs_expr *visit_comma(struct bfs_opt *opt, struct bfs_expr *expr, struct bfs_opt nested = *opt; - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (SLIST_EMPTY(&children)) { nested.ignore_result = opt->ignore_result; } else { @@ -1384,8 +1378,7 @@ static struct bfs_expr *sink_not_andor(struct bfs_opt *opt, struct bfs_expr *exp struct bfs_exprs children; foster_children(expr, &children); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { opt_enter(opt, "%pe\n", child); child = negate_expr(opt, child, argv); @@ -1412,8 +1405,7 @@ static struct bfs_expr *sink_not_comma(struct bfs_opt *opt, struct bfs_expr *exp struct bfs_exprs children; foster_children(expr, &children); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { if (SLIST_EMPTY(&children)) { opt_enter(opt, "%pe\n", child); opt_debug(opt, "sink\n"); @@ -1441,7 +1433,6 @@ static struct bfs_expr *canonicalize_not(struct bfs_opt *opt, struct bfs_expr *e if (rhs->eval_fn == eval_not) { opt_debug(opt, "double negation\n"); - rhs = only_child(expr); return only_child(rhs); } else if (rhs->eval_fn == eval_and || rhs->eval_fn == eval_or) { return sink_not_andor(opt, expr); @@ -1463,8 +1454,7 @@ static struct bfs_expr *canonicalize_assoc(struct bfs_opt *opt, struct bfs_expr struct bfs_exprs flat; SLIST_INIT(&flat); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { if (child->eval_fn == expr->eval_fn) { struct bfs_expr *head = SLIST_HEAD(&child->children); struct bfs_expr *tail = SLIST_TAIL(&child->children); @@ -1572,8 +1562,7 @@ static struct bfs_expr *reorder_andor(struct bfs_opt *opt, struct bfs_expr *expr struct bfs_exprs pure; SLIST_INIT(&pure); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { if (child->pure) { SLIST_APPEND(&pure, child); } else { @@ -1634,14 +1623,19 @@ static void data_flow_icmp(struct bfs_opt *opt, const struct bfs_expr *expr, enu /** Transfer function for -{execut,read,writ}able. */ static struct bfs_expr *data_flow_access(struct bfs_opt *opt, struct bfs_expr *expr, const struct visitor *visitor) { - if (expr->num & R_OK) { + switch (expr->num) { + case R_OK: data_flow_pred(opt, READABLE_PRED, true); - } - if (expr->num & W_OK) { + break; + case W_OK: data_flow_pred(opt, WRITABLE_PRED, true); - } - if (expr->num & X_OK) { + break; + case X_OK: data_flow_pred(opt, EXECUTABLE_PRED, true); + break; + default: + bfs_bug("Unknown access() mode %lld", expr->num); + break; } return expr; @@ -1666,7 +1660,7 @@ static struct bfs_expr *data_flow_gid(struct bfs_opt *opt, struct bfs_expr *expr gid_t gid = range->min; bool nogroup = !bfs_getgrgid(opt->ctx->groups, gid); if (errno == 0) { - data_flow_pred(opt, NOGROUP_PRED, nogroup); + constrain_pred(&opt->after_true.preds[NOGROUP_PRED], nogroup); } } @@ -1740,7 +1734,7 @@ static struct bfs_expr *data_flow_uid(struct bfs_opt *opt, struct bfs_expr *expr uid_t uid = range->min; bool nouser = !bfs_getpwuid(opt->ctx->users, uid); if (errno == 0) { - data_flow_pred(opt, NOUSER_PRED, nouser); + constrain_pred(&opt->after_true.preds[NOUSER_PRED], nouser); } } @@ -1975,8 +1969,7 @@ static struct bfs_expr *lift_andor_not(struct bfs_opt *opt, struct bfs_expr *exp struct bfs_exprs children; foster_children(expr, &children); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { opt_enter(opt, "%pe\n", child); child = negate_expr(opt, child, &fake_not_arg); @@ -2022,9 +2015,7 @@ static struct bfs_expr *simplify_and(struct bfs_opt *opt, struct bfs_expr *expr, struct bfs_exprs children; foster_children(expr, &children); - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (child == ignorable) { ignore = true; } @@ -2045,8 +2036,8 @@ static struct bfs_expr *simplify_and(struct bfs_opt *opt, struct bfs_expr *expr, bfs_expr_append(expr, child); if (child->always_false) { - while ((child = SLIST_POP(&children))) { - opt_delete(opt, "%pe [short-circuit]\n", child); + drain_slist (struct bfs_expr, dead, &children) { + opt_delete(opt, "%pe [short-circuit]\n", dead); } } } @@ -2071,9 +2062,7 @@ static struct bfs_expr *simplify_or(struct bfs_opt *opt, struct bfs_expr *expr, struct bfs_exprs children; foster_children(expr, &children); - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (child == ignorable) { ignore = true; } @@ -2094,8 +2083,8 @@ static struct bfs_expr *simplify_or(struct bfs_opt *opt, struct bfs_expr *expr, bfs_expr_append(expr, child); if (child->always_true) { - while ((child = SLIST_POP(&children))) { - opt_delete(opt, "%pe [short-circuit]\n", child); + drain_slist (struct bfs_expr, dead, &children) { + opt_delete(opt, "%pe [short-circuit]\n", dead); } } } @@ -2117,9 +2106,7 @@ static struct bfs_expr *simplify_comma(struct bfs_opt *opt, struct bfs_expr *exp struct bfs_exprs children; foster_children(expr, &children); - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (opt->level >= 2 && child->pure && !SLIST_EMPTY(&children)) { if (!opt_ignore(opt, child, true)) { return NULL; |