From c522052cfb0e14ef8ab78731e78a3cb547a07a5e Mon Sep 17 00:00:00 2001 From: Jason N Date: Wed, 29 Mar 2023 09:39:21 +1100 Subject: [PATCH] Disallow coercion of sets into multidimensional arrays Fixes #656 --- changes.rst | 1 + lib/typecheck.cpp | 7 ++++++- tests/spec/unit/regression/github_656.mzn | 10 ++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/spec/unit/regression/github_656.mzn diff --git a/changes.rst b/changes.rst index 5f5c7a7a1..ab95e4c32 100644 --- a/changes.rst +++ b/changes.rst @@ -70,6 +70,7 @@ Bug fixes: - Fix handling of domains for tuple and record types. - Fix index set checking for tuples and records which contain arrays. - Fix the handling of domain and index set expressions in aliases. +- Fix incorrect coercion of sets into multidimensional arrays (:bugref:`656`). .. _v2.7.0: diff --git a/lib/typecheck.cpp b/lib/typecheck.cpp index 32d56708a..8a3d4eb22 100644 --- a/lib/typecheck.cpp +++ b/lib/typecheck.cpp @@ -1447,13 +1447,18 @@ KeepAlive add_coercion(EnvI& env, Model* m, Expression* e, const Type& funarg_t) } GCLock lock; Call* c = nullptr; - if (e->type().dim() == 0 && funarg_t.dim() != 0) { + if (e->type().isSet() && funarg_t.dim() != 0) { if (e->type().isvar()) { throw TypeError(env, e->loc(), "cannot coerce var set into array"); } if (e->type().isOpt()) { throw TypeError(env, e->loc(), "cannot coerce opt set into array"); } + if (funarg_t.dim() > 1) { + std::stringstream ss; + ss << "cannot coerce set into " << funarg_t.dim() << "-dimensional array"; + throw TypeError(env, e->loc(), ss.str()); + } std::vector set2a_args(1); set2a_args[0] = e; Call* set2a = Call::a(e->loc(), ASTString("set2array"), set2a_args); diff --git a/tests/spec/unit/regression/github_656.mzn b/tests/spec/unit/regression/github_656.mzn new file mode 100644 index 000000000..5a173febf --- /dev/null +++ b/tests/spec/unit/regression/github_656.mzn @@ -0,0 +1,10 @@ +/*** +!Test +solvers: +- gecode +expected: !Error + regex: .*cannot coerce set into 2-dimensional array.* +***/ + +% Previously sets were incorrectly allowed to coerce to multidimensional arrays. +output [show2d(1..2)];