From 920ff9950120df6e5f7b72c98d293cbe6f4b2ca6 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 27 Jul 2026 03:33:08 +0000 Subject: [PATCH 1/4] [io] Fix crash reading emulated collections of SSO strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TEmulatedCollectionProxy stores the collection in a std::vector of raw aligned bytes. When that buffer grows past its capacity, Expand() lets it relocate the existing elements with a raw memory copy. That is correct for trivially relocatable content, but corrupts emulated objects that keep a pointer into themselves -- most notably a libstdc++ std::string (and TString) using the small-string optimization, whose internal data pointer keeps pointing into the old, now freed, buffer. The corrupted object then crashes when it is destroyed, freeing an invalid pointer. TClass::Move(), invoked by Expand(), does not actually move the data, so it cannot fix up the relocated objects. Expand() is however only ever reached while preparing the collection to be entirely overwritten by a member-wise read, so when the buffer would reallocate and the value/key would not survive a raw memory copy, destroy the (still valid) elements first and reconstruct all of them at the new location instead of relocating them. Whether a raw memory copy is good enough is now decided by the new TClass::IsTriviallyRelocatable(), backed by a new kClassIsTriviallyRelocatable class property that TClingClassInfo::ClassProperty() fills in from Sema's implementation of C++26 trivial relocatability ([class.prop], P2786), via clang::Sema::IsCXXTriviallyRelocatableType(). Every trivially copyable class is trivially relocatable, but not vice versa: for example a polymorphic class whose bases and members are all trivially relocatable qualifies too. A positive answer rules out both freeing a resource twice or from the wrong address and skipping a non-trivial copy constructor. It is still not a proof -- `struct Foo { Foo *ptr = this; };` is trivially copyable, hence trivially relocatable, yet a raw memory copy leaves ptr pointing at the old location, and nothing observable here would reveal that -- but such a class is relocated exactly as it was before, so the check can never do worse than the unconditional memcpy it replaces. A class the interpreter does not know about, in particular an emulated one described only by a TStreamerInfo, gets the conservative answer, since its members can be anything, for example the std::string of an emulated std::pair. TClass::Move() itself was silent about all this: it only records the address change in the object version repository and otherwise does nothing, leaving a caller that relocated the data with a raw memory copy no indication that the objects it just "moved" are now corrupted. It now reports an error, once per class, when asked to move a type that fails the same check. It cannot tell a raw memory copy from a real move, so the message is phrased conditionally; the in-tree callers avoid the memcpy for these types already, so this is aimed at external users of this public method. Note that Expand() now reconstructs the elements below nCurr instead of carrying their bytes over, so a member that is not written for a given entry is default-constructed rather than retaining the value from the previous one. That only shows up with schema evolution or unread sub-branches, and matches what the elements above nCurr have always done. A new test, roottest/root/io/emulatedGrow, writes a class holding a std::vector> whose collection grows on every entry and reads it back without its dictionary, so the emulated buffer has to reallocate repeatedly. It checks the values it reads back instead of comparing against a reference, so silent corruption fails it too. This fixes the abort observed when reading e.g. a std::vector> without its dictionary. Closes #20882 🤖 Done with the help of AI. --- README/ReleaseNotes/v642/index.md | 4 ++ core/meta/inc/TClass.h | 1 + core/meta/inc/TDictionary.h | 27 +++---- core/meta/src/TClass.cxx | 59 ++++++++++++++++ core/metacling/src/TClingClassInfo.cxx | 7 ++ core/metacling/test/TClingTests.cxx | 39 +++++++++-- io/io/inc/TEmulatedCollectionProxy.h | 2 +- io/io/src/TEmulatedCollectionProxy.cxx | 45 +++++++++++- roottest/root/io/emulatedGrow/CMakeLists.txt | 7 ++ .../root/io/emulatedGrow/growingPairVector.h | 46 ++++++++++++ .../io/emulatedGrow/readGrowingPairVector.C | 70 +++++++++++++++++++ .../io/emulatedGrow/writeGrowingPairVector.C | 27 +++++++ 12 files changed, 314 insertions(+), 20 deletions(-) create mode 100644 roottest/root/io/emulatedGrow/CMakeLists.txt create mode 100644 roottest/root/io/emulatedGrow/growingPairVector.h create mode 100644 roottest/root/io/emulatedGrow/readGrowingPairVector.C create mode 100644 roottest/root/io/emulatedGrow/writeGrowingPairVector.C diff --git a/README/ReleaseNotes/v642/index.md b/README/ReleaseNotes/v642/index.md index a281ac5303589..a62d10b760fcc 100644 --- a/README/ReleaseNotes/v642/index.md +++ b/README/ReleaseNotes/v642/index.md @@ -93,8 +93,12 @@ Replace `obj.Connect(signal, "TPyDispatcher", disp, "Dispatch()")` with ## I/O +* Reading a collection without its dictionary no longer crashes when the elements hold a `std::string` or a `TString`. The emulated collection proxy relocated its elements with a raw memory copy when its buffer had to grow, which corrupts an object that points into itself, such as a `std::string` using the small string optimization; the invalid pointer was then freed when the object was destroyed. Such elements are now destroyed and reconstructed at the new location instead. This affected for instance a `std::vector>` read back without a dictionary. + ## Core +* `TClass::IsTriviallyRelocatable()` reports whether an object of a class can be moved to a new address with a raw memory copy, i.e. without running a move or copy constructor (trivial relocatability in the C++26 sense). It is backed by the new `kClassIsTriviallyRelocatable` class property, which `TInterpreter::ClassInfo_ClassProperty()` now fills in. A class the interpreter does not know about, in particular an emulated one, is conservatively reported as not relocatable. + ## Histograms ### Cumulative histograms in more than one dimension diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h index fec709736ea2b..38f68c3b083dd 100644 --- a/core/meta/inc/TClass.h +++ b/core/meta/inc/TClass.h @@ -530,6 +530,7 @@ friend class TStreamerInfo; Bool_t InheritsFrom(const char *cl) const override; Bool_t InheritsFrom(const TClass *cl) const override; void InterpretedShowMembers(void* obj, TMemberInspector &insp, Bool_t isTransient); + Bool_t IsTriviallyRelocatable() const; Bool_t IsFolder() const override { return kTRUE; } Bool_t IsLoaded() const; Bool_t IsForeign() const; diff --git a/core/meta/inc/TDictionary.h b/core/meta/inc/TDictionary.h index a63db53a4caa8..11909aa173ee3 100644 --- a/core/meta/inc/TDictionary.h +++ b/core/meta/inc/TDictionary.h @@ -132,20 +132,23 @@ enum EFunctionProperty { kIsTemplateSpec= 0x00000020 }; +// clang-format off enum EClassProperty { - kClassIsValid = 0x00000001, - kClassHasExplicitCtor = 0x00000010, - kClassHasImplicitCtor = 0x00000020, - kClassHasCtor = 0x00000030, - kClassHasDefaultCtor = 0x00000040, - kClassHasAssignOpr = 0x00000080, - kClassHasExplicitDtor = 0x00000100, - kClassHasImplicitDtor = 0x00000200, - kClassHasDtor = 0x00000300, - kClassHasVirtual = 0x00001000, - kClassIsAbstract = 0x00002000, - kClassIsAggregate = 0x00004000 + kClassIsValid = 0x00000001, + kClassHasExplicitCtor = 0x00000010, + kClassHasImplicitCtor = 0x00000020, + kClassHasCtor = 0x00000030, + kClassHasDefaultCtor = 0x00000040, + kClassHasAssignOpr = 0x00000080, + kClassHasExplicitDtor = 0x00000100, + kClassHasImplicitDtor = 0x00000200, + kClassHasDtor = 0x00000300, + kClassHasVirtual = 0x00001000, + kClassIsAbstract = 0x00002000, + kClassIsAggregate = 0x00004000, + kClassIsTriviallyRelocatable = 0x00008000 }; +// clang-format on enum ERefTypeValues { kParaNormal = 0, // not used diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx index 37c2b3824ae2c..2e4f6264be763 100644 --- a/core/meta/src/TClass.cxx +++ b/core/meta/src/TClass.cxx @@ -95,6 +95,7 @@ In order to access the name of a class within the ROOT type system, the method T #include #include #include +#include #include #include #include @@ -4378,6 +4379,39 @@ void TClass::MakeCustomMenuList() delete methodList; } +//////////////////////////////////////////////////////////////////////////////// +/// Return kTRUE if an object of this class can be relocated to a new address +/// with a raw memory copy, i.e. without running a move or copy constructor -- +/// trivial relocatability in the C++26 sense ([class.prop]), as answered by the +/// interpreter. Every trivially copyable class is trivially relocatable, but not +/// every trivially relocatable class is trivially copyable: e.g. a polymorphic +/// class whose bases and members are all trivially relocatable qualifies too. +/// +/// A kTRUE answer rules out both a resource being freed twice or from the wrong +/// address (the failure mode of root-project/root#20882) and a non-trivial copy +/// constructor being skipped. It is still not a proof that a raw memory copy +/// preserves the class' semantics: +/// ~~~ {.cpp} +/// struct Foo { Foo *ptr = this; }; +/// ~~~ +/// is trivially copyable, hence trivially relocatable, yet a raw memory copy +/// leaves `ptr` pointing at the old location -- and nothing observable here +/// would reveal that. Such a class is relocated the way it always has been. +/// +/// An emulated class, described only by a TStreamerInfo, gets the conservative +/// answer since its members can be anything -- e.g. the std::string of an +/// emulated pair. + +Bool_t TClass::IsTriviallyRelocatable() const +{ + const Long_t classProperty = ClassProperty(); + // No kClassIsValid means no interpreter information at all (emulated class, + // forward declaration, ...), so assume the worst. + if (!(classProperty & kClassIsValid)) + return kFALSE; + return (classProperty & kClassIsTriviallyRelocatable) != 0; +} + //////////////////////////////////////////////////////////////////////////////// /// Register the fact that an object was moved from the memory location /// 'arenaFrom' to the memory location 'arenaTo'. @@ -4388,6 +4422,31 @@ void TClass::Move(void *arenaFrom, void *arenaTo) const // constructor), this function should also perform the data move. // For now we just information the repository. + // This only records the new address; a caller that relocated the data with a + // raw memory copy silently corrupts the types that do not support it, so warn + // about those rather than let it surface later as an obscure crash (typically + // an invalid free). A caller that did run a real move or copy constructor can + // ignore the message -- we have no way to tell the two apart here. The in-tree + // callers, in TEmulatedCollectionProxy::Expand, already avoid the memcpy for + // these types, so this is aimed at external users of this public method. + if (!IsTriviallyRelocatable()) { + // Keyed by name rather than by 'this': a TClass can be deleted and another + // one allocated at the same address, which would silence the message. + static std::mutex sMoveDiagMutex; + static std::set sMoveDiagDone; + bool firstTime = false; + { + std::lock_guard guard(sMoveDiagMutex); + firstTime = sMoveDiagDone.emplace(GetName()).second; + } + if (firstTime) + Error("Move", + "Objects of type %s are not trivially relocatable, i.e. can not be relocated with a raw memory copy. " + "TClass::Move does not move the data itself (here from %p to %p), so if the caller relocated it that " + "way the objects are now corrupted.", + GetName(), arenaFrom, arenaTo); + } + if ((GetState() <= kEmulated) && !fCollectionProxy) { MoveAddressInRepository("TClass::Move",arenaFrom,arenaTo,this); } diff --git a/core/metacling/src/TClingClassInfo.cxx b/core/metacling/src/TClingClassInfo.cxx index 434996e2cb5aa..5d4015d174e34 100644 --- a/core/metacling/src/TClingClassInfo.cxx +++ b/core/metacling/src/TClingClassInfo.cxx @@ -199,6 +199,13 @@ long TClingClassInfo::ClassProperty() const // according to the C++ standard, being a POD implies being an aggregate property |= kClassIsAggregate; } + if (CRD->hasDefinition() && fInterp->getSema().IsCXXTriviallyRelocatableType(*CRD)) { + // Trivial relocatability in the C++26 sense ([class.prop]), as computed by + // Sema. This is more accurate than isTriviallyCopyable(): every trivially + // copyable class is trivially relocatable, but not vice versa -- e.g. a + // polymorphic class whose bases and members are all trivially relocatable. + property |= kClassIsTriviallyRelocatable; + } return property; } diff --git a/core/metacling/test/TClingTests.cxx b/core/metacling/test/TClingTests.cxx index 2a54d12864dd3..36f40787339ee 100644 --- a/core/metacling/test/TClingTests.cxx +++ b/core/metacling/test/TClingTests.cxx @@ -318,20 +318,49 @@ struct ClassIsAggregate { int x; double y; }; + +struct ClassIsTriviallyRelocatable { + int x; + double y; +}; + +// not trivially copyable because of the virtual function, but still trivially +// relocatable in the C++26 sense +struct ClassIsTriviallyRelocatablePolymorphic { + virtual ~ClassIsTriviallyRelocatablePolymorphic() = default; + int x; +}; + +// a non-trivial copy constructor is enough to lose trivial relocatability, even +// though the destructor stays trivial +struct ClassIsNotTriviallyRelocatable { + int x; + ClassIsNotTriviallyRelocatable(const ClassIsNotTriviallyRelocatable &other) : x(other.x) {} +}; )cpp"); + // clang-format off const std::vector> classNPPairs{ - {"ClassHasImplicitCtor", kClassHasImplicitCtor}, {"ClassHasExplicitCtor", kClassHasExplicitCtor}, - {"ClassHasExplicitDtor", kClassHasExplicitDtor}, {"ClassHasImplicitDtor", kClassHasImplicitDtor}, - {"ClassHasDefaultCtor", kClassHasDefaultCtor}, {"ClassHasDefaultCtor", kClassIsValid}, - {"ClassIsAbstract", kClassIsAbstract}, {"ClassHasVirtual", kClassHasVirtual}, - {"ClassHasAssignOpr", kClassHasAssignOpr}, {"ClassIsAggregate", kClassIsAggregate}}; + {"ClassHasImplicitCtor", kClassHasImplicitCtor}, {"ClassHasExplicitCtor", kClassHasExplicitCtor}, + {"ClassHasExplicitDtor", kClassHasExplicitDtor}, {"ClassHasImplicitDtor", kClassHasImplicitDtor}, + {"ClassHasDefaultCtor", kClassHasDefaultCtor}, {"ClassHasDefaultCtor", kClassIsValid}, + {"ClassIsAbstract", kClassIsAbstract}, {"ClassHasVirtual", kClassHasVirtual}, + {"ClassHasAssignOpr", kClassHasAssignOpr}, {"ClassIsAggregate", kClassIsAggregate}, + {"ClassIsTriviallyRelocatable", kClassIsTriviallyRelocatable}, + {"ClassIsTriviallyRelocatablePolymorphic", kClassIsTriviallyRelocatable}}; + // clang-format on for (auto &[clName, clPropRef] : classNPPairs) { auto cl = TClass::GetClass(clName.c_str()); const auto prop = gInterpreter->ClassInfo_ClassProperty(cl->GetClassInfo()); EXPECT_TRUE(prop & clPropRef) << "Error checking property for class " << clName; } + + // A trivial destructor is not enough: the copy constructor matters too. + auto notTrivial = TClass::GetClass("ClassIsNotTriviallyRelocatable"); + const auto notTrivialProp = gInterpreter->ClassInfo_ClassProperty(notTrivial->GetClassInfo()); + EXPECT_FALSE(notTrivialProp & kClassIsTriviallyRelocatable); + EXPECT_FALSE(notTrivialProp & kClassHasDtor); } // #12108 diff --git a/io/io/inc/TEmulatedCollectionProxy.h b/io/io/inc/TEmulatedCollectionProxy.h index 1c4e7863fd5e2..843807b0f13d4 100644 --- a/io/io/inc/TEmulatedCollectionProxy.h +++ b/io/io/inc/TEmulatedCollectionProxy.h @@ -117,7 +117,7 @@ class TEmulatedCollectionProxy : public TGenCollectionProxy { void Shrink(UInt_t nCurr, UInt_t left, Bool_t force); // Expand the container - void Expand(UInt_t nCurr, UInt_t left); + void Expand(UInt_t nCurr, UInt_t left, Bool_t force); private: TEmulatedCollectionProxy &operator=(const TEmulatedCollectionProxy &); // Not implemented. diff --git a/io/io/src/TEmulatedCollectionProxy.cxx b/io/io/src/TEmulatedCollectionProxy.cxx index b951b314b45f6..c42ef59da14d6 100644 --- a/io/io/src/TEmulatedCollectionProxy.cxx +++ b/io/io/src/TEmulatedCollectionProxy.cxx @@ -24,6 +24,7 @@ the class TEmulatedMapProxy. */ #include "TEmulatedCollectionProxy.h" +#include "TClass.h" #include "TStreamerElement.h" #include "TStreamerInfo.h" #include "TClassEdit.h" @@ -371,10 +372,50 @@ void TEmulatedCollectionProxy::Shrink(UInt_t nCurr, UInt_t left, Bool_t force ) return; } -void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left) +void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left, Bool_t force) { // Expand the container size_t i; + + // The storage is a std::vector of raw, aligned bytes: growing it past its + // capacity relocates the elements with a raw memory copy. That corrupts an + // object holding a pointer into itself -- notably std::string (and TString) + // using the small-string optimization, whose data pointer would keep pointing + // into the old, freed, buffer and be freed again from there when the object is + // destroyed (https://github.com/root-project/root/issues/20882). + // + // TClass::Move (used below) does not actually move the data (in the C++ sense), so it cannot fix + // those up. Expand is however only reached while preparing the collection to + // be entirely overwritten by a member-wise read, so we destroy such elements + // here -- while they are still valid -- and let the code below reconstruct + // them at the new location instead of relocating them. + auto needsRealMove = [](const Value *v) { + if (!v || (v->fCase & kIsPointer)) + return false; // a pointer relocates fine + if (v->fCase & kBIT_ISSTRING) + return true; // std::string, see above + if (v->fCase & kIsClass) { + // TClass is conservative for the types the interpreter does not know. + TClass *cl = v->fType.GetClass(); + return !cl || !cl->IsTriviallyRelocatable(); + } + return false; // fundamental types and enums + }; + if (nCurr > 0) { + // Only worth asking about the type if the buffer actually reallocates. + bool willReallocate = false; + WithCont(fEnv->fObject, [&](auto *c, std::size_t alignmentElemSize) { + willReallocate = (left * fValDiff / alignmentElemSize) > c->capacity(); + }); + if (willReallocate && (needsRealMove(fVal) || needsRealMove(fKey))) { + // Destroys the elements in place and resizes to 0, keeping the capacity; + // the buffer grows again right below with no live object to relocate. + // 'force' is the caller's: it decides whether pointees are deleted too. + Shrink(nCurr, 0, force); + nCurr = 0; + } + } + void *oldstart = fEnv->fStart; WithCont(fEnv->fObject, [&](auto *c, std::size_t alignmentElemSize) { assert(fValDiff % alignmentElemSize == 0); @@ -467,7 +508,7 @@ void TEmulatedCollectionProxy::Resize(UInt_t left, Bool_t force) Shrink(nCurr, left, force); return; } - Expand(nCurr, left); + Expand(nCurr, left, force); return; } Fatal("TEmulatedCollectionProxy","Resize> Logic error - no proxy object set."); diff --git a/roottest/root/io/emulatedGrow/CMakeLists.txt b/roottest/root/io/emulatedGrow/CMakeLists.txt new file mode 100644 index 0000000000000..02593a8403df0 --- /dev/null +++ b/roottest/root/io/emulatedGrow/CMakeLists.txt @@ -0,0 +1,7 @@ +ROOTTEST_ADD_TEST(write + MACRO writeGrowingPairVector.C+ + FIXTURES_SETUP root-io-emulatedGrow-write-fixture) + +ROOTTEST_ADD_TEST(read + MACRO readGrowingPairVector.C + FIXTURES_REQUIRED root-io-emulatedGrow-write-fixture) diff --git a/roottest/root/io/emulatedGrow/growingPairVector.h b/roottest/root/io/emulatedGrow/growingPairVector.h new file mode 100644 index 0000000000000..36011cbbe738d --- /dev/null +++ b/roottest/root/io/emulatedGrow/growingPairVector.h @@ -0,0 +1,46 @@ +#ifndef GROWINGPAIRVECTOR_H +#define GROWINGPAIRVECTOR_H + +#include +#include +#include + +// The number of entries and their sizes are chosen so that the collection grows +// on every entry, forcing the reader's buffer to reallocate several times. +const int kNEntries = 12; + +inline int NElements(int entry) +{ + return 8 * (entry + 1); +} + +// Alternate between a string that fits in the small-string-optimization buffer +// and one that does not, so both layouts get relocated. +inline std::string ElementString(int entry, int i) +{ + std::string s = std::to_string(entry) + "_" + std::to_string(i); + if (i % 3 == 0) + s += std::string(40, 'x'); + return s; +} + +inline double ElementValue(int entry, int i) +{ + return entry * 1000.0 + i; +} + +// A class of our own on purpose: read back without this dictionary, its +// vector> member goes through TEmulatedCollectionProxy. +class GrowingPairVector { +public: + std::vector> fData; + + void Fill(int entry) + { + fData.clear(); + for (int i = 0; i < NElements(entry); ++i) + fData.emplace_back(ElementString(entry, i), ElementValue(entry, i)); + } +}; + +#endif diff --git a/roottest/root/io/emulatedGrow/readGrowingPairVector.C b/roottest/root/io/emulatedGrow/readGrowingPairVector.C new file mode 100644 index 0000000000000..dc7d3abd539a1 --- /dev/null +++ b/roottest/root/io/emulatedGrow/readGrowingPairVector.C @@ -0,0 +1,70 @@ +// Reads back the file written by writeGrowingPairVector.C without loading its +// dictionary, so the vector> goes through +// TEmulatedCollectionProxy. +// +// growingPairVector.h is deliberately NOT included: if cling knew the class, +// the collection would get a real proxy and the emulated path -- the one this +// test is about -- would never run. The expectations below mirror the header +// on purpose; keep the two in sync. + +#include "TError.h" +#include "TFile.h" +#include "TTree.h" + +int readGrowingPairVector() +{ + const int nEntries = 12; + + auto file = TFile::Open("growingPairVector.root"); + if (!file || file->IsZombie()) { + Error("readGrowingPairVector", "could not open growingPairVector.root"); + return 1; + } + + TTree *tree = nullptr; + file->GetObject("tree", tree); + if (!tree) { + Error("readGrowingPairVector", "could not find the tree"); + return 1; + } + + if (tree->GetEntries() != nEntries) { + Error("readGrowingPairVector", "expected %d entries, found %lld", nEntries, tree->GetEntries()); + return 1; + } + + // The collection grows on every entry, so the emulated buffer has to + // reallocate repeatedly. Before the fix for #20882 this aborted with an + // invalid free: the relocated std::string kept pointing into the old buffer. + for (Long64_t entry = 0; entry < tree->GetEntries(); ++entry) + tree->GetEntry(entry); + + // Check the values too, so that silent corruption fails the test rather than + // only an outright crash. + Long64_t expectedCount = 0; + double expectedSum = 0.; + for (int entry = 0; entry < nEntries; ++entry) { + for (int i = 0; i < 8 * (entry + 1); ++i) { + ++expectedCount; + expectedSum += entry * 1000.0 + i; + } + } + + const Long64_t count = tree->Draw("obj.fData.second", "", "goff"); + if (count != expectedCount) { + Error("readGrowingPairVector", "expected %lld elements, read %lld", expectedCount, count); + return 1; + } + + double sum = 0.; + const double *values = tree->GetV1(); + for (Long64_t i = 0; i < count; ++i) + sum += values[i]; + + if (sum != expectedSum) { + Error("readGrowingPairVector", "expected the values to sum to %f, got %f", expectedSum, sum); + return 1; + } + + return 0; +} diff --git a/roottest/root/io/emulatedGrow/writeGrowingPairVector.C b/roottest/root/io/emulatedGrow/writeGrowingPairVector.C new file mode 100644 index 0000000000000..5ed7779e74337 --- /dev/null +++ b/roottest/root/io/emulatedGrow/writeGrowingPairVector.C @@ -0,0 +1,27 @@ +#include "growingPairVector.h" + +#include "TFile.h" +#include "TTree.h" + +// Writes a tree whose only branch holds a class with a growing +// vector>. Compiled with ACLiC, so the dictionary exists +// here; the reader deliberately runs without it. +int writeGrowingPairVector() +{ + TFile f("growingPairVector.root", "RECREATE"); + TTree tree("tree", "growing emulated collections"); + + GrowingPairVector obj; + GrowingPairVector *pobj = &obj; + // Unsplit, so the collection is read back through the collection proxy. + tree.Branch("obj", &pobj, 32000, 0); + + for (int entry = 0; entry < kNEntries; ++entry) { + obj.Fill(entry); + tree.Fill(); + } + + tree.Write(); + f.Close(); + return 0; +} From 5a71ed5663f51625af2e8cfd4c7656d37435103e Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 27 Jul 2026 05:39:43 +0200 Subject: [PATCH 2/4] [roottest] Enable io/newstl nolib test The nolib test reads the STL containers back without the dictionary library, exercising the emulated collection proxy. It was flagged WILLFAIL because it crashed ROOT (and, before that, silently failed to compile) and its reference file dated back to the CINT/Makefile era, so it never matched. Now that the underlying crash is fixed (see previous commit), regenerate the reference from the current, deterministic output and drop the WILLFAIL flag, turning nolib into a real regression test that guards against the crash reappearing. --- roottest/root/io/newstl/CMakeLists.txt | 2 - roottest/root/io/newstl/stlNoLibTest.ref | 1340 +++++++--------------- 2 files changed, 395 insertions(+), 947 deletions(-) diff --git a/roottest/root/io/newstl/CMakeLists.txt b/roottest/root/io/newstl/CMakeLists.txt index 9fb01172db3a5..407af4c79ea2a 100644 --- a/roottest/root/io/newstl/CMakeLists.txt +++ b/roottest/root/io/newstl/CMakeLists.txt @@ -30,12 +30,10 @@ ROOTTEST_ADD_TEST(run FIXTURES_REQUIRED root-io-newstl-test-fixture FIXTURES_SETUP root-io-newstl-run-fixture) -# failing tests, crashes ROOT, was disabled in Makefile ROOTTEST_ADD_TEST(nolib MACRO readNoLib.C MACROARG "\"vector.root\"" OUTREF stlNoLibTest.ref - WILLFAIL FIXTURES_REQUIRED root-io-newstl-run-fixture) ROOTTEST_COMPILE_MACRO(ComplexTest.h diff --git a/roottest/root/io/newstl/stlNoLibTest.ref b/roottest/root/io/newstl/stlNoLibTest.ref index 5b9e6081927b8..cedbf41d3ce2f 100644 --- a/roottest/root/io/newstl/stlNoLibTest.ref +++ b/roottest/root/io/newstl/stlNoLibTest.ref @@ -1,945 +1,395 @@ - -Processing readNoLib.C("vector.root")... -Warning in : no dictionary for class vectorHolder is available -Warning in : no dictionary for class pair is available -Warning in : no dictionary for class GHelper > > is available -Warning in : no dictionary for class GHelper > is available -Warning in : no dictionary for class GHelper is available -Warning in : no dictionary for class Helper is available -Warning in : no dictionary for class THelper is available -Warning in : no dictionary for class THelperDerived is available -Warning in : no dictionary for class HelperDerived is available -Warning in : no dictionary for class HelperClassDef is available -******************************************************** -* Row * Instance * split99.fScalar * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** - -*ERROR 30 : - Bad numerical expression : "split3.fScalar" -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Warning in : vectorHolder::Streamer not available, using TClass::ReadBuffer instead -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Warning in : vectorHolder::Streamer not available, using TClass::ReadBuffer instead -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -********************************************* -* Row * split3.fScalar * -********************************************* -* 0 * * -* 1 * * -* 2 * * -********************************************* -******************************************************** -* Row * Instance * split2.fScalar * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split1.fScalar * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split0.fScalar * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split_1.fScalar * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split_2.fScalar * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split99.fPairFlInt.first * -******************************************************** -* 0 * 0 * 2 * -* 1 * 0 * 1 * -* 1 * 1 * 3 * -* 2 * 0 * 0 * -* 2 * 1 * 2 * -* 2 * 2 * 4 * -******************************************************** -******************************************************** -* Row * Instance * split2.fPairFlInt.first * -******************************************************** -* 0 * 0 * 2 * -* 1 * 0 * 1 * -* 1 * 1 * 3 * -* 2 *Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 - 0 * 0 * -* 2 * 1 * 2 * -* 2 * 2 * 4 * -******************************************************** -******************************************************** -* Row * Instance * split1.fPairFlInt.first * -******************************************************** -* 0 * 0 * 2 * -* 1 * 0 * 1 * -* 1 * 1 * 3 * -* 2 * 0 * 0 * -* 2 * 1 * 2 * -* 2 * 2 * 4 * -******************************************************** -******************************************************** -* Row * Instance * split0.fPairFlInt.first * -******************************************************** -* 0 * 0 * 2 * -* 1 * 0 * 1 * -* 1 * 1 * 3 * -* 2 * 0 * 0 * -* 2 * 1 * 2 * -* 2 * 2 * 4 * -******************************************************** -******************************************************** -* Row * Instance * split_1.fPairFlInt.first * -******************************************************** -* 0 * 0 * 2 * -* 1 * 0 * 1 * -* 1 * 1 * 3 * -* 2 * 0 * 0 * -* 2 * 1 * 2 * -* 2 * 2 * 4 * -******************************************************** -******************************************************** -* Row * Instance * split_2.fPairFlInt.first * -******************************************************** -* 0 * 0 * 2 * -* 1 * 0 * 1 * -* 1 * 1 * 3 * -* 2 * 0 * 0 * -* 2 * 1 * 2 * -* 2 * 2 * 4 * -******************************************************** -******************************************************** -* Row * Instance * split99.fPairStrDb * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -******************************************************** -* Row * Instance * split2.fPairStrDb * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -********************************************* -* Row * split1.fPairStrDb * -********************************************* -* 0 * 0 * -* 1 * 0 * -* 2 * 0 * -********************************************* -******************************************************** -* Row * Instance * split0.fPairStrDb * -************************Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -******************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -******************************************************** -* Row * Instance * split_1.fPairStrDb * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -******************************************************** -* Row * Instance * split_2.fPairStrDb * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -*********************************** -* Row * Instance * split99.f * -*********************************** -* 0 * 0 * 0.6006006 * -* 0 * 1 * 0.6306306 * -* 1 * 0 * 1.2012012 * -* 1 * 1 * 1.2312312 * -* 1 * 2 * 1.2612612 * -* 1 * 3 * 1.2912912 * -* 2 * 0 * 1.8018018 * -* 2 * 1 * 1.8318318 * -* 2 * 2 * 1.8618618 * -* 2 * 3 * 1.8918918 * -* 2 * 4 * 1.9219219 * -* 2 * 5 * 1.9519519 * -*********************************** -*********************************** -* Row * Instance * split2.fO * -*********************************** -* 0 * 0 * 0.6006006 * -* 0 * 1 * 0.6306306 * -* 1 * 0 * 1.2012012 * -* 1 * 1 * 1.2312312 * -* 1 * 2 * 1.2612612 * -* 1 * 3 * 1.2912912 * -* 2 * 0 * 1.8018018 * -* 2 * 1 * 1.8318318 * -* 2 * 2 * 1.8618618 * -* 2 * 3 * 1.8918918 * -* 2 * 4 * 1.9219219 * -* 2 * 5 * 1.9519519 * -*********************************** -*********************************** -* Row * Instance * split1.fO * -*********************************** -* 0 * 0 * 0.6006006 * -* 0 * 1 * 0.6306306 * -* 1 * 0 * 1.2012012 * -* 1 * 1 * 1.2312312 * -* 1 * 2 * 1.2612612 * -* 1 * 3 * 1.2912912 * -* 2 * 0 * 1.8018018 * -* 2 * 1 * 1.8318318 * -* 2 * 2 * 1.8618618 * -* 2 * 3 * 1.8918918 * -* 2 * 4 * 1.9219219 * -* 2 * 5 * 1.9519519 * -*********************************** -*********************************** -* Row * Instance * split0.fO * -*********************************** -* 0 * 0 * 0.6006006 * -* 0 * 1 * 0.6306306 * -* 1 * 0 * 1.2012012 * -* 1 * 1 * 1.2312312 * -* 1 * 2 * 1.2612612 * -* 1 * 3 * 1.2912912 * -* 2 * 0 * 1.8018018 * -* 2 * 1 * 1.8318318 * -* 2 * 2 * 1.8618618 * -* 2 * 3 * 1.8918918 * -* 2 * 4 * 1.9219219 * -* 2 * 5 * 1.9519519 * -*********************************** -*********************************** -* Row * Instance * split_1.f * -*********************************** -* 0 * 0 * 0.6006006 * -* 0 * 1 * 0.6306306 * -* 1 * 0 * 1.2012012 * -* Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 - 1 * 1 * 1.2312312 * -* 1 * 2 * 1.2612612 * -* 1 * 3 * 1.2912912 * -* 2 * 0 * 1.8018018 * -* 2 * 1 * 1.8318318 * -* 2 * 2 * 1.8618618 * -* 2 * 3 * 1.8918918 * -* 2 * 4 * 1.9219219 * -* 2 * 5 * 1.9519519 * -*********************************** -*********************************** -* Row * Instance * split_2.f * -*********************************** -* 0 * 0 * 0.6006006 * -* 0 * 1 * 0.6306306 * -* 1 * 0 * 1.2012012 * -* 1 * 1 * 1.2312312 * -* 1 * 2 * 1.2612612 * -* 1 * 3 * 1.2912912 * -* 2 * 0 * 1.8018018 * -* 2 * 1 * 1.8318318 * -* 2 * 2 * 1.8618618 * -* 2 * 3 * 1.8918918 * -* 2 * 4 * 1.9219219 * -* 2 * 5 * 1.9519519 * -*********************************** -******************************************************** -* Row * Instance * split99.fPairStrDb.first * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -******************************************************** -* Row * Instance * split2.fPairStrDb.first * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -******************************************************** -* Row * Instance * split1.fPairStrDb.first * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -******************************************************** -* Row * Instance * split0.fPairStrDb.first * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -******************************************************** -* Row * Instance * split_1.fPairStrDb.first * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -******************************************************** -* Row * Instance * split_2.fPairStrDb.first * -******************************************************** -* 0 * 0 * 0 * -* 1 * 0 * 0 * -* 1 * 1 * Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too many bytes: 12 instead of 10 -Warning in : fNestedL::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedD read too many bytes: 12 instead of 10 -Warning in : fNestedD::Streamer() not in sync with data on file 4-01-03/vector.root, fix Streamer() -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class fNestedL read too few bytes: 14 instead of 36 -Error in : object of class fNestedD read too few bytes: 14 instead of 36 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 -Error in : object of class list read too few bytes: 6 instead of 18 -Error in : object of class fNestedL read too few bytes: 36 instead of 84 -Error in : object of class deque read too few bytes: 6 instead of 18 -Error in : object of class fNestedD read too few bytes: 36 instead of 84 - 0 * -* 2 * 0 * 0 * -* 2 * 1 * 0 * -* 2 * 2 * 0 * -******************************************************** -******************************************************** -* Row * Instance * split99.fTemplates.val.val.val * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split2.fTemplates.val.val.val * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split1.fTemplates.val.val.val * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split0.fTemplates.val.val.val * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split_1.fTemplates.val.val.val * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** -******************************************************** -* Row * Instance * split_2.fTemplates.val.val.val * -******************************************************** -* 0 * 0 * 10 * -* 1 * 0 * 20 * -* 1 * 1 * 21 * -* 2 * 0 * 30 * -* 2 * 1 * 31 * -* 2 * 2 * 32 * -******************************************************** +Warning in : no dictionary for class GHelper > > is available +Warning in : no dictionary for class GHelper > is available +Warning in : no dictionary for class GHelper is available +Warning in : no dictionary for class Helper is available +Warning in : no dictionary for class THelper is available +Warning in : no dictionary for class THelperDerived is available +Warning in : no dictionary for class HelperDerived is available +Warning in : no dictionary for class HelperClassDef is available +Warning in : no dictionary for class vectorHolder is available +Error in : Bad numerical expression : "split3.fScalar" +Warning in : vectorHolder::Streamer not available, using TClass::ReadBuffer instead +Warning in : vectorHolder::Streamer not available, using TClass::ReadBuffer instead +******************************************************** +* Row * Instance * split99.fScalar * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +********************************************* +* Row * split3.fScalar * +********************************************* +* 0 * * +* 1 * * +* 2 * * +********************************************* +******************************************************** +* Row * Instance * split2.fScalar * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split1.fScalar * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split0.fScalar * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split_1.fScalar * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split_2.fScalar * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split99.fPairFlInt.first * +******************************************************** +* 0 * 0 * 2 * +* 1 * 0 * 1 * +* 1 * 1 * 3 * +* 2 * 0 * 0 * +* 2 * 1 * 2 * +* 2 * 2 * 4 * +******************************************************** +******************************************************** +* Row * Instance * split2.fPairFlInt.first * +******************************************************** +* 0 * 0 * 2 * +* 1 * 0 * 1 * +* 1 * 1 * 3 * +* 2 * 0 * 0 * +* 2 * 1 * 2 * +* 2 * 2 * 4 * +******************************************************** +******************************************************** +* Row * Instance * split1.fPairFlInt.first * +******************************************************** +* 0 * 0 * 2 * +* 1 * 0 * 1 * +* 1 * 1 * 3 * +* 2 * 0 * 0 * +* 2 * 1 * 2 * +* 2 * 2 * 4 * +******************************************************** +******************************************************** +* Row * Instance * split0.fPairFlInt.first * +******************************************************** +* 0 * 0 * 2 * +* 1 * 0 * 1 * +* 1 * 1 * 3 * +* 2 * 0 * 0 * +* 2 * 1 * 2 * +* 2 * 2 * 4 * +******************************************************** +******************************************************** +* Row * Instance * split_1.fPairFlInt.first * +******************************************************** +* 0 * 0 * 2 * +* 1 * 0 * 1 * +* 1 * 1 * 3 * +* 2 * 0 * 0 * +* 2 * 1 * 2 * +* 2 * 2 * 4 * +******************************************************** +******************************************************** +* Row * Instance * split_2.fPairFlInt.first * +******************************************************** +* 0 * 0 * 2 * +* 1 * 0 * 1 * +* 1 * 1 * 3 * +* 2 * 0 * 0 * +* 2 * 1 * 2 * +* 2 * 2 * 4 * +******************************************************** +******************************************************** +* Row * Instance * split99.fPairStrDb * +******************************************************** +* 0 * 0 * 0 * +* 1 * 0 * 0 * +* 1 * 1 * * +* 2 * 0 * 0 * +* 2 * 1 * 0 * +* 2 * 2 * * +******************************************************** +******************************************************** +* Row * Instance * split2.fPairStrDb * +******************************************************** +* 0 * 0 * 0 * +* 1 * 0 * 0 * +* 1 * 1 * * +* 2 * 0 * 0 * +* 2 * 1 * 0 * +* 2 * 2 * * +******************************************************** +********************************************* +* Row * split1.fPairStrDb * +********************************************* +* 0 * 0 * +* 1 * 0 * +* 2 * 0 * +********************************************* +******************************************************** +* Row * Instance * split0.fPairStrDb * +******************************************************** +* 0 * 0 * 0 * +* 1 * 0 * 0 * +* 1 * 1 * * +* 2 * 0 * 0 * +* 2 * 1 * 0 * +* 2 * 2 * * +******************************************************** +******************************************************** +* Row * Instance * split_1.fPairStrDb * +******************************************************** +* 0 * 0 * 0 * +* 1 * 0 * 0 * +* 1 * 1 * * +* 2 * 0 * 0 * +* 2 * 1 * 0 * +* 2 * 2 * * +******************************************************** +******************************************************** +* Row * Instance * split_2.fPairStrDb * +******************************************************** +* 0 * 0 * 0 * +* 1 * 0 * 0 * +* 1 * 1 * * +* 2 * 0 * 0 * +* 2 * 1 * 0 * +* 2 * 2 * * +******************************************************** +*********************************** +* Row * Instance * split99.f * +*********************************** +* 0 * 0 * 0.6006006 * +* 0 * 1 * 0.6306306 * +* 1 * 0 * 1.2012012 * +* 1 * 1 * 1.2312312 * +* 1 * 2 * 1.2612612 * +* 1 * 3 * 1.2912912 * +* 2 * 0 * 1.8018018 * +* 2 * 1 * 1.8318318 * +* 2 * 2 * 1.8618618 * +* 2 * 3 * 1.8918918 * +* 2 * 4 * 1.9219219 * +* 2 * 5 * 1.9519519 * +*********************************** +*********************************** +* Row * Instance * split2.fO * +*********************************** +* 0 * 0 * 0.6006006 * +* 0 * 1 * 0.6306306 * +* 1 * 0 * 1.2012012 * +* 1 * 1 * 1.2312312 * +* 1 * 2 * 1.2612612 * +* 1 * 3 * 1.2912912 * +* 2 * 0 * 1.8018018 * +* 2 * 1 * 1.8318318 * +* 2 * 2 * 1.8618618 * +* 2 * 3 * 1.8918918 * +* 2 * 4 * 1.9219219 * +* 2 * 5 * 1.9519519 * +*********************************** +*********************************** +* Row * Instance * split1.fO * +*********************************** +* 0 * 0 * 0.6006006 * +* 0 * 1 * 0.6306306 * +* 1 * 0 * 1.2012012 * +* 1 * 1 * 1.2312312 * +* 1 * 2 * 1.2612612 * +* 1 * 3 * 1.2912912 * +* 2 * 0 * 1.8018018 * +* 2 * 1 * 1.8318318 * +* 2 * 2 * 1.8618618 * +* 2 * 3 * 1.8918918 * +* 2 * 4 * 1.9219219 * +* 2 * 5 * 1.9519519 * +*********************************** +*********************************** +* Row * Instance * split0.fO * +*********************************** +* 0 * 0 * 0.6006006 * +* 0 * 1 * 0.6306306 * +* 1 * 0 * 1.2012012 * +* 1 * 1 * 1.2312312 * +* 1 * 2 * 1.2612612 * +* 1 * 3 * 1.2912912 * +* 2 * 0 * 1.8018018 * +* 2 * 1 * 1.8318318 * +* 2 * 2 * 1.8618618 * +* 2 * 3 * 1.8918918 * +* 2 * 4 * 1.9219219 * +* 2 * 5 * 1.9519519 * +*********************************** +*********************************** +* Row * Instance * split_1.f * +*********************************** +* 0 * 0 * 0.6006006 * +* 0 * 1 * 0.6306306 * +* 1 * 0 * 1.2012012 * +* 1 * 1 * 1.2312312 * +* 1 * 2 * 1.2612612 * +* 1 * 3 * 1.2912912 * +* 2 * 0 * 1.8018018 * +* 2 * 1 * 1.8318318 * +* 2 * 2 * 1.8618618 * +* 2 * 3 * 1.8918918 * +* 2 * 4 * 1.9219219 * +* 2 * 5 * 1.9519519 * +*********************************** +*********************************** +* Row * Instance * split_2.f * +*********************************** +* 0 * 0 * 0.6006006 * +* 0 * 1 * 0.6306306 * +* 1 * 0 * 1.2012012 * +* 1 * 1 * 1.2312312 * +* 1 * 2 * 1.2612612 * +* 1 * 3 * 1.2912912 * +* 2 * 0 * 1.8018018 * +* 2 * 1 * 1.8318318 * +* 2 * 2 * 1.8618618 * +* 2 * 3 * 1.8918918 * +* 2 * 4 * 1.9219219 * +* 2 * 5 * 1.9519519 * +*********************************** +********************************************* +* Row * split99.fPairStrDb.first * +********************************************* +* 0 * aa * +* 1 * a * +* 2 * * +********************************************* +********************************************* +* Row * split2.fPairStrDb.first * +********************************************* +* 0 * aa * +* 1 * a * +* 2 * * +********************************************* +********************************************* +* Row * split1.fPairStrDb.first * +********************************************* +* 0 * aa * +* 1 * a * +* 2 * * +********************************************* +********************************************* +* Row * split0.fPairStrDb.first * +********************************************* +* 0 * aa * +* 1 * a * +* 2 * * +********************************************* +********************************************* +* Row * split_1.fPairStrDb.first * +********************************************* +* 0 * aa * +* 1 * a * +* 2 * * +********************************************* +********************************************* +* Row * split_2.fPairStrDb.first * +********************************************* +* 0 * aa * +* 1 * a * +* 2 * * +********************************************* +******************************************************** +* Row * Instance * split99.fTemplates.val.val.val * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split2.fTemplates.val.val.val * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split1.fTemplates.val.val.val * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split0.fTemplates.val.val.val * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split_1.fTemplates.val.val.val * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +******************************************************** +* Row * Instance * split_2.fTemplates.val.val.val * +******************************************************** +* 0 * 0 * 10 * +* 1 * 0 * 20 * +* 1 * 1 * 21 * +* 2 * 0 * 30 * +* 2 * 1 * 31 * +* 2 * 2 * 32 * +******************************************************** +(int) 0 From fb5d7ca52211904acc06c2cefe64b51b01c4b6c0 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Sun, 9 Aug 2026 10:00:15 +0000 Subject: [PATCH 3/4] [io] Fix the element addresses registered by TEmulatedCollectionProxy::Expand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the storage of an emulated collection is reallocated, Expand() tells TClass::Move() where each element went so that the object version repository stays in sync. Two things were wrong with the addresses it passed. The value loop walked the elements from the start of the buffer, i.e. from the key, while the New() loop right below it correctly starts at fValOffset. For a map-like proxy the values therefore got registered under the addresses of their keys. This is harmless for a sequential container, where fValOffset is 0. Both loops also ran one iteration too many: the live elements are [0, nCurr), so the last iteration handed Move() an address one past the end of the old, about-to-be-freed buffer. Harmless in practice, since MoveAddressInRepository() only uses the addresses as map keys and never dereferences them. 🤖 Done with the help of AI. --- io/io/src/TEmulatedCollectionProxy.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/io/io/src/TEmulatedCollectionProxy.cxx b/io/io/src/TEmulatedCollectionProxy.cxx index c42ef59da14d6..b676e16f79d57 100644 --- a/io/io/src/TEmulatedCollectionProxy.cxx +++ b/io/io/src/TEmulatedCollectionProxy.cxx @@ -434,7 +434,7 @@ void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left, Bool_t force) case kIsClass: if (oldstart && oldstart != fEnv->fStart) { Long_t offset = 0; - for( i=0; i<=nCurr; ++i, offset += fValDiff ) { + for (i = 0; i < nCurr; ++i, offset += fValDiff) { // For now 'Move' only register the change of location // so per se this is wrong since the object are copied via memcpy // rather than a copy (or move) constructor. @@ -466,8 +466,10 @@ void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left, Bool_t force) break; case kIsClass: if (oldstart && oldstart != fEnv->fStart) { - Long_t offset = 0; - for( i=0; i<=nCurr; ++i, offset += fValDiff ) { + // fValOffset locates the value inside the element, as it does + // for the New() loop below; for a map it is past the key. + Long_t offset = fValOffset; + for (i = 0; i < nCurr; ++i, offset += fValDiff) { // For now 'Move' only register the change of location // so per se this is wrong since the object are copied via memcpy // rather than a copy (or move) constructor. From 9aa7479e36c84c48b874b326f7a49dd1ac4ae4c7 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Sun, 9 Aug 2026 15:58:50 +0000 Subject: [PATCH 4/4] [io] Compute collection byte offsets in 64 bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The collection proxies derive byte offsets and buffer sizes from an element count and fValDiff, the distance between two consecutive elements. fValDiff is an int and the counts are UInt_t or int, so their product was computed in 32 bits and only widened afterwards, when it was assigned to a size_t or added to a pointer. The product therefore wraps well before the operands do: for the int * int cases in TGenCollectionStreamer it overflows at 2 GiB of payload, which a hundred million elements of thirty-odd bytes already reach. Note that `size_t len = fValDiff * nElements;` reads as if it were computed in 64 bits, but the multiplication has already truncated by then. Introduce TGenCollectionProxy::ElementOffset(), which multiplies in size_t, and use it wherever an element count is turned into a byte offset. The divisions by fValDiff are left alone: those widen correctly already. 🤖 Done with the help of AI. --- io/io/inc/TGenCollectionProxy.h | 8 +++++++ io/io/src/TEmulatedCollectionProxy.cxx | 26 ++++++++++++--------- io/io/src/TEmulatedMapProxy.cxx | 6 ++--- io/io/src/TGenCollectionProxy.cxx | 8 +++---- io/io/src/TGenCollectionStreamer.cxx | 32 +++++++++++++++++--------- 5 files changed, 51 insertions(+), 29 deletions(-) diff --git a/io/io/inc/TGenCollectionProxy.h b/io/io/inc/TGenCollectionProxy.h index 832d53e88de7f..162b88c33a031 100644 --- a/io/io/inc/TGenCollectionProxy.h +++ b/io/io/inc/TGenCollectionProxy.h @@ -318,6 +318,14 @@ class TGenCollectionProxy EnvironBase_t*fEnv; ///< Address of the currently proxied object int fValOffset; ///< Offset from key to value (in maps) int fValDiff; ///< Offset between two consecutive value_types (memory layout). + + /// Byte offset of the n-th element. fValDiff is an int and the element counts + /// are UInt_t, so a plain product would be computed in 32 bits and wrap once + /// the collection data grows past 4 GiB -- which is reached well within the + /// UInt_t element counts this interface supports whenever the elements are + /// bigger than one byte. + std::size_t ElementOffset(std::size_t n) const { return n * static_cast(fValDiff); } + Proxies_t fProxyList; ///< Stack of recursive proxies Proxies_t fProxyKept; ///< Optimization: Keep proxies once they were created Staged_t fStaged; ///< Optimization: Keep staged array once they were created diff --git a/io/io/src/TEmulatedCollectionProxy.cxx b/io/io/src/TEmulatedCollectionProxy.cxx index b676e16f79d57..883dab626fd3a 100644 --- a/io/io/src/TEmulatedCollectionProxy.cxx +++ b/io/io/src/TEmulatedCollectionProxy.cxx @@ -270,13 +270,13 @@ void TEmulatedCollectionProxy::Shrink(UInt_t nCurr, UInt_t left, Bool_t force ) // Shrink the container typedef std::string String_t; - char* addr = ((char*)fEnv->fStart) + fValDiff*left; + char *addr = ((char *)fEnv->fStart) + ElementOffset(left); size_t i; switch ( fSTL_type ) { case ROOT::kSTLmap: case ROOT::kSTLmultimap: - addr = ((char*)fEnv->fStart) + fValDiff*left; + addr = ((char *)fEnv->fStart) + ElementOffset(left); switch(fKey->fCase) { case kIsFundamental: // Only handle primitives this way case kIsEnum: @@ -319,7 +319,7 @@ void TEmulatedCollectionProxy::Shrink(UInt_t nCurr, UInt_t left, Bool_t force ) } break; } - addr = ((char*)fEnv->fStart)+fValOffset+fValDiff*left; + addr = ((char *)fEnv->fStart) + fValOffset + ElementOffset(left); // DO NOT break; just continue // General case for all values @@ -366,7 +366,7 @@ void TEmulatedCollectionProxy::Shrink(UInt_t nCurr, UInt_t left, Bool_t force ) } WithCont(fEnv->fObject, [&](auto *c, std::size_t alignmentElemSize) { assert(fValDiff % alignmentElemSize == 0); - c->resize(left * fValDiff / alignmentElemSize); + c->resize(ElementOffset(left) / alignmentElemSize); fEnv->fStart = left > 0 ? c->data() : nullptr; }); return; @@ -405,7 +405,7 @@ void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left, Bool_t force) // Only worth asking about the type if the buffer actually reallocates. bool willReallocate = false; WithCont(fEnv->fObject, [&](auto *c, std::size_t alignmentElemSize) { - willReallocate = (left * fValDiff / alignmentElemSize) > c->capacity(); + willReallocate = (ElementOffset(left) / alignmentElemSize) > c->capacity(); }); if (willReallocate && (needsRealMove(fVal) || needsRealMove(fKey))) { // Destroys the elements in place and resizes to 0, keeping the capacity; @@ -419,11 +419,11 @@ void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left, Bool_t force) void *oldstart = fEnv->fStart; WithCont(fEnv->fObject, [&](auto *c, std::size_t alignmentElemSize) { assert(fValDiff % alignmentElemSize == 0); - c->resize(left * fValDiff / alignmentElemSize); + c->resize(ElementOffset(left) / alignmentElemSize); fEnv->fStart = left > 0 ? c->data() : nullptr; }); - char* addr = ((char*)fEnv->fStart) + fValDiff*nCurr; + char *addr = ((char *)fEnv->fStart) + ElementOffset(nCurr); switch ( fSTL_type ) { case ROOT::kSTLmap: case ROOT::kSTLmultimap: @@ -455,7 +455,7 @@ void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left, Bool_t force) *(void**)addr = 0; break; } - addr = ((char*)fEnv->fStart)+fValOffset+fValDiff*nCurr; + addr = ((char *)fEnv->fStart) + fValOffset + ElementOffset(nCurr); // DO NOT break; just continue // General case for all values @@ -525,7 +525,7 @@ void* TEmulatedCollectionProxy::At(UInt_t idx) if ( idx >= (s/fValDiff) ) { return 0; } - return idx < (s / fValDiff) ? c->data() + idx * fValDiff : 0; + return idx < (s / fValDiff) ? c->data() + ElementOffset(idx) : 0; } Fatal("TEmulatedCollectionProxy","At> Logic error - no proxy object set."); return 0; @@ -583,7 +583,9 @@ void TEmulatedCollectionProxy::ReadItems(int nElements, TBuffer &b) } break; -#define DOLOOP(x) {int idx=0; while(idxfType) ); @@ -631,7 +633,9 @@ void TEmulatedCollectionProxy::WriteItems(int nElements, TBuffer &b) Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind); } break; -#define DOLOOP(x) {int idx=0; while(idxfType) ); case kBIT_ISSTRING: diff --git a/io/io/src/TEmulatedMapProxy.cxx b/io/io/src/TEmulatedMapProxy.cxx index f244a8aba6f05..d1ec2d546bd55 100644 --- a/io/io/src/TEmulatedMapProxy.cxx +++ b/io/io/src/TEmulatedMapProxy.cxx @@ -71,7 +71,7 @@ void* TEmulatedMapProxy::At(UInt_t idx) // Return the address of the value at index 'idx'. if ( fEnv && fEnv->fObject ) { PCont_t c = PCont_t(fEnv->fObject); - return (idx<(c->size() / fValDiff)) ? (c->data() + idx * fValDiff) : 0; + return (idx < (c->size() / fValDiff)) ? (c->data() + ElementOffset(idx)) : 0; } Fatal("TEmulatedMapProxy","At> Logic error - no proxy object set."); return 0; @@ -100,7 +100,7 @@ void TEmulatedMapProxy::ReadMap(UInt_t nElements, TBuffer &b) char* addr = 0; char* temp = (char*)At(0); for ( idx = 0; idx < nElements; ++idx ) { - addr = temp + idx*fValDiff; + addr = temp + ElementOffset(idx); for ( loop=0; loop<2; loop++) { addr += off[loop]; helper = (StreamHelper*)addr; @@ -161,7 +161,7 @@ void TEmulatedMapProxy::WriteMap(UInt_t nElements, TBuffer &b) char* addr = 0; char* temp = (char*)At(0); for (UInt_t loop, idx = 0; idx < nElements; ++idx ) { - addr = temp + idx*fValDiff; + addr = temp + ElementOffset(idx); for ( loop = 0; loop<2; ++loop ) { addr += off[loop]; i = (StreamHelper*)addr; diff --git a/io/io/src/TGenCollectionProxy.cxx b/io/io/src/TGenCollectionProxy.cxx index 9b240e02ad28d..eb974f5dd6e69 100644 --- a/io/io/src/TGenCollectionProxy.cxx +++ b/io/io/src/TGenCollectionProxy.cxx @@ -56,7 +56,7 @@ class TGenVectorProxy : public TGenCollectionProxy { return fEnv->fStart = fFirst.invoke(fEnv); default: if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv); - return ((char*)fEnv->fStart) + fValDiff*idx; + return ((char *)fEnv->fStart) + ElementOffset(idx); } } Fatal("TGenVectorProxy","At> Logic error - no proxy object set."); @@ -244,7 +244,7 @@ class TGenSetProxy : public TGenVectorProxy { { if ( fEnv && fEnv->fObject ) { if ( fEnv->fUseTemp ) { - return (((char*)fEnv->fTemp)+idx*fValDiff); + return (((char *)fEnv->fTemp) + ElementOffset(idx)); } switch( idx ) { case 0: @@ -1084,7 +1084,7 @@ void* TGenCollectionProxy::At(UInt_t idx) return fEnv->fStart = fFirst.invoke(fEnv); default: if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv); - return ((char*)fEnv->fStart) + fValDiff*idx; + return ((char *)fEnv->fStart) + ElementOffset(idx); } case ROOT::kSTLbitset: { switch (idx) { @@ -1112,7 +1112,7 @@ void* TGenCollectionProxy::At(UInt_t idx) case ROOT::kSTLmultimap: case ROOT::kSTLunorderedmultimap: if ( fEnv->fUseTemp ) { - return (((char*)fEnv->fTemp)+idx*fValDiff); + return (((char *)fEnv->fTemp) + ElementOffset(idx)); } // Intentional fall through. default: diff --git a/io/io/src/TGenCollectionStreamer.cxx b/io/io/src/TGenCollectionStreamer.cxx index 3dbddde5df4b3..b8918ec5de02a 100644 --- a/io/io/src/TGenCollectionStreamer.cxx +++ b/io/io/src/TGenCollectionStreamer.cxx @@ -213,7 +213,7 @@ void DispatchConvertArray(int writeType, TGenCollectionProxy::StreamHelper *read void TGenCollectionStreamer::ReadPrimitives(int nElements, TBuffer &b, const TClass *onFileClass) { // Primitive input streamer. - size_t len = fValDiff * nElements; + size_t len = ElementOffset(nElements); char buffer[8096]; Bool_t feed = false; void* memory = 0; @@ -367,7 +367,7 @@ void TGenCollectionStreamer::ReadObjects(int nElements, TBuffer &b, const TClass { // Object input streamer. Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion() <= 3; - size_t len = fValDiff * nElements; + size_t len = ElementOffset(nElements); StreamHelper* itm = 0; TClass* onFileValClass = (onFileClass ? onFileClass->GetCollectionProxy()->GetValueClass() : 0); @@ -376,7 +376,9 @@ void TGenCollectionStreamer::ReadObjects(int nElements, TBuffer &b, const TClass switch (fSTL_type) { // Simple case: contiguous memory. get address of first, then jump. case ROOT::kSTLvector: -#define DOLOOP(x) {int idx=0; while(idxfObject,fEnv->fSize); fEnv->fIdx = 0; @@ -432,7 +434,9 @@ void TGenCollectionStreamer::ReadObjects(int nElements, TBuffer &b, const TClass case ROOT::kSTLset: case ROOT::kSTLunorderedset: case ROOT::kSTLunorderedmultiset: { -#define DOLOOP(x) {int idx=0; while(idx(len); fEnv->fStart = itm = reinterpret_cast(buffer.get()); fConstruct(itm,nElements); @@ -473,7 +477,7 @@ void TGenCollectionStreamer::ReadPairFromMap(int nElements, TBuffer &b) // Input streamer to convert a map into another collection Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion() <= 3; - size_t len = fValDiff * nElements; + size_t len = ElementOffset(nElements); StreamHelper* itm = 0; TStreamerInfo *pinfo = (TStreamerInfo*)fVal->fType->GetStreamerInfo(); @@ -491,7 +495,9 @@ void TGenCollectionStreamer::ReadPairFromMap(int nElements, TBuffer &b) switch (fSTL_type) { // Simple case: contiguous memory. get address of first, then jump. case ROOT::kSTLvector: -#define DOLOOP(x) {int idx=0; while(idxfObject,fEnv->fSize); fEnv->fIdx = 0; @@ -541,7 +547,9 @@ void TGenCollectionStreamer::ReadPairFromMap(int nElements, TBuffer &b) case ROOT::kSTLset: case ROOT::kSTLunorderedset: case ROOT::kSTLunorderedmultiset: { -#define DOLOOP(x) {int idx=0; while(idx(len); fEnv->fStart = itm = reinterpret_cast(buffer.get()); fConstruct(itm,nElements); @@ -726,7 +734,7 @@ void TGenCollectionStreamer::ReadMap(int nElements, TBuffer &b, const TClass *on { // Map input streamer. Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion() <= 3; - size_t len = fValDiff * nElements; + size_t len = ElementOffset(nElements); Value *v; char buffer[8096], *addr, *temp; void* memory = 0; @@ -745,7 +753,7 @@ void TGenCollectionStreamer::ReadMap(int nElements, TBuffer &b, const TClass *on onFileValueKind[1] = ((TStreamerElement*)sourceInfo->GetElements()->At(1))->GetType(); } for (int loop, idx = 0; idx < nElements; ++idx) { - addr = temp + fValDiff * idx; + addr = temp + ElementOffset(idx); v = fKey; for (loop = 0; loop < 2; loop++) { i = (StreamHelper*)addr; @@ -891,7 +899,7 @@ void TGenCollectionStreamer::ReadMap(int nElements, TBuffer &b, const TClass *on void TGenCollectionStreamer::WritePrimitives(int nElements, TBuffer &b) { // Primitive output streamer. - size_t len = fValDiff * nElements; + size_t len = ElementOffset(nElements); char buffer[8192]; void* memory = 0; StreamHelper* itm = 0; @@ -969,7 +977,9 @@ void TGenCollectionStreamer::WriteObjects(int nElements, TBuffer &b) switch (fSTL_type) { // Simple case: contiguous memory. get address of first, then jump. case ROOT::kSTLvector: -#define DOLOOP(x) {int idx=0; while(idxfCase) { case kIsClass: