From bdba1ed7ea56ed382d6a670db0f992c14ac3a9d0 Mon Sep 17 00:00:00 2001
From: Miloslav Metelka <miloslav.metelka@oracle.com>
Date: Mon, 20 Nov 2017 15:03:11 +0100
Subject: [PATCH] AssertionError upon paste(NA) or paste(c(1,NA)).

---
 .../oracle/truffle/r/nodes/builtin/base/Paste.java | 14 +++++++++++++-
 .../oracle/truffle/r/test/ExpectedTestOutput.test  | 12 ++++++++++++
 .../truffle/r/test/builtins/TestBuiltin_paste.java |  3 +++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java
index 4db45a113d..eab25eb77c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java
@@ -44,6 +44,7 @@ import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
 import com.oracle.truffle.r.nodes.function.call.RExplicitBaseEnvCallDispatcher;
 import com.oracle.truffle.r.nodes.unary.CastNode;
 import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RIntSequence;
@@ -164,7 +165,18 @@ public abstract class Paste extends RBuiltinNode.Arg3 {
         if (emptyCnt == length) {
             return ONE_EMPTY_STRING;
         } else if (length == 1) {
-            return converted[0];
+            if (values.isComplete()) {
+                return converted[0];
+            } else {
+                // Clone array since it might be physical data array of a string vector
+                String[] result = converted[0].clone();
+                for (int j = result.length - 1; j >= 0; j--) {
+                    if (result[j] == RRuntime.STRING_NA) {
+                        result[j] = "NA";
+                    }
+                }
+                return result;
+            }
         } else {
             return prepareResult(sep, length, converted, maxLength);
         }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index d0a65ff2df..a9fb990216 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -46689,10 +46689,18 @@ character(0)
 #{ paste(1:2, 1:3, FALSE, collapse=NULL) }
 [1] "1 1 FALSE" "2 2 FALSE" "1 3 FALSE"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_paste.testPaste#
+#{ paste(NA) }
+[1] "NA"
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_paste.testPaste#
 #{ paste(NULL, list(), sep = "=") }
 character(0)
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_paste.testPaste#
+#{ paste(c(1,NA)) }
+[1] "1"  "NA"
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_paste.testPaste#
 #{ paste(character(0),31415) }
 [1] " 31415"
@@ -46701,6 +46709,10 @@ character(0)
 #{ paste(sep="") }
 character(0)
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_paste.testPaste#
+#{ s<-c('1',NA); paste(s); s; }
+[1] "1" NA
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_paste.testPasteWithS3AsCharacter#
 #{ as.character.myc <- function(x) '42'; val <- 'hello'; class(val) <- 'myc'; paste(val, 'world') }
 [1] "hello world"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_paste.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_paste.java
index d132fb4543..197cd5a603 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_paste.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_paste.java
@@ -81,6 +81,9 @@ public class TestBuiltin_paste extends TestBase {
         assertEval("{ paste(sep=\"\") }");
         assertEval("{ paste(1:2, 1:3, FALSE, collapse=\"-\", sep=\"+\") }");
         assertEval("{ paste(NULL, list(), sep = \"=\") }");
+        assertEval("{ paste(NA) }");
+        assertEval("{ paste(c(1,NA)) }");
+        assertEval("{ s<-c('1',NA); paste(s); s; }");
     }
 
     @Test
-- 
GitLab