isl_multi_pw_aff_read_from_str: check domain constraint is free from output ids
authorSven Verdoolaege <sven@cerebras.net>
Fri, 21 May 2021 10:30:42 +0000 (21 12:30 +0200)
committerSven Verdoolaege <sven@cerebras.net>
Sat, 29 May 2021 08:23:41 +0000 (29 10:23 +0200)
Even though the output tuple of an isl_multi_pw_aff
is allowed to introduce new identifiers, the domain constraints
are not allowed to reference those identifiers.
If they do then this would result in invalid accesses
because read_formula is passed only the domain of the expression
while it was being passed in the names of all identifiers.
Drop the identifiers corresponding that appear in the output tuple
before calling read_formula.

Signed-off-by: Sven Verdoolaege <sven@cerebras.net>
Makefile.am
check_parse_fail_test_templ.c [new file with mode: 0644]
isl_input.c
isl_test.c

index 96cac65..4a9f682 100644 (file)
@@ -487,6 +487,7 @@ EXTRA_DIST = \
        bset_to_bmap.c \
        bset_from_bmap.c \
        isl_check_named_params_templ.c \
+       check_parse_fail_test_templ.c \
        check_reparse_templ.c \
        check_reparse_test_templ.c \
        check_single_reference_templ.c \
diff --git a/check_parse_fail_test_templ.c b/check_parse_fail_test_templ.c
new file mode 100644 (file)
index 0000000..6fba085
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021      Cerebras Systems
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege,
+ * Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA
+ */
+
+#define xCAT(A,B) A ## B
+#define CAT(A,B) xCAT(A,B)
+#undef TYPE
+#define TYPE CAT(isl_,BASE)
+#define xFN(TYPE,NAME) TYPE ## _ ## NAME
+#define FN(TYPE,NAME) xFN(TYPE,NAME)
+
+#undef TESTS
+#define TESTS CAT(parse_,CAT(BASE,_fail_tests))
+
+/* Test parsing of objects of type TYPE
+ * that are expected to fail.
+ */
+static isl_stat FN(check,TESTS)(isl_ctx *ctx)
+{
+       int i, n;
+       int on_error;
+
+       on_error = isl_options_get_on_error(ctx);
+       isl_options_set_on_error(ctx, ISL_ON_ERROR_CONTINUE);
+       n = ARRAY_SIZE(TESTS);
+       for (i = 0; i < n; ++i) {
+               TYPE *obj;
+
+               obj = FN(TYPE,read_from_str)(ctx, TESTS[i]);
+               FN(TYPE,free)(obj);
+               if (obj)
+                       break;
+       }
+       isl_options_set_on_error(ctx, on_error);
+       if (i < n)
+               isl_die(ctx, isl_error_unknown,
+                       "parsing not expected to succeed",
+                       return isl_stat_error);
+
+       return isl_stat_ok;
+}
index fced365..2e12704 100644 (file)
@@ -3989,10 +3989,14 @@ __isl_give isl_multi_aff *isl_multi_aff_read_from_str(isl_ctx *ctx,
  * is then converted into the isl_multi_pw_aff through a call
  * to extract_mpa_from_tuple and the domain of the result
  * is intersected with the domain.
+ *
+ * Note that the last tuple may introduce new identifiers,
+ * but these cannot be referenced in the description of the domain.
  */
 __isl_give isl_multi_pw_aff *isl_stream_read_multi_pw_aff(
        __isl_keep isl_stream *s)
 {
+       int n_dom;
        struct vars *v;
        isl_set *dom = NULL;
        isl_multi_pw_aff *tuple = NULL;
@@ -4011,17 +4015,20 @@ __isl_give isl_multi_pw_aff *isl_stream_read_multi_pw_aff(
        if (isl_stream_eat(s, '{'))
                goto error;
 
+       n_dom = v->n;
        tuple = read_tuple(s, v, 0, 0);
        if (!tuple)
                goto error;
        if (isl_stream_eat_if_available(s, ISL_TOKEN_TO)) {
                isl_map *map = map_from_tuple(tuple, dom, isl_dim_in, v, 0);
                dom = isl_map_domain(map);
+               n_dom = v->n;
                tuple = read_tuple(s, v, 0, 0);
                if (!tuple)
                        goto error;
        }
 
+       vars_drop(v, v->n - n_dom);
        if (isl_stream_eat_if_available(s, ':'))
                dom = read_formula(s, v, dom, 0);
 
index 9a5e394..295fb86 100644 (file)
@@ -135,6 +135,8 @@ static const char *reparse_multi_pw_aff_tests[] = {
        "[N] -> { [N] : N >= 0 }",
        "[N] -> { [N, N + 1] : N >= 0 }",
        "[N, M] -> { [(N : N >= 0), (M : M >= 0)] : N + M >= 0 }",
+       "{ [a] -> [b = a] }",
+       "{ [a] -> [b = a] : a >= 0 }",
 };
 
 #undef BASE
@@ -143,6 +145,16 @@ static const char *reparse_multi_pw_aff_tests[] = {
 #include "check_reparse_templ.c"
 #include "check_reparse_test_templ.c"
 
+/* String descriptions that cannot be parsed
+ * as multi piecewise affine expressions.
+ */
+static const char *parse_multi_pw_aff_fail_tests[] = {
+       "{ [a] -> [b] : b = a }",
+       "{ [a] -> [b = a] : b >= 0 }",
+};
+
+#include "check_parse_fail_test_templ.c"
+
 /* String descriptions of piecewise multi affine expressions
  * that are used for testing printing and parsing.
  */
@@ -191,6 +203,8 @@ static isl_stat test_parse_pma(isl_ctx *ctx)
  * an expression converted from a map with an output dimension name
  * that is equal to an automatically generated name, and
  * a set of expressions parsed from strings.
+ *
+ * Additionally, check some cases where parsing is supposed to fail.
  */
 static int test_parse_mpa(isl_ctx *ctx)
 {
@@ -227,6 +241,8 @@ static int test_parse_mpa(isl_ctx *ctx)
 
        if (check_reparse_multi_pw_aff_tests(ctx) < 0)
                return -1;
+       if (check_parse_multi_pw_aff_fail_tests(ctx) < 0)
+               return -1;
 
        return 0;
 }