mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-20 01:30:08 +08:00
re PR libstdc++/12736 (Demangler bug)
PR libstdc++/12736 * bits/demangle.h (qualifier_list<Allocator>::decode_KVrA): Added. (qualifier_list<Allocator>::decode_qualifiers): Collect concatenated K, V, r and A qualifiers before processing them as a group. * testsuite/demangle/abi_text/01.cc: Reordered CV-qualifiers. * testsuite/demangle/regression/cw-16.cc: New. From-SVN: r73339
This commit is contained in:
parent
bcc8cc820a
commit
2d369f351f
@ -1,3 +1,12 @@
|
||||
2003-11-07 Carlo Wood <carlo@alinoe.com>
|
||||
|
||||
PR libstdc++/12736
|
||||
* bits/demangle.h (qualifier_list<Allocator>::decode_KVrA): Added.
|
||||
(qualifier_list<Allocator>::decode_qualifiers): Collect concatenated
|
||||
K, V, r and A qualifiers before processing them as a group.
|
||||
* testsuite/demangle/abi_text/01.cc: Reordered CV-qualifiers.
|
||||
* testsuite/demangle/regression/cw-16.cc: New.
|
||||
|
||||
2003-11-07 Robert Millan <robertmh@gnu.org>
|
||||
|
||||
* configure.host: Add kfreebsd*-gnu and knetbsd*-gnu.
|
||||
|
@ -227,6 +227,10 @@ namespace __gnu_cxx
|
||||
std::vector<qualifier<Allocator>, Allocator> M_qualifier_starts;
|
||||
session<Allocator>& M_demangler;
|
||||
|
||||
void decode_KVrA(string_type& prefix, string_type& postfix, int cvq,
|
||||
typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
const_reverse_iterator const& iter_array) const;
|
||||
|
||||
public:
|
||||
qualifier_list(session<Allocator>& demangler_obj)
|
||||
: M_printing_suppressed(false), M_demangler(demangler_obj)
|
||||
@ -339,11 +343,6 @@ namespace __gnu_cxx
|
||||
static int
|
||||
decode_encoding(string_type& output, char const* input, int len);
|
||||
|
||||
bool
|
||||
decode_type_with_postfix(string_type& prefix,
|
||||
string_type& postfix,
|
||||
qualifier_list<Allocator>* qualifiers = NULL);
|
||||
|
||||
bool
|
||||
decode_type(string_type& output,
|
||||
qualifier_list<Allocator>* qualifiers = NULL)
|
||||
@ -384,6 +383,8 @@ namespace __gnu_cxx
|
||||
substitution_nt sub_type,
|
||||
int number_of_prefixes);
|
||||
|
||||
bool decode_type_with_postfix(string_type& prefix,
|
||||
string_type& postfix, qualifier_list<Allocator>* qualifiers = NULL);
|
||||
bool decode_bare_function_type(string_type& output);
|
||||
bool decode_builtin_type(string_type& output);
|
||||
bool decode_call_offset(string_type& output);
|
||||
@ -1382,8 +1383,11 @@ namespace __gnu_cxx
|
||||
// <Q>M<C> ==> C::*Q "M<C>..." (<C> recurs.)
|
||||
// A<I> ==> [I] "A<I>..." (<I> recurs.)
|
||||
// <Q>A<I> ==> (Q) [I] "A<I>..." (<I> recurs.)
|
||||
// Note that when <Q> ends on an A<I2> then the brackets are omitted:
|
||||
// A<I2>A<I> ==> [I2][I]
|
||||
// Note that when <Q> ends on an A<I2> then the brackets are omitted
|
||||
// and no space is written between the two:
|
||||
// A<I2>A<I> ==> [I2][I]
|
||||
// If <Q> ends on [KVr]+, which can happen in combination with
|
||||
// substitutions only, then special handling is required, see below.
|
||||
//
|
||||
// A <substitution> is handled with an input position switch during which
|
||||
// new substitutions are turned off. Because recursive handling of types
|
||||
@ -1411,6 +1415,86 @@ namespace __gnu_cxx
|
||||
// For some weird reason, g++ (3.2.1) does not add substitutions for
|
||||
// qualified member function pointers. I think that is another bug.
|
||||
//
|
||||
|
||||
// In the case of
|
||||
// <Q>A<I>
|
||||
// where <Q> ends on [K|V|r]+ then that part should be processed as
|
||||
// if it was behind the A<I> instead of in front of it. This is
|
||||
// because a constant array of ints is normally always mangled as
|
||||
// an array of constant ints. KVr qualifiers can end up in front
|
||||
// of an array when the array is part of a substitution or template
|
||||
// parameter, but the demangling should still result in the same
|
||||
// syntax; thus KA2_i (const array of ints) must result in the same
|
||||
// demangling as A2_Ki (array of const ints). As a result we must
|
||||
// demangle ...[...[[KVr]+A<I0>][KVr]+A<I1>]...[KVr]+A<In>[KVr]+
|
||||
// as A<I0>A<I1>...A<In>[KVr]+ where each K, V and r in the series
|
||||
// collapses to a single character at the right of the string.
|
||||
// For example:
|
||||
// VA9_KrA6_KVi --> A9_A6_KVri --> int volatile const restrict [9][6]
|
||||
// Note that substitutions are still added as usual (the translation
|
||||
// to A9_A6_KVri does not really happen).
|
||||
//
|
||||
// This decoding is achieved by delaying the decoding of any sequence
|
||||
// of [KVrA]'s and processing them together in the order: first the
|
||||
// short-circuited KVr part and then the arrays.
|
||||
static int const cvq_K = 1; // Saw at least one K
|
||||
static int const cvq_V = 2; // Saw at least one V
|
||||
static int const cvq_r = 4; // Saw at least one r
|
||||
static int const cvq_A = 8; // Saw at least one A
|
||||
static int const cvq_last = 16; // No remaining qualifiers.
|
||||
static int const cvq_A_cnt = 32; // Bit 5 and higher represent the
|
||||
// number of A's in the series.
|
||||
// In the function below, iter_array points to the first (right most)
|
||||
// A in the series, if any.
|
||||
template<typename Allocator>
|
||||
void
|
||||
qualifier_list<Allocator>::decode_KVrA(
|
||||
string_type& prefix, string_type& postfix, int cvq,
|
||||
typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
const_reverse_iterator const& iter_array) const
|
||||
{
|
||||
_GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA");
|
||||
if ((cvq & cvq_K))
|
||||
prefix += " const";
|
||||
if ((cvq & cvq_V))
|
||||
prefix += " volatile";
|
||||
if ((cvq & cvq_r))
|
||||
prefix += " restrict";
|
||||
if ((cvq & cvq_A))
|
||||
{
|
||||
int n = cvq >> 5;
|
||||
for (typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
const_reverse_iterator iter = iter_array;
|
||||
iter != M_qualifier_starts.rend(); ++iter)
|
||||
{
|
||||
switch((*iter).first_qualifier())
|
||||
{
|
||||
case 'K':
|
||||
case 'V':
|
||||
case 'r':
|
||||
break;
|
||||
case 'A':
|
||||
{
|
||||
string_type index = (*iter).get_optional_type();
|
||||
if (--n == 0 && (cvq & cvq_last))
|
||||
postfix = " [" + index + "]" + postfix;
|
||||
else if (n > 0)
|
||||
postfix = "[" + index + "]" + postfix;
|
||||
else
|
||||
{
|
||||
prefix += " (";
|
||||
postfix = ") [" + index + "]" + postfix;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
_GLIBCXX_DEMANGLER_RETURN3;
|
||||
}
|
||||
}
|
||||
}
|
||||
_GLIBCXX_DEMANGLER_RETURN3;
|
||||
}
|
||||
|
||||
template<typename Allocator>
|
||||
void
|
||||
qualifier_list<Allocator>::decode_qualifiers(
|
||||
@ -1419,9 +1503,12 @@ namespace __gnu_cxx
|
||||
bool member_function_pointer_qualifiers = false) const
|
||||
{
|
||||
_GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers");
|
||||
int cvq = 0;
|
||||
typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
const_reverse_iterator iter_array;
|
||||
for(typename std::vector<qualifier<Allocator>, Allocator>::
|
||||
const_reverse_iterator iter = M_qualifier_starts.rbegin();
|
||||
iter != M_qualifier_starts.rend();)
|
||||
iter != M_qualifier_starts.rend(); ++iter)
|
||||
{
|
||||
if (!member_function_pointer_qualifiers
|
||||
&& !(*iter).part_of_substitution())
|
||||
@ -1437,40 +1524,54 @@ namespace __gnu_cxx
|
||||
switch(qualifier_char)
|
||||
{
|
||||
case 'P':
|
||||
if (cvq)
|
||||
{
|
||||
decode_KVrA(prefix, postfix, cvq, iter_array);
|
||||
cvq = 0;
|
||||
}
|
||||
prefix += "*";
|
||||
break;
|
||||
case 'R':
|
||||
if (cvq)
|
||||
{
|
||||
decode_KVrA(prefix, postfix, cvq, iter_array);
|
||||
cvq = 0;
|
||||
}
|
||||
prefix += "&";
|
||||
break;
|
||||
case 'K':
|
||||
prefix += " const";
|
||||
cvq |= cvq_K;
|
||||
continue;
|
||||
case 'V':
|
||||
prefix += " volatile";
|
||||
cvq |= cvq_V;
|
||||
continue;
|
||||
case 'r':
|
||||
prefix += " restrict";
|
||||
cvq |= cvq_r;
|
||||
continue;
|
||||
case 'A':
|
||||
{
|
||||
string_type index = (*iter).get_optional_type();
|
||||
if (++iter == M_qualifier_starts.rend())
|
||||
postfix = " [" + index + "]" + postfix;
|
||||
else if ((*iter).first_qualifier() == 'A')
|
||||
postfix = "[" + index + "]" + postfix;
|
||||
else
|
||||
if (!(cvq & cvq_A))
|
||||
{
|
||||
prefix += " (";
|
||||
postfix = ") [" + index + "]" + postfix;
|
||||
cvq |= cvq_A;
|
||||
iter_array = iter;
|
||||
}
|
||||
cvq += cvq_A_cnt;
|
||||
break;
|
||||
}
|
||||
case 'M':
|
||||
if (cvq)
|
||||
{
|
||||
decode_KVrA(prefix, postfix, cvq, iter_array);
|
||||
cvq = 0;
|
||||
}
|
||||
prefix += " ";
|
||||
prefix += (*iter).get_optional_type();
|
||||
prefix += "::*";
|
||||
break;
|
||||
case 'U':
|
||||
if (cvq)
|
||||
{
|
||||
decode_KVrA(prefix, postfix, cvq, iter_array);
|
||||
cvq = 0;
|
||||
}
|
||||
prefix += " ";
|
||||
prefix += (*iter).get_optional_type();
|
||||
break;
|
||||
@ -1479,9 +1580,9 @@ namespace __gnu_cxx
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (qualifier_char != 'A')
|
||||
++iter;
|
||||
}
|
||||
if (cvq)
|
||||
decode_KVrA(prefix, postfix, cvq|cvq_last, iter_array);
|
||||
M_printing_suppressed = false;
|
||||
_GLIBCXX_DEMANGLER_RETURN3;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ int main()
|
||||
// standard text
|
||||
// verify_demangle("U4_farrVKPi", "int* volatile const restrict _far");
|
||||
// new __cxa_demangle
|
||||
verify_demangle("U4_farrVKPi", "int* restrict volatile const _far");
|
||||
verify_demangle("U4_farrVKPi", "int* const volatile restrict _far");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
34
libstdc++-v3/testsuite/demangle/regression/cw-16.cc
Normal file
34
libstdc++-v3/testsuite/demangle/regression/cw-16.cc
Normal file
@ -0,0 +1,34 @@
|
||||
// 2003-10-14 Carlo Wood <carlo@alinoe.com>
|
||||
|
||||
// Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library 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 2, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library 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 library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// IA 64 C++ ABI - 5.1 External Names (a.k.a. Mangling)
|
||||
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// libcwd tests
|
||||
int main()
|
||||
{
|
||||
using namespace __gnu_test;
|
||||
|
||||
verify_demangle("_Z3fooIA6_KiEvA9_KT_rVPrS4_",
|
||||
"void foo<int const [6]>(int const [9][6], int const restrict (* volatile restrict) [9][6])");
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user