From 1ade82e135d4e815db5b33c9ebd67632b74e5e1d Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 4 Jul 2018 12:24:39 +0200
Subject: Fixed various mistakes in Itanium C++ demangling.

---
 plugins/itanium/abi.c                       | 59 +++++++++++---------------
 plugins/itanium/component-int.h             |  5 +--
 plugins/itanium/component.c                 | 63 +++++++++++----------------
 plugins/itanium/component.h                 | 16 +++++--
 plugins/itanium/context.c                   | 43 +++++++++++++++----
 plugins/itanium/context.h                   |  2 +-
 plugins/pychrysalide/analysis/types/array.c | 19 +++++++--
 src/analysis/types/array.c                  | 33 +++++++++++++--
 src/analysis/types/array.h                  |  3 ++
 tests/mangling/itanium.py                   | 66 +++++++++++++++++++++++++++++
 10 files changed, 212 insertions(+), 97 deletions(-)

diff --git a/plugins/itanium/abi.c b/plugins/itanium/abi.c
index 5f76342..3f6f713 100644
--- a/plugins/itanium/abi.c
+++ b/plugins/itanium/abi.c
@@ -1954,6 +1954,7 @@ static itanium_component *itd_type(GItaniumDemangling *context)
             {
                 builtin = g_class_enum_type_new(CET_UNKNOWN, itd_translate_component(vendor, NULL));
                 result = itd_make_type(builtin);
+                itd_set_type(result, ICT_VENDOR_TYPE);
                 itd_unref_comp(vendor);
 
                 sub = itd_type(context);
@@ -2483,10 +2484,10 @@ static itanium_component *itd_array_type(GItaniumDemangling *context)
 {
     itanium_component *result;              /* Construction à retourner    */
     input_buffer *ibuf;                     /* Tampon de texte manipulé    */
-    char peek;                              /* Prochain caractère dispo.   */
-    itanium_component *dim_expr;            /* Dimension via expression    */
     ssize_t dim_number;                     /* Dimension par un nombre     */
     itanium_component *type;                /* Type du tableau             */
+    itd_state saved;                        /* Position d'analyse courante */
+    itanium_component *dim_expr;            /* Dimension via expression    */
 
     /**
      * La règle traitée ici est la suivante :
@@ -2501,58 +2502,46 @@ static itanium_component *itd_array_type(GItaniumDemangling *context)
     if (!check_input_buffer_char(ibuf, 'A'))
         return NULL;
 
-    peek = peek_input_buffer_char(ibuf);
-
-    if (peek == '[')
+    if (itd_number(context, &dim_number))
     {
-        advance_input_buffer(ibuf, 1);
-
-        dim_expr = itd_expression(context);
-
-        if (dim_expr == NULL)
-            return NULL;
-
-        if (!check_input_buffer_char(ibuf, ']'))
-            return NULL;
-
         if (!check_input_buffer_char(ibuf, '_'))
             return NULL;
 
         type = itd_type(context);
 
         if (type == NULL)
-        {
-            itd_unref_comp(dim_expr);
             return NULL;
-        }
 
-        result = itd_make_array_with_dim_expr(dim_expr, type);
-
-        if (result == NULL)
-        {
-            itd_unref_comp(dim_expr);
-            itd_unref_comp(type);
-        }
+        result = itd_make_array_with_dim_number(dim_number, type);
 
     }
 
     else
     {
-        if (!itd_number(context, &dim_number))
-            return NULL;
+        g_itanium_demangling_push_state(context, &saved);
+
+        dim_expr = itd_expression(context);
+
+        if (dim_expr == NULL)
+            g_itanium_demangling_pop_state(context, &saved);
 
         if (!check_input_buffer_char(ibuf, '_'))
+        {
+            if (dim_expr != NULL)
+                itd_unref_comp(dim_expr);
             return NULL;
+        }
 
         type = itd_type(context);
 
         if (type == NULL)
+        {
+            if (dim_expr != NULL)
+                itd_unref_comp(dim_expr);
             return NULL;
+        }
 
-        result = itd_make_array_with_dim_number(dim_number, type);
-
-        if (result == NULL)
-            itd_unref_comp(type);
+        result = itd_make_array_with_dim_expr(dim_expr, type);
 
     }
 
@@ -2660,6 +2649,9 @@ static itanium_component *itd_template_param(GItaniumDemangling *context)
 
             result = g_itanium_demangling_get_template_arg(context, id);
 
+            if (result != NULL)
+                result = itd_make_unary(ICT_TEMPLATE_PARAM, result);
+
         }
 
     }
@@ -2761,6 +2753,8 @@ static itanium_component *itd_template_args(GItaniumDemangling *context)
 
     result = itd_make_unary(ICT_TEMPLATE_ARGS, result);
 
+    g_itanium_demangling_add_template_args(context, result);
+
     return result;
 
 }
@@ -2817,9 +2811,6 @@ static itanium_component *itd_template_arg(GItaniumDemangling *context)
     else
         result = itd_type(context);
 
-    if (result != NULL)
-        g_itanium_demangling_add_template_arg(context, result);
-
     return result;
 
 }
diff --git a/plugins/itanium/component-int.h b/plugins/itanium/component-int.h
index fb8c423..20b2c8d 100644
--- a/plugins/itanium/component-int.h
+++ b/plugins/itanium/component-int.h
@@ -36,8 +36,6 @@ struct _itanium_component
 
     unsigned int refcount;                  /* Compteur de références      */
 
-    fnv64_t hash;                           /* Empreinte en cache          */
-
     union
     {
         /* ICT_NAME */
@@ -66,8 +64,9 @@ struct _itanium_component
         /* ICT_VIRTUAL_OFFSET */
         ssize_t offset;                     /* Décalage de fonction        */
 
-        /* ICT_STD_SUBST */
         /* ICT_TYPE */
+        /* ICT_VENDOR_TYPE */
+        /* ICT_STD_SUBST */
         GDataType *dtype;                   /* Type instancié              */
 
         /* ICT_QUALIFIED_TYPE */
diff --git a/plugins/itanium/component.c b/plugins/itanium/component.c
index 6e580f6..d890a1b 100644
--- a/plugins/itanium/component.c
+++ b/plugins/itanium/component.c
@@ -48,9 +48,6 @@
 typedef void (* visit_comp_fc) (itanium_component *);
 
 
-#define reset_comp_hash(c) c->hash = 0
-
-
 /* Crée un composant de contexte Itanium complètement vierge. */
 static itanium_component *itd_alloc(void);
 
@@ -191,6 +188,7 @@ static void visit_comp(itanium_component *comp, visit_comp_fc visitor)
             break;
 
         case ICT_TYPE:
+        case ICT_VENDOR_TYPE:
             break;
 
         case ICT_QUALIFIED_TYPE:
@@ -227,7 +225,7 @@ static void visit_comp(itanium_component *comp, visit_comp_fc visitor)
             break;
 
         case ICT_ARRAY:
-            if (!comp->array.numbered_dim)
+            if (!comp->array.numbered_dim && comp->array.dim_expr != NULL)
                 visit_comp(comp->array.dim_expr, visitor);
             visit_comp(comp->array.atype, visitor);
             break;
@@ -237,6 +235,10 @@ static void visit_comp(itanium_component *comp, visit_comp_fc visitor)
             visit_comp(comp->pmember.member, visitor);
             break;
 
+        case ICT_TEMPLATE_PARAM:
+            visit_comp(comp->unary, visitor);
+            break;
+
         case ICT_TEMPLATE_ARGS:
             visit_comp(comp->unary, visitor);
             break;
@@ -320,7 +322,7 @@ void itd_unref_comp(itanium_component *comp)
     {
         if (--comp->refcount == 0)
         {
-            if (comp->type == ICT_TYPE || comp->type == ICT_STD_SUBST)
+            if (comp->type == ICT_TYPE || comp->type == ICT_VENDOR_TYPE || comp->type == ICT_STD_SUBST)
                 g_object_unref(G_OBJECT(comp->dtype));
 
             itd_free(comp);
@@ -336,34 +338,6 @@ void itd_unref_comp(itanium_component *comp)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : comp = composant à manipuler.                                *
-*                                                                             *
-*  Description : Détermine ou fournit l'empreinte d'un composant.             *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-fnv64_t itd_hash_comp(itanium_component *comp)
-{
-    char *desc;                             /* Description du composant    */
-
-    if (comp->hash == 0)
-    {
-        desc = itd_translate_component(comp, NULL);
-        comp->hash = fnv_64a_hash(desc);
-        free(desc);
-    }
-
-    return comp->hash;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : type = type à définir pour le composant.                     *
 *                                                                             *
 *  Description : Construit un composant dans un contexte Itanium.             *
@@ -797,7 +771,7 @@ itanium_component *itd_append_right_to_binary(ItaniumComponentType type, itanium
     if (parent != NULL)
     {
         for (iter = parent; iter->binary.right != NULL; iter = iter->binary.right)
-            reset_comp_hash(iter);
+            ;
         iter->binary.right = result;
     }
 
@@ -854,8 +828,6 @@ void itd_set_type(itanium_component *comp, ItaniumComponentType type)
 {
     comp->type = type;
 
-    reset_comp_hash(comp);
-
 }
 
 
@@ -1025,6 +997,7 @@ char *itd_translate_component(const itanium_component *comp, char *base)
             break;
 
         case ICT_TYPE:
+        case ICT_VENDOR_TYPE:
             name = g_data_type_to_string(comp->dtype, true);
             result = stradd(base, name);
             free(name);
@@ -1112,7 +1085,7 @@ char *itd_translate_component(const itanium_component *comp, char *base)
                 free(tmp);
             }
 
-            else
+            else if (comp->array.dim_expr != NULL)
                 result = itd_translate_component(comp->array.dim_expr, result);
 
             result = stradd(result, "]");
@@ -1125,6 +1098,10 @@ char *itd_translate_component(const itanium_component *comp, char *base)
             result = itd_translate_component(comp->pmember.member, result);
             break;
 
+        case ICT_TEMPLATE_PARAM:
+            result = itd_translate_component(comp->unary, base);
+            break;
+
         case ICT_TEMPLATE_ARGS:
             result = stradd(base, "<");
             result = itd_translate_component(comp->unary, result);
@@ -1543,6 +1520,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
             break;
 
         case ICT_TYPE:
+        case ICT_VENDOR_TYPE:
             result = g_data_type_dup(comp->dtype);
             break;
 
@@ -1631,9 +1609,12 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
                 if (comp->array.numbered_dim)
                     g_array_type_set_dimension_number(G_ARRAY_TYPE(result), comp->array.dim_number);
 
-                else
+                else if (comp->array.dim_expr != NULL)
                     g_array_type_set_dimension_expression(G_ARRAY_TYPE(result),
-                                                          itd_translate_component(comp, NULL));
+                                                          itd_translate_component(comp->array.dim_expr, NULL));
+
+                else
+                    g_array_type_set_empty_dimension(G_ARRAY_TYPE(result));
 
             }
 
@@ -1660,6 +1641,10 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
 
             break;
 
+        case ICT_TEMPLATE_PARAM:
+            result = itd_translate_component_to_type(comp->unary);
+            break;
+
         case ICT_TEMPLATE_ARGS:
 
             assert(comp->unary->type == ICT_TYPES_LIST);
diff --git a/plugins/itanium/component.h b/plugins/itanium/component.h
index f921ff9..7012283 100644
--- a/plugins/itanium/component.h
+++ b/plugins/itanium/component.h
@@ -34,7 +34,6 @@
 
 #include <analysis/routine.h>
 #include <analysis/type.h>
-#include <common/fnv1a.h>
 
 
 
@@ -113,6 +112,12 @@ typedef enum _ItaniumComponentType
     ICT_TYPE,
 
     /**
+     * Simple distinction de ICT_TYPE, pour la distinction lors des candidatures
+     * aux substitutions.
+     */
+    ICT_VENDOR_TYPE,
+
+    /**
      * Type qualifié ; les infos utilies sont explicitement
      * conservées dans le champ qualified.
      */
@@ -154,6 +159,12 @@ typedef enum _ItaniumComponentType
     ICT_POINTER_TO_MEMBER,
 
     /**
+     * Argument de template. Utile pour les candidatures aux substitutions.
+     * 'unary' renvoie vers le composant utile.
+     */
+    ICT_TEMPLATE_PARAM,
+
+    /**
      * Liste d'arguments pour templates, à encadrer par des chevrons.
      * 'unary' pointe vers la liste des éléments.
      */
@@ -223,9 +234,6 @@ void itd_ref_comp(itanium_component *);
 /* Décrémente le nombre d'utilisation du composant. */
 void itd_unref_comp(itanium_component *);
 
-/* Détermine ou fournit l'empreinte d'un composant. */
-fnv64_t itd_hash_comp(itanium_component *);
-
 /* Construit un composant dans un contexte Itanium. */
 itanium_component *itd_make_with_type(ItaniumComponentType);
 
diff --git a/plugins/itanium/context.c b/plugins/itanium/context.c
index 1d2c365..c89f823 100644
--- a/plugins/itanium/context.c
+++ b/plugins/itanium/context.c
@@ -411,10 +411,12 @@ void g_itanium_demangling_pop_state(GItaniumDemangling *context, const itd_state
 *                                                                             *
 ******************************************************************************/
 
-void g_itanium_demangling_add_template_arg(GItaniumDemangling *context, itanium_component *comp)
+void g_itanium_demangling_add_template_args(GItaniumDemangling *context, itanium_component *comp)
 {
     assert(comp != NULL);
 
+    assert(itd_get_component_type(comp) == ICT_TEMPLATE_ARGS);
+
     context->template_args[context->targs_count++] = comp;
     itd_ref_comp(comp);
 
@@ -437,14 +439,37 @@ void g_itanium_demangling_add_template_arg(GItaniumDemangling *context, itanium_
 itanium_component *g_itanium_demangling_get_template_arg(GItaniumDemangling *context, size_t index)
 {
     itanium_component *result;              /* Composant à retourner       */
+    itanium_component *targs;               /* Racine des arguments        */
+    itanium_component *iter;                /* Boucle de parcours #1       */
+
+    if (context->targs_count == 0)
+        result = NULL;
 
-    if (index < context->targs_count)
+    else
     {
-        result = context->template_args[index];
-        itd_ref_comp(result);
+        targs = context->template_args[context->targs_count - 1];
+
+        for (iter = targs->unary; iter != NULL; iter = iter->binary.right)
+        {
+            assert(itd_get_component_type(iter) == ICT_TYPES_LIST);
+
+            if (index == 0)
+                break;
+
+            index--;
+
+        }
+
+        if (iter != NULL)
+        {
+            result = iter->binary.left;
+            itd_ref_comp(result);
+        }
+
+        else
+            result = NULL;
+
     }
-    else
-        result = NULL;
 
     return result;
 
@@ -466,15 +491,15 @@ itanium_component *g_itanium_demangling_get_template_arg(GItaniumDemangling *con
 
 void g_itanium_demangling_add_substitution(GItaniumDemangling *context, itanium_component *comp)
 {
-    fnv64_t hash;                           /* Empreinte du candidat       */
     size_t i;                               /* Boucle de parcours          */
 
     assert(comp != NULL);
 
-    hash = itd_hash_comp(comp);
+    if (itd_get_component_type(comp) == ICT_STD_SUBST)
+        return;
 
     for (i = 0; i < context->subst_count; i++)
-        if (cmp_fnv_64a(itd_hash_comp(context->substitutions[i]), hash) == 0)
+        if (comp == context->substitutions[i])
             break;
 
     if (i == context->subst_count)
diff --git a/plugins/itanium/context.h b/plugins/itanium/context.h
index 6ec65ae..d836afb 100644
--- a/plugins/itanium/context.h
+++ b/plugins/itanium/context.h
@@ -67,7 +67,7 @@ void g_itanium_demangling_push_state(const GItaniumDemangling *, itd_state *);
 void g_itanium_demangling_pop_state(GItaniumDemangling *, const itd_state *);
 
 /* Indexe un composant représentant un argument de modèle. */
-void g_itanium_demangling_add_template_arg(GItaniumDemangling *, itanium_component *);
+void g_itanium_demangling_add_template_args(GItaniumDemangling *, itanium_component *);
 
 /* Fournit un composant représentant un argument de modèle. */
 itanium_component *g_itanium_demangling_get_template_arg(GItaniumDemangling *, size_t);
diff --git a/plugins/pychrysalide/analysis/types/array.c b/plugins/pychrysalide/analysis/types/array.c
index d021e16..6f70b02 100644
--- a/plugins/pychrysalide/analysis/types/array.c
+++ b/plugins/pychrysalide/analysis/types/array.c
@@ -281,7 +281,14 @@ static PyObject *py_array_type_get_dimension_expression(PyObject *self, void *cl
 
     dim = g_array_type_get_dimension_expression(type);
 
-    result = PyUnicode_FromString(dim);
+    if (dim != NULL)
+        result = PyUnicode_FromString(dim);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
 
     return result;
 
@@ -306,15 +313,19 @@ static int py_array_type_set_dimension_expression(PyObject *self, PyObject *valu
 {
     GArrayType *type;                       /* Version GLib du type        */
 
-    if (!PyUnicode_Check(value))
+    if (!PyUnicode_Check(value) && value != Py_None)
     {
-        PyErr_SetString(PyExc_TypeError, _("The attribute value must be a string."));
+        PyErr_SetString(PyExc_TypeError, _("The attribute value must be a string or None."));
         return -1;
     }
 
     type = G_ARRAY_TYPE(pygobject_get(self));
 
-    g_array_type_set_dimension_expression(type, strdup(PyUnicode_DATA(value)));
+    if (value == Py_None)
+        g_array_type_set_empty_dimension(type);
+
+    else
+        g_array_type_set_dimension_expression(type, strdup(PyUnicode_DATA(value)));
 
     return 0;
 
diff --git a/src/analysis/types/array.c b/src/analysis/types/array.c
index 714ab58..5aea07b 100644
--- a/src/analysis/types/array.c
+++ b/src/analysis/types/array.c
@@ -230,6 +230,9 @@ static GDataType *g_array_type_dup(const GArrayType *type)
     else if (type->dim_expr != NULL)
         g_array_type_set_dimension_expression(G_ARRAY_TYPE(result), strdup(type->dim_expr));
 
+    else
+        g_array_type_set_empty_dimension(G_ARRAY_TYPE(result));
+
     return result;
 
 }
@@ -268,7 +271,7 @@ static char *g_array_type_to_string(const GArrayType *type, bool include)
         }
     }
 
-    else
+    else if (type->dim_expr != NULL)
         result = stradd(result, type->dim_expr);
 
     result = stradd(result, "]");
@@ -356,7 +359,7 @@ ssize_t g_array_type_get_dimension_number(const GArrayType *type)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : type = type à consulter.                                     *
+*  Paramètres  : type = type à traiter.                                       *
 *                dim  = dimension positive ou nulle.                          *
 *                                                                             *
 *  Description : Définit la dimension associée au tableau.                    *
@@ -406,7 +409,7 @@ const char *g_array_type_get_dimension_expression(const GArrayType *type)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : type = type à consulter.                                     *
+*  Paramètres  : type = type à traiter.                                       *
 *                expr = expression de dimension.                              *
 *                                                                             *
 *  Description : Définit la dimension associée au tableau.                    *
@@ -427,3 +430,27 @@ void g_array_type_set_dimension_expression(GArrayType *type, char *expr)
     type->dim_expr = expr;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type à traiter.                                       *
+*                                                                             *
+*  Description : Définit une dimension vide pour le tableau.                  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_array_type_set_empty_dimension(GArrayType *type)
+{
+    if (!type->numbered && type->dim_expr != NULL)
+        free(type->dim_expr);
+
+    type->numbered = false;
+
+    type->dim_expr = NULL;
+
+}
diff --git a/src/analysis/types/array.h b/src/analysis/types/array.h
index d432c22..3bec2a0 100644
--- a/src/analysis/types/array.h
+++ b/src/analysis/types/array.h
@@ -71,6 +71,9 @@ const char *g_array_type_get_dimension_expression(const GArrayType *);
 /* Définit la dimension associée au tableau. */
 void g_array_type_set_dimension_expression(GArrayType *, char *);
 
+/* Définit une dimension vide pour le tableau. */
+void g_array_type_set_empty_dimension(GArrayType *);
+
 
 
 #endif  /* _ANALYSIS_TYPES_ARRAY_H */
diff --git a/tests/mangling/itanium.py b/tests/mangling/itanium.py
index 6bb49d3..a04c590 100644
--- a/tests/mangling/itanium.py
+++ b/tests/mangling/itanium.py
@@ -109,3 +109,69 @@ class TestItaniumMangling(ChrysalideTestCase):
 
         demangled = demangler.decode_routine('_ZN1N1TIiiE2mfES0_IddE')
         self.check_demangling(demangled, '??? N::T<int, int>::mf(N::T<double, double>)')
+
+
+    def testItaniumRoutineManglingExtra(self):
+        """Check extra Itanium routine demangling cases."""
+
+        # http://refspecs.linuxbase.org/cxxabi-1.83.html#linkage
+
+        demangler = ItaniumDemangler()
+
+        # A la lecture, il s'agit d'une référence sur un tableau, et non
+        # d'un tableau de références.
+        demangled = demangler.decode_routine('_Z3fooILi2EEvRAplT_Li1E_i')
+        self.check_demangling(demangled, 'void foo<2>(int[2+1] &)')
+
+
+    def testAFL(self):
+        """Tests from AFL."""
+
+        demangler = ItaniumDemangler()
+
+        demangled = demangler.decode_routine('_Z4makeI7FactoryiET_IT')
+        self.assertIsNone(demangled)
+
+        demangled = demangler.decode_routine('_Z4makeN7FactoryiET_IT0_Ev')
+        self.assertIsNone(demangled)
+
+        demangled = demangler.decode_routine('_Z4makeI7FactoryiET_I4makeIMGaptoryiET_T0_Ev')
+        self.assertIsNone(demangled)
+
+        demangled = demangler.decode_routine('_Z4maktoryiaS_ILNd')
+        self.assertIsNone(demangled)
+
+        # ?!
+        demangled = demangler.decode_routine('_Z4makeMVFactoryiES_')
+        self.assertIsNotNone(demangled)
+
+
+    def testOldRealWorldDemanglings(self):
+        """Check real world demangling cases from previous code."""
+
+        demangler = ItaniumDemangler()
+
+        demangled = demangler.decode_routine('_ZNSt6vectorItSaItEE6insertEN9__gnu_cxx17__normal_iteratorIPtS1_EERKt')
+        self.check_demangling(demangled, '??? std::vector<unsigned short, std::allocator<unsigned short>>::insert(__gnu_cxx::__normal_iterator<unsigned short *, std::vector<unsigned short, std::allocator<unsigned short>>>, const unsigned short &)')
+
+        demangled = demangler.decode_routine('_ZSt26__uninitialized_fill_n_auxIP15CProfStringListiS0_ET_S2_T0_RKT1_12__false_type')
+        self.check_demangling(demangled, 'CProfStringList *std::__uninitialized_fill_n_aux<CProfStringList *, int, CProfStringList>(CProfStringList *, int, const CProfStringList &, __false_type)')
+
+
+        demangled = demangler.decode_routine('_ZN21IUDFSettingsValidator15IdNotIllegalStdEN13UDFParameters12UDF_STANDARDES1_')
+        self.check_demangling(demangled, '??? IUDFSettingsValidator::IdNotIllegalStd(UDFParameters::UDF_STANDARD, UDFParameters::UDF_STANDARD)')
+
+        demangled = demangler.decode_routine('_ZNSbI26NeroMediumFeatureSpecifierSt11char_traitsIS_ESaIS_EE4_Rep10_M_destroyERKS2_')
+        self.check_demangling(demangled, '??? std::basic_string<NeroMediumFeatureSpecifier, std::char_traits<NeroMediumFeatureSpecifier>, std::allocator<NeroMediumFeatureSpecifier>>::_Rep::_M_destroy(const std::allocator<NeroMediumFeatureSpecifier> &)')
+
+        demangled = demangler.decode_routine('_ZNSt6vectorIlSaIlEE6insertEN9__gnu_cxx17__normal_iteratorIPlS1_EERKl')
+        self.check_demangling(demangled, '??? std::vector<long, std::allocator<long>>::insert(__gnu_cxx::__normal_iterator<long *, std::vector<long, std::allocator<long>>>, const long &)')
+
+        demangled = demangler.decode_routine('_ZSt22__merge_without_bufferIN9__gnu_cxx17__normal_iteratorIP15CProfStringListSt6vectorIS2_SaIS2_EEEEiEvT_S8_S8_T0_S9_')
+        self.check_demangling(demangled, 'void std::__merge_without_buffer<__gnu_cxx::__normal_iterator<CProfStringList *, std::vector<CProfStringList, std::allocator<CProfStringList>>>, int>(__gnu_cxx::__normal_iterator<CProfStringList *, std::vector<CProfStringList, std::allocator<CProfStringList>>>, __gnu_cxx::__normal_iterator<CProfStringList *, std::vector<CProfStringList, std::allocator<CProfStringList>>>, __gnu_cxx::__normal_iterator<CProfStringList *, std::vector<CProfStringList, std::allocator<CProfStringList>>>, int, int)')
+
+        demangled = demangler.decode_routine('_ZSt11__push_heapIN9__gnu_cxx17__normal_iteratorIP8DRIVE_IDSt6vectorIS2_SaIS2_EEEEiS2_EvT_T0_S9_T1_')
+        self.check_demangling(demangled, 'void std::__push_heap<__gnu_cxx::__normal_iterator<DRIVE_ID *, std::vector<DRIVE_ID, std::allocator<DRIVE_ID>>>, int, DRIVE_ID>(__gnu_cxx::__normal_iterator<DRIVE_ID *, std::vector<DRIVE_ID, std::allocator<DRIVE_ID>>>, int, int, DRIVE_ID)')
+
+        demangled = demangler.decode_routine('_ZSt12partial_sortIN9__gnu_cxx17__normal_iteratorIP28CPR_MAI_ADPTY_SectorSequenceSt6vectorIS2_SaIS2_EEEEEvT_S8_S8_')
+        self.check_demangling(demangled, 'void std::partial_sort<__gnu_cxx::__normal_iterator<CPR_MAI_ADPTY_SectorSequence *, std::vector<CPR_MAI_ADPTY_SectorSequence, std::allocator<CPR_MAI_ADPTY_SectorSequence>>>>(__gnu_cxx::__normal_iterator<CPR_MAI_ADPTY_SectorSequence *, std::vector<CPR_MAI_ADPTY_SectorSequence, std::allocator<CPR_MAI_ADPTY_SectorSequence>>>, __gnu_cxx::__normal_iterator<CPR_MAI_ADPTY_SectorSequence *, std::vector<CPR_MAI_ADPTY_SectorSequence, std::allocator<CPR_MAI_ADPTY_SectorSequence>>>, __gnu_cxx::__normal_iterator<CPR_MAI_ADPTY_SectorSequence *, std::vector<CPR_MAI_ADPTY_SectorSequence, std::allocator<CPR_MAI_ADPTY_SectorSequence>>>)')
-- 
cgit v0.11.2-87-g4458