From 74c5a3706b4504bb63305abd888779099dcd9d49 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Tue, 26 Nov 2024 10:43:31 +0100 Subject: [PATCH 1/7] [core] remove class prefix if any in IsDefAlloc Fixes https://github.com/root-project/root/issues/6607 --- core/foundation/src/TClassEdit.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/foundation/src/TClassEdit.cxx b/core/foundation/src/TClassEdit.cxx index d3115602c30d0..a4facc6eb8be1 100644 --- a/core/foundation/src/TClassEdit.cxx +++ b/core/foundation/src/TClassEdit.cxx @@ -621,6 +621,10 @@ static size_t findNameEnd(const std::string &full, size_t pos) bool TClassEdit::IsDefAlloc(const char *allocname, const char *classname) { string_view a( allocname ); + const static int clalloclen = strlen("class "); + if (a.compare(0,clalloclen,"class ") == 0) { + a.remove_prefix(clalloclen); + } RemoveStd(a); if (a=="alloc") return true; From a4103aee65246b52f276109de733de7f313b1e0d Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Tue, 26 Nov 2024 10:48:45 +0100 Subject: [PATCH 2/7] [core] add test for IsDefAlloc with class prefix --- core/foundation/test/testClassEdit.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/foundation/test/testClassEdit.cxx b/core/foundation/test/testClassEdit.cxx index 384cde50fc9ab..efec0924ae19d 100644 --- a/core/foundation/test/testClassEdit.cxx +++ b/core/foundation/test/testClassEdit.cxx @@ -274,3 +274,9 @@ TEST(TClassEdit, DefComp) { EXPECT_FALSE(TClassEdit::IsDefComp("std::less<>", "std::string")); } + +// https://github.com/root-project/root/issues/6607 +TEST(TClassEdit, DefAlloc) +{ + EXPECT_TRUE(TClassEdit::IsDefAlloc("class std::allocator", "float")); +} From 0bf4df4a1ca3e6ad9e241d34a5966f5fcf4328dc Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Tue, 26 Nov 2024 15:31:38 +0100 Subject: [PATCH 3/7] [core] add original test for getnormalizedname GH issue as suggested by dpiparo --- core/foundation/test/testClassEdit.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/foundation/test/testClassEdit.cxx b/core/foundation/test/testClassEdit.cxx index efec0924ae19d..63766a4747581 100644 --- a/core/foundation/test/testClassEdit.cxx +++ b/core/foundation/test/testClassEdit.cxx @@ -280,3 +280,11 @@ TEST(TClassEdit, DefAlloc) { EXPECT_TRUE(TClassEdit::IsDefAlloc("class std::allocator", "float")); } + +// https://github.com/root-project/root/issues/6607 +TEST(TClassEdit, GetNormalizedName) +{ + std::string n; + TClassEdit::GetNormalizedName(n, "std::vector>"); + EXPECT_STREQ("vector", n.c_str()); +} From 8104898247e3beb5202ff640cdf211aa74b36596 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Tue, 3 Dec 2024 17:30:18 +0100 Subject: [PATCH 4/7] [core] skip potentially preceding class prefix --- core/foundation/src/TClassEdit.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/foundation/src/TClassEdit.cxx b/core/foundation/src/TClassEdit.cxx index a4facc6eb8be1..98302971d8619 100644 --- a/core/foundation/src/TClassEdit.cxx +++ b/core/foundation/src/TClassEdit.cxx @@ -1537,14 +1537,17 @@ static void ResolveTypedefImpl(const char *tname, } while (tname[cursor]==' ') ++cursor; } - + if (tname[cursor]=='c' && (cursor+6 2 && strncmp(tname+cursor,"::",2) == 0) { From 35395a3e00c6054cf055d7b16fea2256ab8205f4 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Wed, 4 Dec 2024 17:36:38 +0100 Subject: [PATCH 5/7] [core] use constexpr static instead of const static as suggested by pcanal --- core/foundation/src/TClassEdit.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/foundation/src/TClassEdit.cxx b/core/foundation/src/TClassEdit.cxx index 98302971d8619..6be77c0f9d7d3 100644 --- a/core/foundation/src/TClassEdit.cxx +++ b/core/foundation/src/TClassEdit.cxx @@ -621,7 +621,7 @@ static size_t findNameEnd(const std::string &full, size_t pos) bool TClassEdit::IsDefAlloc(const char *allocname, const char *classname) { string_view a( allocname ); - const static int clalloclen = strlen("class "); + constexpr static int clalloclen = strlen("class "); if (a.compare(0,clalloclen,"class ") == 0) { a.remove_prefix(clalloclen); } @@ -631,7 +631,7 @@ bool TClassEdit::IsDefAlloc(const char *allocname, const char *classname) if (a=="__default_alloc_template") return true; if (a=="__malloc_alloc_template<0>") return true; - const static int alloclen = strlen("allocator<"); + constexpr static int alloclen = strlen("allocator<"); if (a.compare(0,alloclen,"allocator<") != 0) { return false; } @@ -680,7 +680,7 @@ bool TClassEdit::IsDefAlloc(const char *allocname, string_view a( allocname ); RemoveStd(a); - const static int alloclen = strlen("allocator<"); + constexpr static int alloclen = strlen("allocator<"); if (a.compare(0,alloclen,"allocator<") != 0) { return false; } @@ -688,7 +688,7 @@ bool TClassEdit::IsDefAlloc(const char *allocname, RemoveStd(a); - const static int pairlen = strlen("pair<"); + constexpr static int pairlen = strlen("pair<"); if (a.compare(0,pairlen,"pair<") != 0) { return false; } From 044b1a4e2c3fe94fa77c8d7c2f04ba54b58038e1 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Wed, 4 Dec 2024 17:53:18 +0100 Subject: [PATCH 6/7] [skip-ci] clarify rationale of skipping leading 'class ' as suggested by pcanal --- core/foundation/src/TClassEdit.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/foundation/src/TClassEdit.cxx b/core/foundation/src/TClassEdit.cxx index 6be77c0f9d7d3..56287eeebf1ae 100644 --- a/core/foundation/src/TClassEdit.cxx +++ b/core/foundation/src/TClassEdit.cxx @@ -621,6 +621,8 @@ static size_t findNameEnd(const std::string &full, size_t pos) bool TClassEdit::IsDefAlloc(const char *allocname, const char *classname) { string_view a( allocname ); + // In Windows, allocname might be 'class const std::allocator', + // (never 'const class ...'), so we start by stripping the 'class ', if any constexpr static int clalloclen = strlen("class "); if (a.compare(0,clalloclen,"class ") == 0) { a.remove_prefix(clalloclen); @@ -1537,6 +1539,8 @@ static void ResolveTypedefImpl(const char *tname, } while (tname[cursor]==' ') ++cursor; } + // In Windows, we might have 'class const ...' as name, + // (never 'const class ...'), so skip the leading 'class ', if any if (tname[cursor]=='c' && (cursor+6 Date: Wed, 4 Dec 2024 18:16:17 +0100 Subject: [PATCH 7/7] [core] fix: try constexpr alternative to strlen --- core/foundation/src/TClassEdit.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/foundation/src/TClassEdit.cxx b/core/foundation/src/TClassEdit.cxx index 56287eeebf1ae..bbba888b3c78d 100644 --- a/core/foundation/src/TClassEdit.cxx +++ b/core/foundation/src/TClassEdit.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include "TSpinLockGuard.h" @@ -623,7 +624,7 @@ bool TClassEdit::IsDefAlloc(const char *allocname, const char *classname) string_view a( allocname ); // In Windows, allocname might be 'class const std::allocator', // (never 'const class ...'), so we start by stripping the 'class ', if any - constexpr static int clalloclen = strlen("class "); + constexpr static int clalloclen = std::char_traits::length("class "); if (a.compare(0,clalloclen,"class ") == 0) { a.remove_prefix(clalloclen); } @@ -633,7 +634,7 @@ bool TClassEdit::IsDefAlloc(const char *allocname, const char *classname) if (a=="__default_alloc_template") return true; if (a=="__malloc_alloc_template<0>") return true; - constexpr static int alloclen = strlen("allocator<"); + constexpr static int alloclen = std::char_traits::length("allocator<"); if (a.compare(0,alloclen,"allocator<") != 0) { return false; } @@ -682,7 +683,7 @@ bool TClassEdit::IsDefAlloc(const char *allocname, string_view a( allocname ); RemoveStd(a); - constexpr static int alloclen = strlen("allocator<"); + constexpr static int alloclen = std::char_traits::length("allocator<"); if (a.compare(0,alloclen,"allocator<") != 0) { return false; } @@ -690,7 +691,7 @@ bool TClassEdit::IsDefAlloc(const char *allocname, RemoveStd(a); - constexpr static int pairlen = strlen("pair<"); + constexpr static int pairlen = std::char_traits::length("pair<"); if (a.compare(0,pairlen,"pair<") != 0) { return false; }