From 238e0cc7186e3ccf6cf0400c1b94388255cb7fde Mon Sep 17 00:00:00 2001
From: Tomas Stupka <tomas.stupka@oracle.com>
Date: Mon, 4 Dec 2017 13:57:33 +0100
Subject: [PATCH] complete flag on logical vector wasn't properly set on
 creation

---
 .../access/vector/ExtractVectorNodeTest.java     | 16 +++++++++++++++-
 .../r/nodes/binary/BinaryBooleanScalarNode.java  |  3 ++-
 .../truffle/r/runtime/data/RDataFactory.java     |  2 +-
 .../com/oracle/truffle/r/runtime/data/RList.java |  6 ++++++
 .../r/runtime/data/model/RAbstractVector.java    |  2 ++
 5 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java
index 7461c2db64..493c99a196 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java
@@ -217,15 +217,29 @@ public class ExtractVectorNodeTest extends TestBase {
     }
 
     @Theory
-    public void testCompletenessAfterExtraction(RType targetType) {
+    public void testCompletenessAfterScalarExtraction(RType targetType) {
         RAbstractVector vector = generateVector(targetType, 4, false);
 
+        assumeTrue(targetType != RType.List);
         assumeThat(vector.isComplete(), is(false));
         RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(1));
 
         assertThat(result.isComplete(), is(true));
     }
 
+    @Theory
+    public void testCompletenessAfterExtraction(RType targetType) {
+        RAbstractVector vector = generateVector(targetType, 4, false);
+
+        assumeTrue(targetType != RType.List);
+        assumeThat(vector.isComplete(), is(false));
+        // extract some non NA elements
+        int[] positions = targetType == RType.Complex ? new int[]{1, 3} : new int[]{1, 2};
+        RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RDataFactory.createIntVector(positions, true));
+
+        assertThat(result.isComplete(), is(true));
+    }
+
     @Theory
     public void testCompletenessAfterSelectAll(RType targetType) {
         RAbstractVector vector = generateVector(targetType, 4, false);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java
index 24672b6082..79066816d0 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java
@@ -120,11 +120,12 @@ public abstract class BinaryBooleanScalarNode extends RBuiltinNode.Arg2 {
         }
 
         private byte castImpl(RAbstractVector vector) {
-            this.check.enable(!vector.isComplete());
             if (vector.getLength() == 0) {
                 seenEmpty.enter();
+                this.check.enable(true);
                 return RRuntime.LOGICAL_NA;
             }
+            this.check.enable(!vector.isComplete());
             RType type = vector.getRType();
             CompilerAsserts.compilationConstant(type);
             switch (type) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
index 2587193a85..4d2214df1c 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
@@ -967,7 +967,7 @@ public final class RDataFactory {
         if (fillNA) {
             Arrays.fill(data, RRuntime.LOGICAL_NA);
         }
-        return createLogicalVector(data, false);
+        return createLogicalVector(data, !fillNA);
     }
 
     public static RLogicalVector createLogicalVector(byte[] data, boolean complete) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
index ee3847e78b..c886692fd1 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
@@ -28,10 +28,16 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.data.nodes.FastPathVectorAccess.FastPathFromListAccess;
 import com.oracle.truffle.r.runtime.data.nodes.SlowPathVectorAccess.SlowPathFromListAccess;
 import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
 
+/**
+ * A note on the RList complete flag {@link RAbstractVector#isComplete() } - it is always
+ * initialized with <code>false</code> in {@link RListBase#RListBase(java.lang.Object[])} and never
+ * expected to change.
+ */
 public final class RList extends RListBase implements RAbstractListVector {
 
     public String elementNamePrefix;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java
index 43039d80a1..73637118f3 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java
@@ -116,6 +116,8 @@ public interface RAbstractVector extends RAbstractContainer {
                     assert access.getListElement(iter) != null : "element " + iter.getIndex() + " of vector " + vector + " is null";
                 }
             }
+        } else if (access.getType() == RType.List) {
+            assert !vector.isComplete();
         }
         if (vector.isComplete()) {
             // check all vectors for completeness
-- 
GitLab