Merge pull request #209 from sergiud/cmake-icc-fix
[platform/upstream/glog.git] / src / demangle_unittest.cc
index c07332a..be48341 100644 (file)
 #include "googletest.h"
 #include "config.h"
 
+#ifdef HAVE_LIB_GFLAGS
+#include <gflags/gflags.h>
+using namespace GFLAGS_NAMESPACE;
+#endif
+
 GLOG_DEFINE_bool(demangle_filter, false,
                  "Run demangle_unittest in filter mode");
 
@@ -57,18 +62,63 @@ static const char *DemangleIt(const char * const mangled) {
   }
 }
 
+#if defined(OS_WINDOWS)
+
+TEST(Demangle, Windows) {
+  EXPECT_STREQ(
+    "public: static void __cdecl Foo::func(int)",
+    DemangleIt("?func@Foo@@SAXH@Z"));
+  EXPECT_STREQ(
+    "public: static void __cdecl Foo::func(int)",
+    DemangleIt("@ILT+1105(?func@Foo@@SAXH@Z)"));
+  EXPECT_STREQ(
+    "int __cdecl foobarArray(int * const)",
+    DemangleIt("?foobarArray@@YAHQAH@Z"));
+}
+
+#else
+
 // Test corner cases of bounary conditions.
 TEST(Demangle, CornerCases) {
-  char tmp[10];
-  EXPECT_TRUE(Demangle("_Z6foobarv", tmp, sizeof(tmp)));
-  // sizeof("foobar()") == 9
-  EXPECT_STREQ("foobar()", tmp);
-  EXPECT_TRUE(Demangle("_Z6foobarv", tmp, 9));
-  EXPECT_STREQ("foobar()", tmp);
-  EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 8));  // Not enough.
-  EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 1));
-  EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 0));
-  EXPECT_FALSE(Demangle("_Z6foobarv", NULL, 0));  // Should not cause SEGV.
+  const size_t size = 10;
+  char tmp[size] = { 0 };
+  const char *demangled = "foobar()";
+  const char *mangled = "_Z6foobarv";
+  EXPECT_TRUE(Demangle(mangled, tmp, sizeof(tmp)));
+  // sizeof("foobar()") == size - 1
+  EXPECT_STREQ(demangled, tmp);
+  EXPECT_TRUE(Demangle(mangled, tmp, size - 1));
+  EXPECT_STREQ(demangled, tmp);
+  EXPECT_FALSE(Demangle(mangled, tmp, size - 2));  // Not enough.
+  EXPECT_FALSE(Demangle(mangled, tmp, 1));
+  EXPECT_FALSE(Demangle(mangled, tmp, 0));
+  EXPECT_FALSE(Demangle(mangled, NULL, 0));  // Should not cause SEGV.
+}
+
+// Test handling of functions suffixed with .clone.N, which is used by GCC
+// 4.5.x, and .constprop.N and .isra.N, which are used by GCC 4.6.x.  These
+// suffixes are used to indicate functions which have been cloned during
+// optimization.  We ignore these suffixes.
+TEST(Demangle, Clones) {
+  char tmp[20];
+  EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  // Invalid (truncated), should not demangle.
+  EXPECT_FALSE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp)));
+  // Invalid (.clone. not followed by number), should not demangle.
+  EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp)));
+  // Invalid (.clone. followed by non-number), should not demangle.
+  EXPECT_FALSE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp)));
+  // Invalid (.constprop. not followed by number), should not demangle.
+  EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp)));
 }
 
 TEST(Demangle, FromFile) {
@@ -92,6 +142,8 @@ TEST(Demangle, FromFile) {
   }
 }
 
+#endif
+
 int main(int argc, char **argv) {
 #ifdef HAVE_LIB_GFLAGS
   ParseCommandLineFlags(&argc, &argv, true);