]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR other/61321 (demangler crash on casts in template parameters)
authorJakub Jelinek <jakub@redhat.com>
Thu, 19 May 2016 12:04:11 +0000 (14:04 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 19 May 2016 12:04:11 +0000 (14:04 +0200)
Backported from mainline
2015-11-27  Pedro Alves  <palves@redhat.com>

PR other/61321
PR other/61233
* demangle.h (enum demangle_component_type)
<DEMANGLE_COMPONENT_CONVERSION>: New value.

* cp-demangle.c (d_demangle_callback, d_make_comp): Handle
DEMANGLE_COMPONENT_CONVERSION.
(is_ctor_dtor_or_conversion): Handle DEMANGLE_COMPONENT_CONVERSION
instead of DEMANGLE_COMPONENT_CAST.
(d_operator_name): Return a DEMANGLE_COMPONENT_CONVERSION
component if handling a conversion.
(d_count_templates_scopes, d_print_comp_inner): Handle
DEMANGLE_COMPONENT_CONVERSION.
(d_print_comp_inner): Handle DEMANGLE_COMPONENT_CONVERSION instead
of DEMANGLE_COMPONENT_CAST.
(d_print_cast): Rename as ...
(d_print_conversion): ... this.  Adjust comments.
(d_print_cast): Rewrite - simply print the left subcomponent.
* cp-demint.c (cplus_demangle_fill_component): Handle
DEMANGLE_COMPONENT_CONVERSION.

* testsuite/demangle-expected: Add tests.

From-SVN: r236455

include/ChangeLog
include/demangle.h
libiberty/ChangeLog
libiberty/cp-demangle.c
libiberty/cp-demint.c
libiberty/testsuite/demangle-expected
libiberty/testsuite/demangler-fuzzer.c [new file with mode: 0644]

index 59839bd57475587bc49f4e15a45f6a2f89c8377f..6ac4c4fd6e6901d8f392feedf47b90bdc041c13c 100644 (file)
@@ -1,3 +1,13 @@
+2016-05-19  Jakub Jelinek  <jakub@redhat.com>
+
+       Backported from mainline
+       2015-11-27  Pedro Alves  <palves@redhat.com>
+
+       PR other/61321
+       PR other/61233
+       * demangle.h (enum demangle_component_type)
+       <DEMANGLE_COMPONENT_CONVERSION>: New value.
+
 2015-06-26  Release Manager
 
        * GCC 4.9.3 released.
index bbad71bd8c742519283ebeaf17e9686b71c2b140..7dc26489d6f93b66a66f6305b0d312abf7491870 100644 (file)
@@ -373,6 +373,10 @@ enum demangle_component_type
   /* A typecast, represented as a unary operator.  The one subtree is
      the type to which the argument should be cast.  */
   DEMANGLE_COMPONENT_CAST,
+  /* A conversion operator, represented as a unary operator.  The one
+     subtree is the type to which the argument should be converted
+     to.  */
+  DEMANGLE_COMPONENT_CONVERSION,
   /* A nullary expression.  The left subtree is the operator.  */
   DEMANGLE_COMPONENT_NULLARY,
   /* A unary expression.  The left subtree is the operator, and the
index f112f762a1ebe4ceda742134309470520e719109..a32a08f0211b63da7bd6956755f7b72a9377db40 100644 (file)
@@ -1,6 +1,28 @@
 2016-05-19  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2015-11-27  Pedro Alves  <palves@redhat.com>
+
+       PR other/61321
+       PR other/61233
+       * cp-demangle.c (d_demangle_callback, d_make_comp): Handle
+       DEMANGLE_COMPONENT_CONVERSION.
+       (is_ctor_dtor_or_conversion): Handle DEMANGLE_COMPONENT_CONVERSION
+       instead of DEMANGLE_COMPONENT_CAST.
+       (d_operator_name): Return a DEMANGLE_COMPONENT_CONVERSION
+       component if handling a conversion.
+       (d_count_templates_scopes, d_print_comp_inner): Handle
+       DEMANGLE_COMPONENT_CONVERSION.
+       (d_print_comp_inner): Handle DEMANGLE_COMPONENT_CONVERSION instead
+       of DEMANGLE_COMPONENT_CAST.
+       (d_print_cast): Rename as ...
+       (d_print_conversion): ... this.  Adjust comments.
+       (d_print_cast): Rewrite - simply print the left subcomponent.
+       * cp-demint.c (cplus_demangle_fill_component): Handle
+       DEMANGLE_COMPONENT_CONVERSION.
+
+       * testsuite/demangle-expected: Add tests.
+
        2015-07-13  Mikhail Maltsev  <maltsevm@gmail.com>
 
        * cp-demangle.c (d_dump): Fix syntax error.
index fc58050e4bc2a5780e894cdfc92df6717e8f0fed..3409fcda3237fcd3bcbb35fd11e04882e53c93e4 100644 (file)
@@ -538,8 +538,10 @@ d_print_array_type (struct d_print_info *, int,
 static void
 d_print_expr_op (struct d_print_info *, int, const struct demangle_component *);
 
-static void
-d_print_cast (struct d_print_info *, int, const struct demangle_component *);
+static void d_print_cast (struct d_print_info *, int,
+                         const struct demangle_component *);
+static void d_print_conversion (struct d_print_info *, int,
+                               const struct demangle_component *);
 
 static int d_demangle_callback (const char *, int,
                                 demangle_callbackref, void *);
@@ -729,6 +731,9 @@ d_dump (struct demangle_component *dc, int indent)
     case DEMANGLE_COMPONENT_CAST:
       printf ("cast\n");
       break;
+    case DEMANGLE_COMPONENT_CONVERSION:
+      printf ("conversion operator\n");
+      break;
     case DEMANGLE_COMPONENT_NULLARY:
       printf ("nullary operator\n");
       break;
@@ -938,6 +943,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
     case DEMANGLE_COMPONENT_IMAGINARY:
     case DEMANGLE_COMPONENT_VENDOR_TYPE:
     case DEMANGLE_COMPONENT_CAST:
+    case DEMANGLE_COMPONENT_CONVERSION:
     case DEMANGLE_COMPONENT_JAVA_RESOURCE:
     case DEMANGLE_COMPONENT_DECLTYPE:
     case DEMANGLE_COMPONENT_PACK_EXPANSION:
@@ -1229,7 +1235,7 @@ is_ctor_dtor_or_conversion (struct demangle_component *dc)
       return is_ctor_dtor_or_conversion (d_right (dc));
     case DEMANGLE_COMPONENT_CTOR:
     case DEMANGLE_COMPONENT_DTOR:
-    case DEMANGLE_COMPONENT_CAST:
+    case DEMANGLE_COMPONENT_CONVERSION:
       return 1;
     }
 }
@@ -1785,11 +1791,16 @@ d_operator_name (struct d_info *di)
     {
       struct demangle_component *type;
       int was_conversion = di->is_conversion;
+      struct demangle_component *res;
 
       di->is_conversion = ! di->is_expression;
       type = cplus_demangle_type (di);
+      if (di->is_conversion)
+       res = d_make_comp (di, DEMANGLE_COMPONENT_CONVERSION, type, NULL);
+      else
+       res = d_make_comp (di, DEMANGLE_COMPONENT_CAST, type, NULL);
       di->is_conversion = was_conversion;
-      return d_make_comp (di, DEMANGLE_COMPONENT_CAST, type, NULL);
+      return res;
     }
   else
     {
@@ -3888,6 +3899,7 @@ d_count_templates_scopes (int *num_templates, int *num_scopes,
     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
     case DEMANGLE_COMPONENT_INITIALIZER_LIST:
     case DEMANGLE_COMPONENT_CAST:
+    case DEMANGLE_COMPONENT_CONVERSION:
     case DEMANGLE_COMPONENT_NULLARY:
     case DEMANGLE_COMPONENT_UNARY:
     case DEMANGLE_COMPONENT_BINARY:
@@ -5021,9 +5033,9 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
       d_print_comp (dpi, options, dc->u.s_extended_operator.name);
       return;
 
-    case DEMANGLE_COMPONENT_CAST:
+    case DEMANGLE_COMPONENT_CONVERSION:
       d_append_string (dpi, "operator ");
-      d_print_cast (dpi, options, dc);
+      d_print_conversion (dpi, options, dc);
       return;
 
     case DEMANGLE_COMPONENT_NULLARY:
@@ -5756,11 +5768,20 @@ d_print_expr_op (struct d_print_info *dpi, int options,
 
 static void
 d_print_cast (struct d_print_info *dpi, int options,
-              const struct demangle_component *dc)
+                   const struct demangle_component *dc)
+{
+  d_print_comp (dpi, options, d_left (dc));
+}
+
+/* Print a conversion operator.  */
+
+static void
+d_print_conversion (struct d_print_info *dpi, int options,
+                   const struct demangle_component *dc)
 {
   struct d_print_template dpt;
 
-  /* For a cast operator, we need the template parameters from
+  /* For a conversion operator, we need the template parameters from
      the enclosing template in scope for processing the type.  */
   if (dpi->current_template != NULL)
     {
index 1d1a77af748ba2485272db761fa4244e25b5e2e2..efcc5b7f5c02a3ae1cda503a80fe1f85609e85bd 100644 (file)
@@ -110,6 +110,7 @@ cplus_demangle_fill_component (struct demangle_component *p,
     case DEMANGLE_COMPONENT_IMAGINARY:
     case DEMANGLE_COMPONENT_VENDOR_TYPE:
     case DEMANGLE_COMPONENT_CAST:
+    case DEMANGLE_COMPONENT_CONVERSION:
       if (right != NULL)
        return 0;
       break;
index 4f793c469670fe4868382a28070881a791db0d78..7038c7d136529adda66c1eca5b07070d1b3a570d 100644 (file)
@@ -4383,3 +4383,26 @@ xxx
 _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
 _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
 _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
+#
+# These two are from gcc PR61321, and gcc PR61233 / gdb PR16957
+#
+--format=gnu-v3
+_Z13function_tempIiEv1AIXszcvT_Li999EEE
+void function_temp<int>(A<sizeof ((int)(999))>)
+#
+--format=gnu-v3
+_Z7ZipWithI7QStringS0_5QListZN4oral6detail16AdaptCreateTableI7AccountEES0_RKNS3_16CachedFieldsDataEEUlRKS0_SA_E_ET1_IDTclfp1_cvT__EcvT0__EEEERKT1_ISC_ERKT1_ISD_ET2_
+QList<decltype ({parm#3}((QString)(), (QString)()))> ZipWith<QString, QString, QList, QString oral::detail::AdaptCreateTable<Account>(oral::detail::CachedFieldsData const&)::{lambda(QString const&, QString const&)#1}>(QList<QString oral::detail::AdaptCreateTable<Account>(oral::detail::CachedFieldsData const&)::{lambda(QString const&, QString const&)#1}> const&, QList<QList> const&, QString oral::detail::AdaptCreateTable<Account>(oral::detail::CachedFieldsData const&)::{lambda(QString const&, QString const&)#1})
+#
+# These three are symbols generated by g++'s testsuite, which triggered the same bug as above.
+--format=gnu-v3
+_Z14int_if_addableI1YERiP1AIXszpldecvPT_Li0EdecvS4_Li0EEE
+int& int_if_addable<Y>(A<sizeof ((*((Y*)(0)))+(*((Y*)(0))))>*)
+#
+--format=gnu-v3
+_Z3bazIiEvP1AIXszcl3foocvT__ELCf00000000_00000000EEEE
+void baz<int>(A<sizeof (foo((int)(), (floatcomplex )00000000_00000000))>*)
+#
+--format=gnu-v3
+_Z3fooI1FEN1XIXszdtcl1PclcvT__EEE5arrayEE4TypeEv
+X<sizeof ((P(((F)())())).array)>::Type foo<F>()
diff --git a/libiberty/testsuite/demangler-fuzzer.c b/libiberty/testsuite/demangler-fuzzer.c
new file mode 100644 (file)
index 0000000..aff7024
--- /dev/null
@@ -0,0 +1,108 @@
+/* Demangler fuzzer.
+
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+   This file is part of GNU libiberty.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include "demangle.h"
+
+#define MAXLEN 253
+#define ALPMIN 33
+#define ALPMAX 127
+
+static char *program_name;
+
+#define DEFAULT_MAXCOUNT 7500000
+
+static void
+print_usage (FILE *fp, int exit_value)
+{
+  fprintf (fp, "Usage: %s [OPTION]...\n", program_name);
+  fprintf (fp, "Options:\n");
+  fprintf (fp, "  -h           Display this message.\n");
+  fprintf (fp, "  -s SEED      Select the random seed to be used.\n");
+  fprintf (fp, "               The default is to base one on the");
+  fprintf (fp, " current time.\n");
+  fprintf (fp, "  -m MAXCOUNT  Exit after MAXCOUNT symbols.\n");
+  fprintf (fp, "               The default is %d.", DEFAULT_MAXCOUNT);
+  fprintf (fp, " Set to `-1' for no limit.\n");
+
+  exit (exit_value);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char symbol[2 + MAXLEN + 1] = "_Z";
+  int seed = -1, seed_set = 0;
+  int count = 0, maxcount = DEFAULT_MAXCOUNT;
+  int optchr;
+
+  program_name = argv[0];
+
+  do
+    {
+      optchr = getopt (argc, argv, "hs:m:t:");
+      switch (optchr)
+       {
+       case '?':  /* Unrecognized option.  */
+         print_usage (stderr, 1);
+         break;
+
+       case 'h':
+         print_usage (stdout, 0);
+         break;
+
+       case 's':
+         seed = atoi (optarg);
+         seed_set = 1;
+         break;
+
+       case 'm':
+         maxcount = atoi (optarg);
+         break;
+       }
+    }
+  while (optchr != -1);
+
+  if (!seed_set)
+    seed = time (NULL);
+  srand (seed);
+  printf ("%s: seed = %d\n", program_name, seed);
+
+  while (maxcount < 0 || count < maxcount)
+    {
+      char *buffer = symbol + 2;
+      int length, i;
+
+      length = rand () % MAXLEN;
+      for (i = 0; i < length; i++)
+       *buffer++ = (rand () % (ALPMAX - ALPMIN)) + ALPMIN;
+
+      *buffer++ = '\0';
+
+      cplus_demangle (symbol, DMGL_AUTO | DMGL_ANSI | DMGL_PARAMS);
+
+      count++;
+    }
+
+  printf ("%s: successfully demangled %d symbols\n", program_name, count);
+  exit (0);
+}