summaryrefslogtreecommitdiff
path: root/absl/debugging
diff options
context:
space:
mode:
authorGravatar Chris Mihelich <cmihelic@google.com>2024-06-06 08:34:38 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2024-06-06 08:35:28 -0700
commitffa1e4a52a35c49e52352674d3099692a3958625 (patch)
treeaed156d9d647ff70ff603fca6b3c95ecee067a16 /absl/debugging
parente7a5d7ace011100f6495cb681c1276371f9a693a (diff)
Demangle new-expressions with braced-init-lists.
PiperOrigin-RevId: 640908672 Change-Id: I85bed6e7d79b24b693007c08acde8e28e3e1429c
Diffstat (limited to 'absl/debugging')
-rw-r--r--absl/debugging/internal/demangle.cc12
-rw-r--r--absl/debugging/internal/demangle_test.cc46
2 files changed, 58 insertions, 0 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index efaaf68d..72cc887b 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -2291,6 +2291,11 @@ static bool ParseExpression(State *state) {
}
// <initializer> ::= pi <expression>* E
+// ::= il <braced-expression>* E
+//
+// The il ... E form is not in the ABI spec but is seen in practice for
+// braced-init-lists in new-expressions, which are standard syntax from C++11
+// on.
static bool ParseInitializer(State *state) {
ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false;
@@ -2301,6 +2306,13 @@ static bool ParseInitializer(State *state) {
return true;
}
state->parse_state = copy;
+
+ if (ParseTwoCharToken(state, "il") &&
+ ZeroOrMore(ParseBracedExpression, state) &&
+ ParseOneCharToken(state, 'E')) {
+ return true;
+ }
+ state->parse_state = copy;
return false;
}
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 033fefcf..317e8494 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -1148,6 +1148,36 @@ TEST(Demangle, GlobalScopeNewExpression) {
EXPECT_STREQ("f<>()", tmp);
}
+TEST(Demangle, NewExpressionWithEmptyBraces) {
+ char tmp[80];
+
+ // Source:
+ //
+ // template <class T> decltype(T{*new T{}}) f() { return T{}; }
+ // template decltype(int{*new int{}}) f<int>();
+ //
+ // GNU demangling:
+ //
+ // decltype (int{*(new int{})}) f<int>()
+ EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denw_S0_ilEEEv", tmp, sizeof(tmp)));
+ EXPECT_STREQ("f<>()", tmp);
+}
+
+TEST(Demangle, NewExpressionWithNonemptyBraces) {
+ char tmp[80];
+
+ // Source:
+ //
+ // template <class T> decltype(T{*new T{42}}) f() { return T{}; }
+ // template decltype(int{*new int{42}}) f<int>();
+ //
+ // GNU demangling:
+ //
+ // decltype (int{*(new int{42})}) f<int>()
+ EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denw_S0_ilLi42EEEEv", tmp, sizeof(tmp)));
+ EXPECT_STREQ("f<>()", tmp);
+}
+
TEST(Demangle, SimpleArrayNewExpression) {
char tmp[80];
@@ -1212,6 +1242,22 @@ TEST(Demangle, GlobalScopeArrayNewExpression) {
EXPECT_STREQ("f<>()", tmp);
}
+TEST(Demangle, ArrayNewExpressionWithTwoElementsInBraces) {
+ char tmp[80];
+
+ // Source:
+ //
+ // template <class T> decltype(T{*new T[2]{1, 2}}) f() { return T{}; }
+ // template decltype(int{*new int[2]{1, 2}}) f<int>();
+ //
+ // GNU demangling:
+ //
+ // decltype (int{*(new int{1, 2})}) f<int>()
+ EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_dena_S0_ilLi1ELi2EEEEv",
+ tmp, sizeof(tmp)));
+ EXPECT_STREQ("f<>()", tmp);
+}
+
TEST(Demangle, ReferenceQualifiedFunctionTypes) {
char tmp[80];