native_types: Fix string_wrapper overloads

We should only coalesce to an r-value reference to our internal string if our
object is a move reference. This fixes ambiguous overloads with gcc9.
This also ensures that const references cannot be ambiguous with move
references by requiring a const volatile reference.

Change-Id: I31ed529c015cc311c9933acbc0f0a4aa50fed3a6
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/sdbusplus/message/native_types.hpp b/sdbusplus/message/native_types.hpp
index ace33be..cbbc6a5 100644
--- a/sdbusplus/message/native_types.hpp
+++ b/sdbusplus/message/native_types.hpp
@@ -32,15 +32,11 @@
     {
     }
 
-    operator std::string() const
+    operator const std::string&() const volatile&
     {
-        return str;
+        return const_cast<const string_wrapper<T>*>(this)->str;
     }
-    operator const std::string&() const
-    {
-        return str;
-    }
-    operator std::string &&()
+    operator std::string &&() &&
     {
         return std::move(str);
     }
diff --git a/test/message/native_types.cpp b/test/message/native_types.cpp
index 29dad22..3c9d20a 100644
--- a/test/message/native_types.cpp
+++ b/test/message/native_types.cpp
@@ -1,10 +1,13 @@
 #include <map>
 #include <sdbusplus/message.hpp>
+#include <string>
 #include <unordered_map>
 #include <vector>
 
 #include <gtest/gtest.h>
 
+using namespace std::string_literals;
+
 /* Suite tests that object_path and signature can be cleanly converted to
  * and from strings and used as container parameters.
  */
@@ -50,3 +53,19 @@
 
     ASSERT_EQ(u[sdbusplus::message::signature("iii")], 2);
 }
+
+TEST(MessageNativeTypeConversions, WrapperReference)
+{
+    auto orig = "str"s;
+    sdbusplus::message::object_path obj = orig;
+    auto out = static_cast<std::string>(obj);
+    EXPECT_EQ(orig, out);
+}
+
+TEST(MessageNativeTypeConversions, WrapperMove)
+{
+    auto orig = "str"s;
+    sdbusplus::message::object_path obj = orig;
+    auto out = static_cast<std::string>(std::move(obj));
+    EXPECT_EQ(orig, out);
+}