[PATCH] D33368: [libcxxabi][demangler] Fix a crash in the demangler
Erik Pilkington via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri May 19 14:15:09 PDT 2017
erik.pilkington created this revision.
Herald added a reviewer: EricWF.
This patch fixes a bug in the demangler where a pack expansion template parameter substitution with more than one element in a lambda's parameter list resulted in either a misdemangle or a crash. I'll commit this change to ItaniumDemangle.cpp as well, as it has the same problem.
rdar://32098667
Thanks for taking a look,
Erik
https://reviews.llvm.org/D33368
Files:
src/cxa_demangle.cpp
test/test_demangle.pass.cpp
Index: test/test_demangle.pass.cpp
===================================================================
--- test/test_demangle.pass.cpp
+++ test/test_demangle.pass.cpp
@@ -29604,6 +29604,7 @@
{"PFvRmOE", "void (*)(unsigned long&) &&"},
{"_ZTW1x", "thread-local wrapper routine for x"},
{"_ZTHN3fooE", "thread-local initialization routine for foo"},
+ {"_Z4algoIJiiiEEvZ1gEUlT_E_", "void algo<int, int, int>(g::'lambda'(int, int, int))"},
};
const unsigned N = sizeof(cases) / sizeof(cases[0]);
Index: src/cxa_demangle.cpp
===================================================================
--- src/cxa_demangle.cpp
+++ src/cxa_demangle.cpp
@@ -3015,6 +3015,7 @@
break;
case 'l':
{
+ size_t lambda_pos = db.names.size();
db.names.push_back(typename C::String("'lambda'("));
const char* t0 = first+2;
if (first[2] == 'v')
@@ -3024,36 +3025,42 @@
}
else
{
- const char* t1 = parse_type(t0, last, db);
- if (t1 == t0)
- {
- if(!db.names.empty())
- db.names.pop_back();
- return first;
- }
- if (db.names.size() < 2)
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first.append(tmp);
- t0 = t1;
+ bool is_first_it = true;
while (true)
{
- t1 = parse_type(t0, last, db);
+ size_t k0 = db.names.size();
+ const char* t1 = parse_type(t0, last, db);
+ size_t k1 = db.names.size();
if (t1 == t0)
break;
- if (db.names.size() < 2)
+ if (k1 <= k0)
return first;
- tmp = db.names.back().move_full();
- db.names.pop_back();
- if (!tmp.empty())
- {
- db.names.back().first.append(", ");
- db.names.back().first.append(tmp);
+ // If the call to parse_type above found a pack expansion
+ // substitution, then multiple names could have been
+ // inserted into the name table. Walk through the names,
+ // appending each onto the lambda's parameter list.
+ for (size_t k = k0; k < k1; ++k) {
+ auto tmp = db.names[k].move_full();
+ if (!tmp.empty())
+ {
+ if (!is_first_it)
+ db.names[lambda_pos].first.append(", ");
+ is_first_it = false;
+ db.names[lambda_pos].first.append(tmp);
+ }
}
+ db.names.erase(db.names.begin() +
+ static_cast<long>(lambda_pos) + 1,
+ db.names.end());
t0 = t1;
}
- if(db.names.empty())
+ if (is_first_it)
+ {
+ if (!db.names.empty())
+ db.names.pop_back();
+ return first;
+ }
+ if (db.names.empty() || db.names.size() - 1 != lambda_pos)
return first;
db.names.back().first.append(")");
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33368.99625.patch
Type: text/x-patch
Size: 3698 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170519/9f767e70/attachment-0001.bin>
More information about the cfe-commits
mailing list