aboutsummaryrefslogtreecommitdiff
path: root/absl/debugging
diff options
context:
space:
mode:
authorChris Mihelich <cmihelic@google.com>2024-05-30 14:10:22 -0700
committerCopybara-Service <copybara-worker@google.com>2024-05-30 14:11:24 -0700
commit9a2da1a407278eb70be13e5cd392a898cfc11792 (patch)
treecfc40c318bf43a95df006a1d6997df1ca841a0cb /absl/debugging
parentc8671e7542ebfd928ee3e239315c8784fdd88e1c (diff)
downloadabseil-9a2da1a407278eb70be13e5cd392a898cfc11792.tar.gz
abseil-9a2da1a407278eb70be13e5cd392a898cfc11792.tar.bz2
abseil-9a2da1a407278eb70be13e5cd392a898cfc11792.zip
Parse <discriminator> more accurately.
PiperOrigin-RevId: 638778076 Change-Id: I97b9bab2d1b6f87d2f449777145f932949d61a38
Diffstat (limited to 'absl/debugging')
-rw-r--r--absl/debugging/internal/demangle.cc14
-rw-r--r--absl/debugging/internal/demangle_test.cc47
2 files changed, 59 insertions, 2 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index c730f8bf..d32d5980 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -2387,12 +2387,22 @@ static bool ParseLocalName(State *state) {
return false;
}
-// <discriminator> := _ <(non-negative) number>
+// <discriminator> := _ <digit>
+// := __ <number (>= 10)> _
static bool ParseDiscriminator(State *state) {
ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false;
ParseState copy = state->parse_state;
- if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr)) {
+
+ // Both forms start with _ so parse that first.
+ if (!ParseOneCharToken(state, '_')) return false;
+
+ // <digit>
+ if (ParseDigit(state, nullptr)) return true;
+
+ // _ <number> _
+ if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr) &&
+ ParseOneCharToken(state, '_')) {
return true;
}
state->parse_state = copy;
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 58832e99..2895736c 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -479,6 +479,53 @@ TEST(Demangle, Clones) {
EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp)));
}
+TEST(Demangle, Discriminators) {
+ char tmp[80];
+
+ // Source:
+ //
+ // using Thunk = void (*)();
+ //
+ // Thunk* f() {
+ // static Thunk thunks[12] = {};
+ //
+ // #define THUNK(i) [backslash here]
+ // do { struct S { static void g() {} }; thunks[i] = &S::g; } while (0)
+ //
+ // THUNK(0);
+ // [... repeat for 1 to 10 ...]
+ // THUNK(11);
+ //
+ // return thunks;
+ // }
+ //
+ // The test inputs are manglings of some of the S::g member functions.
+
+ // The first one omits the discriminator.
+ EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gEv", tmp, sizeof(tmp)));
+ EXPECT_STREQ("f()::S::g()", tmp);
+
+ // The second one encodes 0.
+ EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_0v", tmp, sizeof(tmp)));
+ EXPECT_STREQ("f()::S::g()", tmp);
+
+ // The eleventh one encodes 9.
+ EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_9v", tmp, sizeof(tmp)));
+ EXPECT_STREQ("f()::S::g()", tmp);
+
+ // The twelfth one encodes 10 with extra underscores delimiting it.
+ EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE__10_v", tmp, sizeof(tmp)));
+ EXPECT_STREQ("f()::S::g()", tmp);
+}
+
+TEST(Demangle, SingleDigitDiscriminatorFollowedByADigit) {
+ char tmp[80];
+
+ // Don't parse 911 as a number.
+ EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_911return_type", tmp, sizeof(tmp)));
+ EXPECT_STREQ("f()::S::g()", tmp);
+}
+
TEST(Demangle, LiteralOfGlobalNamespaceEnumType) {
char tmp[80];