From 30f31902fc1a7c5df841eb65a2b8e8fd9d2e7e90 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Thu, 29 Oct 2020 17:27:57 +0100 Subject: [PATCH 1/6] In TStreamerInfo::GenerateInfoForPair use a non-zero size enums. This fix #6726 As reported by CMSSW tests (for example: cms-sw/cmsdist#6314 (comment)) where the data appear odd/corrupted, there is an issue in TStreamerInfo::GenerateInfoForPair (which is almost always used for std::pair in the tip of v6.22 and master). The problem is when calculating the offset of the second data member, TStreamerInfo::GenerateInfoForPair uses (unwittingly, of course :) ), the value zero for the size of the enums. --- io/io/src/TStreamerInfo.cxx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/io/io/src/TStreamerInfo.cxx b/io/io/src/TStreamerInfo.cxx index 32968dfe6bd28..af5651693d1e5 100644 --- a/io/io/src/TStreamerInfo.cxx +++ b/io/io/src/TStreamerInfo.cxx @@ -5589,15 +5589,18 @@ static TStreamerElement* R__CreateEmulatedElement(const char *dmName, const std: } TClass *clm = TClass::GetClass(dmType); if (!clm) { - if (TEnum::GetEnum(dmType, TEnum::kNone)) { - Int_t dtype = kInt_t; - return new TStreamerBasicType(dmName,dmTitle,offset,dtype,dmFull.c_str()); + auto enumdesc = TEnum::GetEnum(dmType, TEnum::kNone); + if (enumdesc) { + auto dtype = enumdesc->GetUnderlyingType(); + auto el = new TStreamerBasicType(dmName, dmTitle, offset, dtype, dmFull.c_str()); + auto datatype = TDataType::GetDataType(dtype); + if (datatype) + el->SetSize(datatype->Size()); + else + el->SetSize(sizeof(int)); // Default size of enums. + return el; } return nullptr; - // either we have an Emulated enum or a really unknown class! - // let's just claim its an enum :( - //Int_t dtype = kInt_t; - //return new TStreamerBasicType(dmName,dmTitle,offset,dtype,dmFull.c_str()); } // a pointer to a class if ( dmIsPtr ) { From 22aae937654a0311cabf4c97f9aba1e54e2bb966 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Thu, 29 Oct 2020 17:57:34 -0500 Subject: [PATCH 2/6] TDataType::GetDataType avoid out-of-bound reads. Search for 'kNumDataTypes'/unknown type should return nullptr not a random. --- core/meta/src/TDataType.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/meta/src/TDataType.cxx b/core/meta/src/TDataType.cxx index 01a88b3c9b763..e638f488f2d41 100644 --- a/core/meta/src/TDataType.cxx +++ b/core/meta/src/TDataType.cxx @@ -439,6 +439,6 @@ void TDataType::AddBuiltins(TCollection* types) TDataType* TDataType::GetDataType(EDataType type) { - if (type == kOther_t) return 0; + if (type == kOther_t || type >= kNumDataTypes) return 0; return fgBuiltins[(int)type]; } From a94d94aa342178de04b99034a27d182ca35d7462 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Thu, 29 Oct 2020 20:04:47 -0500 Subject: [PATCH 3/6] Record in the Enum underlying type in the rootpcm. Fix #6725 --- core/dictgen/src/BaseSelectionRule.cxx | 1 - core/meta/inc/TEnum.h | 3 ++- core/meta/src/TEnum.cxx | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/dictgen/src/BaseSelectionRule.cxx b/core/dictgen/src/BaseSelectionRule.cxx index 170ca763481a1..319c7202bece0 100644 --- a/core/dictgen/src/BaseSelectionRule.cxx +++ b/core/dictgen/src/BaseSelectionRule.cxx @@ -203,7 +203,6 @@ BaseSelectionRule::EMatchType BaseSelectionRule::Match(const clang::NamedDecl *d * isLinkdef - if the selection rules were generating from a linkdef.h file */ - const std::string& name_value = fName; const std::string& pattern_value = fPattern; diff --git a/core/meta/inc/TEnum.h b/core/meta/inc/TEnum.h index 01ef4059a07cd..d60660e1b8117 100644 --- a/core/meta/inc/TEnum.h +++ b/core/meta/inc/TEnum.h @@ -37,6 +37,7 @@ class TEnum : public TDictionary { ClassInfo_t *fInfo; //!interpreter information, owned by TEnum TClass *fClass; //!owning class std::string fQualName; // fully qualified type name + EDataType fUnderlyingType;// Type (size) used to store the enum in memory enum EBits { kBitIsScopedEnum = BIT(14) ///< The enum is an enum class. @@ -50,7 +51,7 @@ class TEnum : public TDictionary { kALoadAndInterpLookup = 3 }; - TEnum(): fInfo(nullptr), fClass(nullptr) {} + TEnum(): fInfo(nullptr), fClass(nullptr), fUnderlyingType(kInt_t) {} TEnum(const char *name, DeclId_t declid, TClass *cls); virtual ~TEnum(); diff --git a/core/meta/src/TEnum.cxx b/core/meta/src/TEnum.cxx index b1d856a432daf..ca785f6efbe69 100644 --- a/core/meta/src/TEnum.cxx +++ b/core/meta/src/TEnum.cxx @@ -36,7 +36,7 @@ ClassImp(TEnum); /// in TROOT::GetListOfGlobals). TEnum::TEnum(const char *name, DeclId_t declid, TClass *cls) - : fInfo(nullptr), fClass(cls) + : fInfo(nullptr), fClass(cls), fUnderlyingType(kInt_t) { SetName(name); if (cls) { @@ -106,9 +106,7 @@ Long_t TEnum::Property() const EDataType TEnum::GetUnderlyingType() const { - if (fInfo) - return gInterpreter->ClassInfo_GetUnderlyingType(fInfo); - return kNumDataTypes; + return fUnderlyingType; } //////////////////////////////////////////////////////////////////////////////// @@ -134,8 +132,10 @@ void TEnum::Update(DeclId_t id) fInfo = gInterpreter->ClassInfo_Factory(id); - if (fInfo) + if (fInfo) { SetBit(kBitIsScopedEnum, gInterpreter->ClassInfo_IsScopedEnum(fInfo)); + fUnderlyingType = gInterpreter->ClassInfo_GetUnderlyingType(fInfo); + } } //////////////////////////////////////////////////////////////////////////////// From 804ab49454e27df175dca523d86ef57d16e8fa06 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Fri, 30 Oct 2020 11:37:20 -0500 Subject: [PATCH 4/6] Skip unnecessary work in TClass::GetClass --- core/meta/src/TClass.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx index 63b46eefab6fa..32ad23f9639a8 100644 --- a/core/meta/src/TClass.cxx +++ b/core/meta/src/TClass.cxx @@ -3141,6 +3141,8 @@ TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent) // to get the part to add or drop the default arguments as requested by the user) std::string alternative; gInterpreter->GetInterpreterTypeName(normalizedName.c_str(), alternative, kTRUE); + if (alternative.empty()) + return nullptr; const char *altname = alternative.c_str(); if (strncmp(altname, "std::", 5) == 0) { // For namespace (for example std::__1), GetInterpreterTypeName does From 7347360f3df34866d043cef68cb34a849af460f6 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Fri, 30 Oct 2020 11:41:57 -0500 Subject: [PATCH 5/6] TEnum: initilize member at declaration point. --- core/meta/inc/TEnum.h | 12 ++++++------ core/meta/src/TEnum.cxx | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/meta/inc/TEnum.h b/core/meta/inc/TEnum.h index d60660e1b8117..12fa3842be43b 100644 --- a/core/meta/inc/TEnum.h +++ b/core/meta/inc/TEnum.h @@ -33,11 +33,11 @@ class TEnumConstant; class TEnum : public TDictionary { private: - THashList fConstantList; //list of constants the enum type - ClassInfo_t *fInfo; //!interpreter information, owned by TEnum - TClass *fClass; //!owning class - std::string fQualName; // fully qualified type name - EDataType fUnderlyingType;// Type (size) used to store the enum in memory + THashList fConstantList; // List of constants the enum type + ClassInfo_t *fInfo = nullptr; //!Interpreter information, owned by TEnum + TClass *fClass = nullptr; //!Owning class + std::string fQualName; // Fully qualified type name + EDataType fUnderlyingType = kInt_t; // Type (size) used to store the enum in memory enum EBits { kBitIsScopedEnum = BIT(14) ///< The enum is an enum class. @@ -51,7 +51,7 @@ class TEnum : public TDictionary { kALoadAndInterpLookup = 3 }; - TEnum(): fInfo(nullptr), fClass(nullptr), fUnderlyingType(kInt_t) {} + TEnum() = default; TEnum(const char *name, DeclId_t declid, TClass *cls); virtual ~TEnum(); diff --git a/core/meta/src/TEnum.cxx b/core/meta/src/TEnum.cxx index ca785f6efbe69..b36eff8303c3e 100644 --- a/core/meta/src/TEnum.cxx +++ b/core/meta/src/TEnum.cxx @@ -36,7 +36,7 @@ ClassImp(TEnum); /// in TROOT::GetListOfGlobals). TEnum::TEnum(const char *name, DeclId_t declid, TClass *cls) - : fInfo(nullptr), fClass(cls), fUnderlyingType(kInt_t) + : fClass(cls) { SetName(name); if (cls) { From a22485e62e603d01b8726f6107635ae5cdb51bef Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Fri, 30 Oct 2020 11:45:13 -0500 Subject: [PATCH 6/6] TEnum: inline trivial accessor. --- core/meta/inc/TEnum.h | 8 +++++++- core/meta/src/TEnum.cxx | 11 ----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/core/meta/inc/TEnum.h b/core/meta/inc/TEnum.h index 12fa3842be43b..db8058bed0a20 100644 --- a/core/meta/inc/TEnum.h +++ b/core/meta/inc/TEnum.h @@ -60,7 +60,13 @@ class TEnum : public TDictionary { const TSeqCollection *GetConstants() const { return &fConstantList; } const TEnumConstant *GetConstant(const char *name) const { return (TEnumConstant *)fConstantList.FindObject(name); } DeclId_t GetDeclId() const; - EDataType GetUnderlyingType() const; + + /// Get the unterlying integer type of the enum: + /// enum E { kOne }; // ==> int + /// enum F: long; // ==> long + /// Returns kNumDataTypes if the enum is unknown / invalid. + EDataType GetUnderlyingType() const { return fUnderlyingType; }; + Bool_t IsValid(); Long_t Property() const; void SetClass(TClass *cl) { fClass = cl; } diff --git a/core/meta/src/TEnum.cxx b/core/meta/src/TEnum.cxx index b36eff8303c3e..25a588e931c61 100644 --- a/core/meta/src/TEnum.cxx +++ b/core/meta/src/TEnum.cxx @@ -98,17 +98,6 @@ Long_t TEnum::Property() const return kIsEnum | (TestBit(kBitIsScopedEnum) ? kIsScopedEnum : 0); } -//////////////////////////////////////////////////////////////////////////////// -/// Get the unterlying integer type of the enum: -/// enum E { kOne }; // ==> int -/// enum F: long; // ==> long -/// Returns kNumDataTypes if the enum is unknown / invalid. - -EDataType TEnum::GetUnderlyingType() const -{ - return fUnderlyingType; -} - //////////////////////////////////////////////////////////////////////////////// TDictionary::DeclId_t TEnum::GetDeclId() const