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(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(")"); } 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(g::'lambda'(int, int, int))"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]);