Skip to content

Commit cdc439c

Browse files
committed
[meta] Return exec id of TRef, TRefArray and derived data members
Instead of all data members the type of which has a name beginning with "TRef". Fixes ROOT-7052
1 parent cf996c3 commit cdc439c

File tree

3 files changed

+57
-8
lines changed

3 files changed

+57
-8
lines changed

core/base/test/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ROOT_ADD_GTEST(CoreBaseTests
2323
TStringTest.cxx
2424
TUrlTest.cxx
2525
TBitsTests.cxx
26+
TRefTests.cxx
2627
LIBRARIES ${extralibs} RIO Core)
2728

2829
ROOT_ADD_GTEST(CoreErrorTests TErrorTests.cxx LIBRARIES Core)

core/base/test/TRefTests.cxx

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "gtest/gtest.h"
2+
3+
#include "TClass.h"
4+
#include "TInterpreter.h"
5+
#include "TStreamerElement.h"
6+
#include "TVirtualStreamerInfo.h"
7+
8+
#include <ROOT/TestSupport.hxx>
9+
10+
// See ROOT-7052
11+
TEST(TRef, Exec)
12+
{
13+
14+
// Needed because we do not generate dictionaries and we do no not want to see warnings
15+
ROOT::TestSupport::CheckDiagsRAII checkDiag;
16+
checkDiag.requiredDiag(kWarning, "TStreamerInfo::Build", "MyClass: ", /*matchFullMessage=*/false);
17+
18+
gInterpreter->ProcessLine("class Foo1 : public TRef {\n"
19+
" int i;\n"
20+
"ClassDef(Foo1, 1);\n"
21+
"};"
22+
"class Foo2 : public TRefArray {\n"
23+
" int i;\n"
24+
"ClassDef(Foo2, 1);\n"
25+
"};"
26+
"class TRefFoo {int i;};\n"
27+
"class Foo3 {int i;};\n"
28+
" class MyClass {\n"
29+
" Foo1 m1; // EXEC:GetFoo\n"
30+
" Foo2 m2; // EXEC:GetFoo\n"
31+
" TRefFoo m3; // EXEC:GetFoo\n"
32+
" Foo3 m4; // EXEC:GetFoo\n"
33+
"};");
34+
35+
auto c = TClass::GetClass("MyClass");
36+
auto si = c->GetStreamerInfo();
37+
int o;
38+
auto se1 = si->GetStreamerElement("m1", o);
39+
auto se2 = si->GetStreamerElement("m2", o);
40+
auto se3 = si->GetStreamerElement("m3", o);
41+
auto se4 = si->GetStreamerElement("m4", o);
42+
43+
EXPECT_EQ(1, se1->GetExecID());
44+
EXPECT_EQ(1, se2->GetExecID());
45+
EXPECT_EQ(0, se3->GetExecID());
46+
EXPECT_EQ(0, se4->GetExecID());
47+
}

core/meta/src/TStreamerElement.cxx

+9-8
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@
99
* For the list of contributors see $ROOTSYS/README/CREDITS. *
1010
*************************************************************************/
1111

12-
//////////////////////////////////////////////////////////////////////////
13-
// //
14-
// //
15-
//////////////////////////////////////////////////////////////////////////
16-
17-
1812
#include "TROOT.h"
1913
#include "TStreamerElement.h"
2014
#include "TVirtualStreamerInfo.h"
@@ -308,8 +302,15 @@ TClass *TStreamerElement::GetClassPointer() const
308302

309303
Int_t TStreamerElement::GetExecID() const
310304
{
311-
//check if element is a TRef or TRefArray
312-
if (strncmp(fTypeName.Data(),"TRef",4) != 0) return 0;
305+
TString typeName = fTypeName;
306+
if (typeName != "TRef" && typeName != "TRefArray") {
307+
// It's not a ROOT standard TRef or TRefArray class, but it could be a user class
308+
// inheriting from it (see ROOT-7052)
309+
const TString clName = ExtractClassName(fTypeName);
310+
const auto cl = TClass::GetClass(clName, kFALSE, kTRUE);
311+
if (!cl || (nullptr == cl->GetBaseClass("TRef") && nullptr == cl->GetBaseClass("TRefArray")))
312+
return 0;
313+
}
313314

314315
//if the UniqueID of this element has already been set, we assume
315316
//that it contains the exec id of a TRef object.

0 commit comments

Comments
 (0)