diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributesNode.java
index 9bb878e1ecf6a293769a6c02f05f57060646b28a..ee6694464fc702ceb2be4ddfda8b7bf956e5a526 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributesNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributesNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,9 @@ import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RPairList;
+import com.oracle.truffle.r.runtime.data.RRaw;
+import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
@@ -65,16 +68,32 @@ public abstract class GetAttributesNode extends RBaseNode {
 
     public abstract Object execute(RAttributable attributable);
 
-    @Specialization
+    @Specialization(guards = "!isPairList(container)")
     protected Object attributesNull(RAbstractContainer container,
                     @Cached("createBinaryProfile()") ConditionProfile hasAttributesProfile) {
         if (hasAttributesProfile.profile(hasAttributes(container))) {
-            return createResult(container, container instanceof RLanguage);
+            return createResult(container, container instanceof RLanguage, null);
         } else {
             return RNull.instance;
         }
     }
 
+    @Specialization
+    @TruffleBoundary
+    protected Object attributesPairList(RPairList pairList) {
+        RStringVector names = pairList.getNames();
+        if (hasAttributes(pairList)) {
+            return createResult(pairList, false, names);
+        } else if (names != null) {
+            return RDataFactory.createList(new Object[] {names}, RDataFactory.createStringVector(RRuntime.NAMES_ATTR_KEY));
+        }
+        return RNull.instance;
+    }
+
+    protected static boolean isPairList(RAbstractContainer x) {
+        return x instanceof RPairList;
+    }
+
     /**
      * Unusual cases that it is not worth specializing on as they are not performance-centric,
      * basically any type that is not an {@link RAbstractContainer} but is {@link RAttributable},
@@ -84,7 +103,7 @@ public abstract class GetAttributesNode extends RBaseNode {
     @TruffleBoundary
     protected Object attributes(RAttributable object) {
         if (hasAttributes(object)) {
-            return createResult(object, false);
+            return createResult(object, false, null);
         } else {
             return RNull.instance;
         }
@@ -107,12 +126,17 @@ public abstract class GetAttributesNode extends RBaseNode {
     /**
      * {@code language} objects behave differently regarding "names"; they don't get included.
      */
-    private Object createResult(RAttributable attributable, boolean ignoreNames) {
+    private Object createResult(RAttributable attributable, boolean ignoreNames, RStringVector explicitNames) {
         DynamicObject attributes = attributable.getAttributes();
-        int size = attributes.size();
+        int size = attributes.size() + (explicitNames == null ? 0 : 1);
         String[] names = new String[size];
         Object[] values = new Object[size];
         int z = 0;
+        if (explicitNames != null) {
+            values[0] = explicitNames;
+            names[0] = RRuntime.NAMES_ATTR_KEY;
+            z = 1;
+        }
         for (RAttributesLayout.RAttribute attr : arrayAttrAccess.execute(attributes)) {
             String name = attr.getName();
             if (ignoreNames && name.equals(RRuntime.NAMES_ATTR_KEY)) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
index 80a0eb023b0a2415cb4553a190aed7898e04d7c8..e3be9c96ea3e37a40fd7df240ff2bfbe95fa3640 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
@@ -326,6 +326,9 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra
 
     @Override
     public RStringVector getNames() {
+        if (this.tag == RNull.instance) {
+            return null;
+        }
         int l = getLength();
         String[] data = new String[l];
         RPairList pl = this;
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 f5d0f59a8ec2837e8e31e6e0e53dbc93c41d6dcc..c35c33503ed0cde9fac550496c9d66d2305340ba 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
@@ -10358,6 +10358,31 @@ attr(,"Object created")
 a b c
 1 2 3
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_attributes.testAttributes#
+#attributes(pairlist(1,2,3))
+NULL
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_attributes.testAttributes#
+#attributes(pairlist(a=1, b=2))
+$names
+[1] "a" "b"
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_attributes.testAttributes#
+#attributes(structure(pairlist(1,2,3), myattr=42))
+$myattr
+[1] 42
+
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_attributes.testAttributes#
+#attributes(structure(pairlist(a=1,b=2,c=3), myattr=42))
+$names
+[1] "a" "b" "c"
+
+$myattr
+[1] 42
+
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_attributes.testAttributes#
 #{ e <- new.env(); attributes(e) <- list(a=1); attributes(e) }
 $a
@@ -41325,6 +41350,18 @@ Error in k() : argument "y" is missing, with no default
 #{ x <- quote(plot(x = age, y = weight)); names(x) }
 [1] ""  "x" "y"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_names.testNames#
+#names(pairlist(1,2,3))
+NULL
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_names.testNames#
+#names(pairlist(a=1,2,q=3))
+[1] "a" ""  "q"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_names.testNames#
+#names(pairlist(a=3, b=4))
+[1] "a" "b"
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_names.testNames#
 #v <- parse(text="useDynLib(digest, digest_impl=digest)"); names(v[[1]][3])
 [1] "digest_impl"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attributes.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attributes.java
index af13a6708d2465a36ad8d63b0cd1408130038d9c..d5425ad60c595995c9591d1886dfa45285e53db4 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attributes.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attributes.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -195,5 +195,10 @@ public class TestBuiltin_attributes extends TestBase {
 
         assertEval("{ e <- new.env(); attributes(e) <- list(a=1); attributes(e) }");
         assertEval("{ e <- new.env(); attributes(e) <- list(class=\"srcfile\"); attributes(e) }");
+
+        assertEval("attributes(pairlist(a=1, b=2))");
+        assertEval("attributes(pairlist(1,2,3))");
+        assertEval("attributes(structure(pairlist(1,2,3), myattr=42))");
+        assertEval("attributes(structure(pairlist(a=1,b=2,c=3), myattr=42))");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_names.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_names.java
index 174fa47cdafbf0d9eebbf262df35e699cdd8dead..147f9137f9ae7786841967d1d25194d966a49e6a 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_names.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_names.java
@@ -208,6 +208,9 @@ public class TestBuiltin_names extends TestBase {
         assertEval("{ e <- new.env(); names(e) <- c('a'); }");
         // FIXME: set names on language does not set the first name
         assertEval(Ignored.ImplementationError, "{ x <- parse(text='x+y')[[1]]; names(x) <- c('a','b','c'); names(x); }");
+        assertEval("names(pairlist(a=3, b=4))");
+        assertEval("names(pairlist(1,2,3))");
+        assertEval("names(pairlist(a=1,2,q=3))");
     }
 
     @Test