Skip to content

Commit f4e0d07

Browse files
committed
[core] Fix improper name normalization in KeepNParams
The algorithm was not recording any default arguments into argsToKeep, but it actually needs to keep them as long as they are followed by a non-default argument. This would cause issues such as this: // std::less<int> is a default argument, but MyAlloc is not using MyMap = std::map<int, int, std::less<int>, MyAlloc>; TClass::GetClass("MyMap")->GetName() # prints "map<int,int,MyAlloc>" !
1 parent d6dbb52 commit f4e0d07

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

core/clingutils/src/TClingUtils.cxx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4047,6 +4047,7 @@ static void KeepNParams(clang::QualType& normalizedType,
40474047
const int nNormArgs = normArgs.size();
40484048

40494049
bool mightHaveChanged = false;
4050+
int latestNonDefaultArg = -1;
40504051

40514052
// becomes true when a parameter has a value equal to its default
40524053
for (int formal = 0, inst = 0; formal != nArgs; ++formal, ++inst) {
@@ -4085,10 +4086,12 @@ static void KeepNParams(clang::QualType& normalizedType,
40854086
argsToKeep.push_back(normTArg);
40864087
}
40874088
// Done.
4089+
latestNonDefaultArg = -1;
40884090
break;
40894091
}
40904092
mightHaveChanged |= RecurseKeepNParams(normTArg, tArg, interp, normCtxt, astCtxt);
40914093
argsToKeep.push_back(normTArg);
4094+
latestNonDefaultArg = formal;
40924095
continue;
40934096
} else {
40944097
if (!isStdDropDefault) {
@@ -4110,16 +4113,21 @@ static void KeepNParams(clang::QualType& normalizedType,
41104113
} else if (argKind == clang::TemplateArgument::Integral){
41114114
equal = areEqualValues(tArg, *tParPtr);
41124115
}
4116+
4117+
argsToKeep.push_back(normTArg);
41134118
if (!equal) {
4119+
latestNonDefaultArg = formal;
41144120
mightHaveChanged |= RecurseKeepNParams(normTArg, tArg, interp, normCtxt, astCtxt);
4115-
argsToKeep.push_back(normTArg);
41164121
} else {
41174122
mightHaveChanged = true;
41184123
}
41194124

41204125

41214126
} // of loop over parameters and arguments
41224127

4128+
if (latestNonDefaultArg >= 0)
4129+
argsToKeep.resize(latestNonDefaultArg + 1);
4130+
41234131
if (!prefix_changed && !mightHaveChanged) {
41244132
normalizedType = originalNormalizedType;
41254133
return;
@@ -4140,7 +4148,6 @@ static void KeepNParams(clang::QualType& normalizedType,
41404148
normalizedType = astCtxt.getElaboratedType(clang::ElaboratedTypeKeyword::None, prefix, normalizedType);
41414149
normalizedType = astCtxt.getQualifiedType(normalizedType,prefix_qualifiers);
41424150
}
4143-
41444151
}
41454152

41464153
////////////////////////////////////////////////////////////////////////////////

core/foundation/test/testClassEdit.cxx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,26 @@ TEST(TClassEdit, GetNormalizedName)
310310

311311
n.clear();
312312
EXPECT_THROW(TClassEdit::GetNormalizedName(n, "_Atomic(map<string, TObjArray* >*"), std::runtime_error);
313+
}
314+
315+
TEST(TClassEdit, GetNormalizedNameTypedef)
316+
{
317+
std::string n;
318+
319+
gInterpreter->Declare(R"(
320+
struct MyAlloc {};
321+
using MyMap = std::map<int,int,std::less<int>,MyAlloc>;
322+
)");
323+
324+
TClassEdit::GetNormalizedName(n, "MyMap");
325+
EXPECT_STREQ("map<int,int,less<int>,MyAlloc>", n.c_str());
326+
327+
gInterpreter->Declare(R"(
328+
using MyMapDefault = std::map<int,int,std::less<int>,std::allocator<std::pair<const int,int>>>;
329+
)");
313330

331+
TClassEdit::GetNormalizedName(n, "MyMapDefault");
332+
EXPECT_STREQ("std::map<int,int>", n.c_str());
314333
}
315334

316335
// https://github.com/root-project/root/issues/18654

0 commit comments

Comments
 (0)