schema compile BUGFIX when cyclic check

... for cases when the context node differs
from the node that depends on the "when".
Fixes #2031
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 001a3af..71a3fed 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -519,7 +519,7 @@
 {
     struct lyxp_set tmp_set;
     struct lyxp_set_scnode *xp_scnode;
-    uint32_t i, j;
+    uint32_t i, j, idx;
     LY_ARRAY_COUNT_TYPE u;
     LY_ERR ret = LY_SUCCESS;
 
@@ -565,36 +565,46 @@
                 }
 
                 for (j = 0; j < tmp_set.used; ++j) {
-                    /* skip roots'n'stuff */
-                    if (tmp_set.val.scnodes[j].type == LYXP_NODE_ELEM) {
-                        /* try to find this node in our set */
-                        uint32_t idx;
-
-                        if (lyxp_set_scnode_contains(set, tmp_set.val.scnodes[j].scnode, LYXP_NODE_ELEM, -1, &idx) &&
-                                (set->val.scnodes[idx].in_ctx == LYXP_SET_SCNODE_START_USED)) {
-                            LOGVAL(set->ctx, LYVE_SEMANTICS, "When condition cyclic dependency on the node \"%s\".",
-                                    tmp_set.val.scnodes[j].scnode->name);
-                            ret = LY_EVALID;
-                            LOG_LOCBACK(1, 0, 0, 0);
-                            goto cleanup;
-                        }
-
-                        /* needs to be checked, if in both sets, will be ignored */
-                        tmp_set.val.scnodes[j].in_ctx = LYXP_SET_SCNODE_ATOM_CTX;
-                    } else {
-                        /* no when, nothing to check */
+                    if (tmp_set.val.scnodes[j].type != LYXP_NODE_ELEM) {
+                        /* skip roots'n'stuff, no when, nothing to check */
                         tmp_set.val.scnodes[j].in_ctx = LYXP_SET_SCNODE_ATOM_NODE;
+                        continue;
+                    }
+
+                    /* try to find this node in our set */
+                    if (lyxp_set_scnode_contains(set, tmp_set.val.scnodes[j].scnode, LYXP_NODE_ELEM, -1, &idx) &&
+                            (set->val.scnodes[idx].in_ctx == LYXP_SET_SCNODE_START_USED)) {
+                        LOGVAL(set->ctx, LYVE_SEMANTICS, "When condition cyclic dependency on the node \"%s\".",
+                                tmp_set.val.scnodes[j].scnode->name);
+                        ret = LY_EVALID;
+                        LOG_LOCBACK(1, 0, 0, 0);
+                        goto cleanup;
+                    }
+
+                    /* needs to be checked, if in both sets, will be ignored */
+                    tmp_set.val.scnodes[j].in_ctx = LYXP_SET_SCNODE_ATOM_CTX;
+                }
+
+                if (when->context != node) {
+                    /* node actually depends on this "when", not the context node */
+                    assert(tmp_set.val.scnodes[0].scnode == when->context);
+                    if (tmp_set.val.scnodes[0].in_ctx == LYXP_SET_SCNODE_START_USED) {
+                        /* replace the non-traversed context node with the dependent node */
+                        tmp_set.val.scnodes[0].scnode = (struct lysc_node *)node;
+                    } else {
+                        /* context node was traversed, so just add the dependent node */
+                        ret = lyxp_set_scnode_insert_node(&tmp_set, node, LYXP_SET_SCNODE_START_USED, LYXP_AXIS_CHILD, NULL);
+                        LY_CHECK_ERR_GOTO(ret, LOG_LOCBACK(1, 0, 0, 0), cleanup);
                     }
                 }
 
                 /* merge this set into the global when set */
                 lyxp_set_scnode_merge(set, &tmp_set);
             }
+            LOG_LOCBACK(1, 0, 0, 0);
 
             /* check when of non-data parents as well */
             node = node->parent;
-
-            LOG_LOCBACK(1, 0, 0, 0);
         } while (node && (node->nodetype & (LYS_CASE | LYS_CHOICE)));
 
         /* this node when was checked (xp_scnode could have been reallocd) */
