From 8cd42d3cc2461df394c718afc270574a061a6ef6 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 21 Dec 2020 15:50:02 -0500 Subject: [PATCH] c++: Fix demangling of qualified-id after '.' The demangler was assuming that only an unqualified-id could appear after . or ->. libiberty/ChangeLog: * cp-demangle.c (d_expression_1): Recognize qualified-id on RHS of dt/pt. * testsuite/demangle-expected: Add test. --- libiberty/cp-demangle.c | 20 ++++++++++++++++---- libiberty/testsuite/demangle-expected | 3 +++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 96f43b65ad6..98ab47a3460 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -3476,10 +3476,22 @@ d_expression_1 (struct d_info *di) right = d_exprlist (di, 'E'); else if (!strcmp (code, "dt") || !strcmp (code, "pt")) { - right = d_unqualified_name (di); - if (d_peek_char (di) == 'I') - right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, - right, d_template_args (di)); + peek = d_peek_char (di); + /* These codes start a qualified name. */ + if ((peek == 'g' && d_peek_next_char (di) == 's') + || (peek == 's' && d_peek_next_char (di) == 'r')) + right = d_expression_1 (di); + else + { + /* Otherwise it's an unqualified name. We use + d_unqualified_name rather than d_expression_1 here for + old mangled names that didn't add 'on' before operator + names. */ + right = d_unqualified_name (di); + if (d_peek_char (di) == 'I') + right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, + right, d_template_args (di)); + } } else right = d_expression_1 (di); diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 6e3e6716def..6789d0d1d9d 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -1482,3 +1482,6 @@ void g(S<&A::operator int>) _Z1jI1AEDTcldtfp_oncvPT_EES1_ decltype (({parm#1}.(operator A*))()) j(A) + +_Z1fI1AEDtdtfp_srT_1xES1_ +decltype ({parm#1}.A::x) f(A)