[libcxxabi] r184668 - After a private conversation with Arthur O'Dwyer, and a good night's sleep, I believe this fix is a better fix than what I committed in r184656 yesterday. I've basically moved the checking for '`' from the start of the demangling process to the end of it. In the process I discovered that one of the test cases no longer demangled to the expected string. After further investigation I believe this case to not be a valid mangled string, and so I moved the test case to the 'invalid cases...

Howard Hinnant hhinnant at apple.com
Sun Jun 23 10:14:35 PDT 2013


Author: hhinnant
Date: Sun Jun 23 12:14:35 2013
New Revision: 184668

URL: http://llvm.org/viewvc/llvm-project?rev=184668&view=rev
Log:
After a private conversation with Arthur O'Dwyer, and a good night's sleep, I believe this fix is a better fix than what I committed in r184656 yesterday.  I've basically moved the checking for '`' from the start of the demangling process to the end of it.  In the process I discovered that one of the test cases no longer demangled to the expected string.  After further investigation I believe this case to not be a valid mangled string, and so I moved the test case to the 'invalid cases'.  The reason I believe it is invalid is that it should use T_ instead of T0_ to index the template parameter.

Modified:
    libcxxabi/trunk/src/cxa_demangle.cpp
    libcxxabi/trunk/test/test_demangle.cpp

Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=184668&r1=184667&r2=184668&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Sun Jun 23 12:14:35 2013
@@ -4382,7 +4382,7 @@ template <class C>
 void
 demangle(const char* first, const char* last, C& db, int& status)
 {
-    if (first >= last || std::find(first, last, '`') != last)
+    if (first >= last)
     {
         status = invalid_mangled_name;
         return;
@@ -4423,21 +4423,52 @@ demangle(const char* first, const char*
         if (t != last)
             status = invalid_mangled_name;
     }
+    if (status == success && db.names.empty())
+        status = invalid_mangled_name;
     if (status == success && db.fix_forward_references)
     {
-        db.names.reserve(db.names.size()+1);
-        auto& nm = db.names.back().first;
+        auto nm = db.names.back().move_full();
+        db.names.pop_back();
         size_t p = nm.size();
         while (p != 0)
         {
             if (nm[--p] == '`')
             {
+                size_t k0 = db.names.size();
                 const char* t = parse_template_param(&nm[p+1], &nm[nm.size()], db);
-                auto s = db.names.back().move_full();
-                db.names.pop_back();
-                nm.replace(p, static_cast<std::size_t>(t - &nm[p]), s);
+                size_t k1 = db.names.size();
+                if (t == &nm[p+1])
+                {
+                    status = invalid_mangled_name;
+                    return;
+                }
+                if (k1 == k0)
+                {
+                    nm.erase(p, static_cast<std::size_t>(t - &nm[p]));
+                }
+                else
+                {
+                    if (db.names[k0].first.front() == '`')
+                    {
+                        status = invalid_mangled_name;
+                        return;
+                    }
+                    size_t p2 = static_cast<size_t>(t - &nm[p]);
+                    size_t s = db.names[k0].size();
+                    nm.replace(p, p2, db.names[k0].move_full());
+                    p2 = p + s;
+                    for (size_t k = k0+1; k < k1; ++k)
+                    {
+                        s = db.names[k].size() + 2;
+                        nm.insert(p2, ", " + db.names[k].move_full());
+                        p2 += s;
+                    }
+                    for (; k1 > k0; --k1)
+                        db.names.pop_back();
+                }
             }
         }
+        db.names.push_back(std::move(nm));
     }
 }
 

Modified: libcxxabi/trunk/test/test_demangle.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.cpp?rev=184668&r1=184667&r2=184668&view=diff
==============================================================================
--- libcxxabi/trunk/test/test_demangle.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.cpp Sun Jun 23 12:14:35 2013
@@ -29575,7 +29575,6 @@ const char* cases[][2] =
     {"_ZSteqIcEN9__gnu_cxx11__enable_ifIXsr9__is_charIT_EE7__valueEbE6__typeERKSbIS2_St11char_traitsIS2_ESaIS2_EESA_", "__gnu_cxx::__enable_if<__is_char<char>::__value, bool>::__type std::operator==<char>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)"},
     {"_ZZ10+[Foo bar]E3Baz", "+[Foo bar]::Baz"},
     {"_ZN9__gnu_cxx17__normal_iteratorIPKSt4pairISsbESt6vectorIS2_SaIS2_EEEC5ERKS4_", "__gnu_cxx::__normal_iterator<std::pair<std::string, bool> const*, std::vector<std::pair<std::string, bool>, std::allocator<std::pair<std::string, bool> > > >::__normal_iterator(std::pair<std::string, bool> const* const&)"},
-    {"_ZNSt16allocator_traitsISaIN4llvm3sys2fs18directory_iteratorEEE9constructIS3_IS3_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS4_PT_DpOS7_", "decltype(_S_construct(fpfp0forward<`T0_>(fp1))) std::allocator_traits<std::allocator<llvm::sys::fs::directory_iterator> >::construct<llvm::sys::fs::directory_iterator<llvm::sys::fs::directory_iterator> >(std::allocator<llvm::sys::fs::directory_iterator>&, llvm::sys::fs::directory_iterator<llvm::sys::fs::directory_iterator>*, llvm::sys::fs::directory_iterator<llvm::sys::fs::directory_iterator>&&)"},
     {"_Z1fIiEDTeqfp_LDnEEPT_", "decltype((fp) == (std::nullptr_t)) f<int>(int*)"},
     {"_Z1fIiEDTeqfp1_LDnEEicPT_", "decltype((fp1) == (std::nullptr_t)) f<int>(int, char, int*)"},
     {"_ZZN1S1fEiiEd0_NKUlvE_clEv", "S::f(int, int)::'lambda'()::operator()() const"},
@@ -29594,6 +29593,7 @@ const char* invalid_cases[] =
     "NSoERj5E=Y1[uM:ga",
     "Aon_PmKVPDk7?fg4XP5smMUL6;<WsI_mgbf23cCgsHbT<l8EE\0uVRkNOoXDrgdA4[8IU>Vl<>IL8ayHpiVDDDXTY;^o9;i",
     "_ZN8Blizza`d6Memory12voidp_returncvPT_IcEEv",
+    "_ZNSt16allocator_traitsISaIN4llvm3sys2fs18directory_iteratorEEE9constructIS3_IS3_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS4_PT_DpOS7_",
 };
 
 const unsigned NI = sizeof(invalid_cases) / sizeof(invalid_cases[0]);





More information about the cfe-commits mailing list