diff --git a/tree/tree/src/TTree.cxx b/tree/tree/src/TTree.cxx index 2a7929789c017..c78906ef66910 100644 --- a/tree/tree/src/TTree.cxx +++ b/tree/tree/src/TTree.cxx @@ -8212,7 +8212,8 @@ void TTree::ResetAfterMerge(TFileMergeInfo *info) } //////////////////////////////////////////////////////////////////////////////// -/// Tell a branch to set its address to zero. +/// Tell a branch to set its address to zero. This is also done for all +/// trees in the list of clones. /// /// @note If the branch owns any objects, they are deleted. @@ -8220,11 +8221,20 @@ void TTree::ResetBranchAddress(TBranch *br) { if (br && br->GetTree()) { br->ResetAddress(); + if (GetListOfClones()) { + for (TObjLink *lnk = GetListOfClones()->FirstLink(); lnk; lnk = lnk->Next()) { + TTree *clone = (TTree *)lnk->GetObject(); + auto clbr = clone ? clone->FindBranch(br->GetName()) : nullptr; + if (clbr) + clone->ResetBranchAddress(clbr); + } + } } } //////////////////////////////////////////////////////////////////////////////// /// Tell all of our branches to drop their current objects and allocate new ones. +/// All trees in lists of Friends and Clones are also told to reset theirs. void TTree::ResetBranchAddresses() { @@ -8248,6 +8258,13 @@ void TTree::ResetBranchAddresses() } } } + if (GetListOfClones()) { + for (TObjLink *lnk = GetListOfClones()->FirstLink(); lnk; lnk = lnk->Next()) { + TTree *clone = (TTree *)lnk->GetObject(); + if (clone) + CopyAddresses(clone); + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/tree/tree/test/TChainRegressions.cxx b/tree/tree/test/TChainRegressions.cxx index 97cdd8a31abab..69f446495392d 100644 --- a/tree/tree/test/TChainRegressions.cxx +++ b/tree/tree/test/TChainRegressions.cxx @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -128,6 +129,52 @@ TEST(TChain, UncommonFileExtension) gSystem->Unlink(dirname); } +// https://github.com/root-project/root/issues/19402 +TEST(TChain, ResetCloneBranchAddress) +{ + std::unique_ptr file1(TFile::Open("t1_19402.root", "RECREATE")); + TTree t1("t", ""); + int value; + t1.Branch("value", &value); + value = 0; + t1.Fill(); + value = 1; + t1.Fill(); + file1->Write(); + file1->Close(); + + std::unique_ptr file2(TFile::Open("t2_19402.root", "RECREATE")); + TTree t2("t", ""); + // int value; + t2.Branch("value", &value); + value = 10; + t2.Fill(); + value = 11; + t2.Fill(); + file2->Write(); + file2->Close(); + + TChain ch("t"); + ch.AddFile("t1_19402.root"); + ch.AddFile("t2_19402.root"); + auto newtree = ch.CloneTree(0); + ch.SetBranchAddress("value", &value); + EXPECT_NE(ch.GetBranch("value")->GetAddress(), nullptr); + EXPECT_NE(newtree->GetBranch("value")->GetAddress(), nullptr); + ch.ResetBranchAddress(ch.GetBranch("value")); + EXPECT_EQ(ch.GetBranch("value")->GetAddress(), nullptr); + EXPECT_EQ(newtree->GetBranch("value")->GetAddress(), nullptr); + ch.SetBranchAddress("value", &value); + EXPECT_NE(ch.GetBranch("value")->GetAddress(), nullptr); + EXPECT_NE(newtree->GetBranch("value")->GetAddress(), nullptr); + ch.ResetBranchAddresses(); + EXPECT_EQ(ch.GetBranch("value")->GetAddress(), nullptr); + EXPECT_EQ(newtree->GetBranch("value")->GetAddress(), nullptr); + + gSystem->Unlink("t1_19402.root"); + gSystem->Unlink("t2_19402.root"); +} + // Originally reproducer of https://github.com/root-project/root/issues/7567 // but see also https://github.com/root-project/root/issues/19220 for an update // The test parameters are