Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-62064

CPS-transformed assignment expressions evaluate to null instead of the value of the RHS

    • workflow-cps 3520.va_8fc49e2f96f

      As described in https://stackoverflow.com/questions/61420959/jenkins-interpretation-of-multiple-object-declarations-on-one-line, CPS-transformed assignment expressions evaluate to null instead of the value of the RHS of the expression. Here is an example:

      def a = b = c = 1 

      In a Pipeline, after executing that expression a == null, b == null, and c == 1.

      In regular Groovy, after executing that expression, a, b, and c, are all equal to 1.

      Here is a (failing) workflow-cps test case (for CpsFlowDefinition2Test) that demonstrates the bug:

      @Test public void assignmentExprsReturnRhs() throws Exception {
          WorkflowJob p = jenkins.createProject(WorkflowJob.class);
          p.setDefinition(new CpsFlowDefinition(
                  "def a = b = c = 1\n" +
                  "println([a, b, c].toString())", true));
          WorkflowRun b = jenkins.buildAndAssertSuccess(p);
          jenkins.assertLogContains("[1, 1, 1]", b); // Actual output today is "[null, null, 1]".
      } 

      I think the relevant code is AssignmentBlock in groovy-cps. In particular, I think that assignAndDone needs to create a new continuation to pass to lhs.set that calls k.receive(rhs) internally.

          [JENKINS-62064] CPS-transformed assignment expressions evaluate to null instead of the value of the RHS

          Justin Vallon added a comment -

          Variations, where assignment is used in conditionals:

          Object o;
          boolean looped = false;
          for (; o = "abc"; ) {
            looped = true;
            break;
          }
          assert looped; // should be true; CPS gives false
          
          boolean x;
          boolean q = false;
          while (x = true) {
              q = true;
              break;
          }
          assert q; // fails in CPS
          

          I see there is a merged PR.

          Justin Vallon added a comment - Variations, where assignment is used in conditionals: Object o; boolean looped = false ; for (; o = "abc" ; ) { looped = true ; break ; } assert looped; // should be true ; CPS gives false boolean x; boolean q = false ; while (x = true ) { q = true ; break ; } assert q; // fails in CPS I see there is a merged PR.

          Devin Nusbaum added a comment -

          A fix has been merged but not yet released. I plan on releasing the fix in the next week or so.

          Devin Nusbaum added a comment - A fix has been merged but not yet released. I plan on releasing the fix in the next week or so.

          Justin Vallon added a comment -

          Tried the following test case in CpsTransformerTest - succeeds with the fix, fails without commit e55920d.

              @Test
              public void loopConditionWithAssignment() throws Throwable {
                  assertEvaluate(Arrays.asList(true, true),
                                 "boolean t = false;\n"+
                                 "Object o;\n"+
                                 "for (; o = true; ) { t = true; break; }\n"+
                                 "[ t, o ]");
                  assertEvaluate(Arrays.asList(true, true),
                                 "boolean t = false;\n"+
                                 "Object o;\n"+
                                 "while (o = true) { t = true; break; }\n"+
                                 "[ t, o ]");
              }
          

          Justin Vallon added a comment - Tried the following test case in CpsTransformerTest - succeeds with the fix, fails without commit e55920d. @Test public void loopConditionWithAssignment() throws Throwable { assertEvaluate(Arrays.asList( true , true ), " boolean t = false ;\n" + " Object o;\n" + " for (; o = true ; ) { t = true ; break ; }\n" + "[ t, o ]" ); assertEvaluate(Arrays.asList( true , true ), " boolean t = false ;\n" + " Object o;\n" + " while (o = true ) { t = true ; break ; }\n" + "[ t, o ]" ); }

          Devin Nusbaum added a comment -

          A fix for this issue was just released in Pipeline: Groovy Plugin version 3520.va_8fc49e2f96f.

          Devin Nusbaum added a comment - A fix for this issue was just released in Pipeline: Groovy Plugin version 3520.va_8fc49e2f96f .

            dnusbaum Devin Nusbaum
            dnusbaum Devin Nusbaum
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: