From 631ea8530155d6c8de2160ee7e24060f700364b9 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 1 May 2014 12:11:27 +0200 Subject: [PATCH] isl_ast_build_expr_from_set: return valid result on empty set When presented with an empty set, isl_ast_build_expr_from_set would simply return the value NULL, indicating a failure. Although there should be no need to call isl_ast_build_expr_from_set on an empty set, we should not fail silently. We choose to return a valid expression rather than requiring a non-empty input. Although it is currently possible for the isl_ast_build_expr_from_set to get called on an empty set, the only known test cases that reach this point only do so due to another bug that will be fixed in the next commit. We therefore test the low-level function instead just in case it ever gets exported. Signed-off-by: Sven Verdoolaege --- isl_ast_build_expr.c | 6 ++++++ isl_test.c | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/isl_ast_build_expr.c b/isl_ast_build_expr.c index b0fdbb9d..f8ee07f8 100644 --- a/isl_ast_build_expr.c +++ b/isl_ast_build_expr.c @@ -1201,6 +1201,8 @@ static int expr_from_set(__isl_take isl_basic_set *bset, void *user) /* Construct an isl_ast_expr that evaluates the conditions defining "set". * The result is simplified in terms of build->domain. + * + * If "set" is an (obviously) empty set, then return the expression "0". */ __isl_give isl_ast_expr *isl_ast_build_expr_from_set( __isl_keep isl_ast_build *build, __isl_take isl_set *set) @@ -1209,6 +1211,10 @@ __isl_give isl_ast_expr *isl_ast_build_expr_from_set( if (isl_set_foreach_basic_set(set, &expr_from_set, &data) < 0) data.res = isl_ast_expr_free(data.res); + else if (data.first) { + isl_ctx *ctx = isl_ast_build_get_ctx(build); + data.res = isl_ast_expr_from_val(isl_val_zero(ctx)); + } isl_set_free(set); return data.res; diff --git a/isl_test.c b/isl_test.c index f96d5466..dd5ce590 100644 --- a/isl_test.c +++ b/isl_test.c @@ -30,6 +30,7 @@ #include #include #include +#include #define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array)) @@ -4331,6 +4332,31 @@ static int test_ast(isl_ctx *ctx) return 0; } +/* Check that isl_ast_build_expr_from_set returns a valid expression + * for an empty set. Note that isl_ast_build_expr_from_set getting + * called on an empty set probably indicates a bug in the caller. + */ +static int test_ast_build(isl_ctx *ctx) +{ + isl_set *set; + isl_ast_build *build; + isl_ast_expr *expr; + + set = isl_set_universe(isl_space_params_alloc(ctx, 0)); + build = isl_ast_build_from_context(set); + + set = isl_set_empty(isl_space_params_alloc(ctx, 0)); + expr = isl_ast_build_expr_from_set(build, set); + + isl_ast_expr_free(expr); + isl_ast_build_free(build); + + if (!expr) + return -1; + + return 0; +} + /* Internal data structure for before_for and after_for callbacks. * * depth is the current depth @@ -4881,6 +4907,7 @@ struct { { "preimage", &test_preimage }, { "pullback", &test_pullback }, { "AST", &test_ast }, + { "AST build", &test_ast_build }, { "AST generation", &test_ast_gen }, { "eliminate", &test_eliminate }, { "residue class", &test_residue_class }, -- 2.11.4.GIT