@@ -640,6 +650,7 @@
 {
     struct lyxp_set tmp_set = {0};
     uint32_t i, opts;
+    struct lysc_node *schema;
     LY_ERR ret = LY_SUCCESS;
 
     opts = LYXP_SCNODE_SCHEMA | ((node->flags & LYS_IS_OUTPUT) ? LYXP_SCNODE_OUTPUT : 0);
@@ -655,28 +666,45 @@
     ctx->path[0] = '\0';
     lysc_path(node, LYSC_PATH_LOG, ctx->path, LYSC_CTX_BUFSIZE);
     for (i = 0; i < tmp_set.used; ++i) {
-        /* skip roots'n'stuff */
-        if ((tmp_set.val.scnodes[i].type == LYXP_NODE_ELEM) &&
-                (tmp_set.val.scnodes[i].in_ctx != LYXP_SET_SCNODE_START_USED)) {
-            struct lysc_node *schema = tmp_set.val.scnodes[i].scnode;
+        if (tmp_set.val.scnodes[i].type != LYXP_NODE_ELEM) {
+            /* skip roots'n'stuff */
+            continue;
+        } else if (tmp_set.val.scnodes[i].in_ctx == LYXP_SET_SCNODE_START_USED) {
+            /* context node not actually traversed */
+            continue;
+        }
 
-            /* XPath expression cannot reference "lower" status than the node that has the definition */
-            if (lysc_check_status(NULL, when->flags, node->module, node->name, schema->flags, schema->module,
-                    schema->name)) {
-                LOGWRN(ctx->ctx, "When condition \"%s\" may be referencing %s node \"%s\".", when->cond->expr,
-                        (schema->flags == LYS_STATUS_OBSLT) ? "obsolete" : "deprecated", schema->name);
-            }
+        schema = tmp_set.val.scnodes[i].scnode;
 
-            /* check dummy node children/value accessing */
-            if (lysc_data_parent(schema) == node) {
-                LOGVAL(ctx->ctx, LYVE_SEMANTICS, "When condition is accessing its own conditional node children.");
-                ret = LY_EVALID;
-                goto cleanup;
-            } else if ((schema == node) && (tmp_set.val.scnodes[i].in_ctx == LYXP_SET_SCNODE_ATOM_VAL)) {
-                LOGVAL(ctx->ctx, LYVE_SEMANTICS, "When condition is accessing its own conditional node value.");
-                ret = LY_EVALID;
-                goto cleanup;
-            }
+        /* XPath expression cannot reference "lower" status than the node that has the definition */
+        if (lysc_check_status(NULL, when->flags, node->module, node->name, schema->flags, schema->module,
+                schema->name)) {
+            LOGWRN(ctx->ctx, "When condition \"%s\" may be referencing %s node \"%s\".", when->cond->expr,
+                    (schema->flags == LYS_STATUS_OBSLT) ? "obsolete" : "deprecated", schema->name);
+        }
+
+        /* check dummy node children/value accessing */
+        if (lysc_data_parent(schema) == node) {
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "When condition is accessing its own conditional node children.");
+            ret = LY_EVALID;
+            goto cleanup;
+        } else if ((schema == node) && (tmp_set.val.scnodes[i].in_ctx == LYXP_SET_SCNODE_ATOM_VAL)) {
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "When condition is accessing its own conditional node value.");
+            ret = LY_EVALID;
+            goto cleanup;
+        }
+    }
+
+    if (when->context != node) {
+        /* node actually depends on this "when", not the context node */
+        assert(tmp_set.val.scnodes[0].scnode == when->context);
+        if (tmp_set.val.scnodes[0].in_ctx == LYXP_SET_SCNODE_START_USED) {
+            /* replace the non-traversed context node with the dependent node */
+            tmp_set.val.scnodes[0].scnode = (struct lysc_node *)node;
+        } else {
+            /* context node was traversed, so just add the dependent node */
+            ret = lyxp_set_scnode_insert_node(&tmp_set, node, LYXP_SET_SCNODE_START_USED, LYXP_AXIS_CHILD, NULL);
+            LY_CHECK_GOTO(ret, cleanup);
         }
     }