From 0ef3089c5eaf5054ad3aa7b20885e1e555a2f6ca Mon Sep 17 00:00:00 2001
From: Miloslav Metelka <miloslav.metelka@oracle.com>
Date: Mon, 13 Aug 2018 16:55:10 +0200
Subject: [PATCH] Fixed UpdateAttributes on NULL.

---
 .../nodes/builtin/base/UpdateAttributes.java  |  7 ++-
 .../truffle/r/test/ExpectedTestOutput.test    | 44 ++++++++++++++++++-
 .../TestBuiltin_attributesassign.java         |  3 +-
 3 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java
index 590f92f883..5dfcd622a4 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java
@@ -51,6 +51,7 @@ import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RComplex;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RRaw;
@@ -284,7 +285,11 @@ public abstract class UpdateAttributes extends RBuiltinNode.Arg2 {
 
     @Specialization(guards = {"!isRAttributable(o)", "!isScalar(o)"})
     protected Object doFallback(@SuppressWarnings("unused") Object o, @SuppressWarnings("unused") Object operand) {
-        throw error(RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS);
+        if (o == RNull.instance) {
+            return (operand != RNull.instance) ? doOtherNull(RDataFactory.createList(), operand) : o;
+        } else {
+            throw error(RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS);
+        }
     }
 
     protected static boolean isScalar(Object o) {
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 f31cfed5fb..bdb20bc4c5 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
@@ -11205,10 +11205,16 @@ Error in attributes(x) <- 44 : attributes must be a list or NULL
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_attributesassign.testArgsCasts#
 #x <- 42;  attributes(x) <- list()
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_attributesassign.testattributesassign1#Ignored.ImplementationError#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_attributesassign.testattributesassign1#
 #argv <- list(NULL, NULL);`attributes<-`(argv[[1]],argv[[2]]);
 NULL
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_attributesassign.testattributesassign1#
+#{ `attributes<-`(NULL, list(a=42)) }
+list()
+attr(,"a")
+[1] 42
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_attributesassign.testattributesassign2#Output.IgnoreWhitespace#
 #argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = 'data.frame'), structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = 'data.frame'));`attributes<-`(argv[[1]],argv[[2]]);
 [[1]]
@@ -42951,6 +42957,11 @@ $<NA>
 #{ z <- c(a=1, b=2) ; names(z) <- NULL ; z }
 [1] 1 2
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_namesassign.testUpdateNamesByFactors#
+#{ x <- c(1,2,1,3); f <- factor(x, labels = c("a","b","c")); names(x)<-f; x; }
+a b a c
+1 2 1 3
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_namesassign.testnamesassign1#
 #argv <- list(structure(list(happy = c('a', 'b', 'c', 'd'), sad = c('A', 'B', 'C', 'D', 'E', 'F')), .Names = c('happy', 'sad')), value = c('happy', 'sad'));`names<-`(argv[[1]],argv[[2]]);
 $happy
@@ -77280,6 +77291,10 @@ Error in tempfile(integer()) : invalid filename pattern
 #... ~ 0 + x
 ... ~ 0 + x
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_tilde.testTildeDirect#
+#x * ~y
+Error: object 'x' not found
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_tilde.testTildeDirect#
 #x ~ y + z
 x ~ y + z
@@ -87176,6 +87191,33 @@ $e
 #{ pi/180; pi }
 [1] 3.141593
 
+##com.oracle.truffle.r.test.library.base.TestSharedCluster.testSharedCluster#
+#library(parallel); fun <- function(data) { cl <- makeCluster(1, ifelse(exists('engine', where=R.version),'SHARED','PSOCK')); parLapply(cl, data, function(x) x+1); stopCluster(cl) }; fun(1:100)
+
+##com.oracle.truffle.r.test.library.base.TestSharedCluster.testSharedCluster#
+#library(parallel); fun <- function(data) { cl <- makeCluster(2, ifelse(exists('engine', where=R.version),'SHARED','PSOCK')); parLapply(cl, data, function(x) x+1); stopCluster(cl) }; fun(1:100)
+
+##com.oracle.truffle.r.test.library.base.TestSharedCluster.testSharedCluster#
+#library(parallel); fun <- function(data) { cl <- makeCluster(3, ifelse(exists('engine', where=R.version),'SHARED','PSOCK')); parLapply(cl, data, function(x) x+1); stopCluster(cl) }; fun(1:100)
+
+##com.oracle.truffle.r.test.library.base.TestSharedCluster.testSharedCluster#
+#library(parallel); fun <- function(data) { cl <- makeCluster(4, ifelse(exists('engine', where=R.version),'SHARED','PSOCK')); parLapply(cl, data, function(x) x+1); stopCluster(cl) }; fun(1:100)
+
+##com.oracle.truffle.r.test.library.base.TestSharedCluster.testSharedCluster#
+#library(parallel); fun <- function(data) { cl <- makeCluster(5, ifelse(exists('engine', where=R.version),'SHARED','PSOCK')); parLapply(cl, data, function(x) x+1); stopCluster(cl) }; fun(1:100)
+
+##com.oracle.truffle.r.test.library.base.TestSharedCluster.testSharedCluster#
+#library(parallel); fun <- function(data) { cl <- makeCluster(6, ifelse(exists('engine', where=R.version),'SHARED','PSOCK')); parLapply(cl, data, function(x) x+1); stopCluster(cl) }; fun(1:100)
+
+##com.oracle.truffle.r.test.library.base.TestSharedCluster.testSharedCluster#
+#library(parallel); fun <- function(data) { cl <- makeCluster(7, ifelse(exists('engine', where=R.version),'SHARED','PSOCK')); parLapply(cl, data, function(x) x+1); stopCluster(cl) }; fun(1:100)
+
+##com.oracle.truffle.r.test.library.base.TestSharedCluster.testSharedCluster#
+#library(parallel); fun <- function(data) { cl <- makeCluster(8, ifelse(exists('engine', where=R.version),'SHARED','PSOCK')); parLapply(cl, data, function(x) x+1); stopCluster(cl) }; fun(1:100)
+
+##com.oracle.truffle.r.test.library.base.TestSharedCluster.testSharedCluster#
+#library(parallel); fun <- function(data) { cl <- makeCluster(9, ifelse(exists('engine', where=R.version),'SHARED','PSOCK')); parLapply(cl, data, function(x) x+1); stopCluster(cl) }; fun(1:100)
+
 ##com.oracle.truffle.r.test.library.base.TestSimpleArithmetic.testArithmeticUpdate#
 #{ x <- 3 ; f <- function(z) { if (z) { x <- 1 } ; x <- 1L + x ; x } ; f(FALSE) }
 [1] 4
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attributesassign.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attributesassign.java
index 829f9b0976..6ef1588f93 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attributesassign.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attributesassign.java
@@ -30,7 +30,8 @@ public class TestBuiltin_attributesassign extends TestBase {
     @Test
     public void testattributesassign1() {
         // FIXME According to docs NULL object is allowed (coerced to empty list)
-        assertEval(Ignored.ImplementationError, "argv <- list(NULL, NULL);`attributes<-`(argv[[1]],argv[[2]]);");
+        assertEval("{ `attributes<-`(NULL, list(a=42)) }");
+        assertEval("argv <- list(NULL, NULL);`attributes<-`(argv[[1]],argv[[2]]);");
     }
 
     @Test
-- 
GitLab