From 2156115db5b95646f922dd3fea3eaa0aefee2a2c Mon Sep 17 00:00:00 2001
From: scott snyder <sss@karma>
Date: Fri, 13 Nov 2020 22:18:11 -0500
Subject: [PATCH] xAODRootAccess: Don't crash opening a schema-evolved file.

Don't crash opening a file that uses some kinds of automatic schema evolution.
If the type of a member changes from one class to another
(for example, from std::vector<double> to std::vector<float>),
then GetExpectedType will give us the on-disk class.
To get the class we use in memory, we need to use GetCurrentClass.
---
 Control/xAODRootAccess/Root/TAuxStore.cxx | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Control/xAODRootAccess/Root/TAuxStore.cxx b/Control/xAODRootAccess/Root/TAuxStore.cxx
index c28951eec91..87e8a6115a7 100644
--- a/Control/xAODRootAccess/Root/TAuxStore.cxx
+++ b/Control/xAODRootAccess/Root/TAuxStore.cxx
@@ -13,6 +13,9 @@
 #include <TClass.h>
 #include <TROOT.h>
 #include <TVirtualCollectionProxy.h>
+#include <TBranchElement.h>
+#include <TStreamerInfo.h>
+#include <TStreamerElement.h>
 
 // EDM include(s):
 #include "AthContainers/AuxTypeRegistry.h"
@@ -1469,6 +1472,19 @@ namespace xAOD {
                     br->GetName() );
       }
 
+      // Check for schema evolution:
+      // If a branch has automatic schema evolution from one class to another,
+      // then what we get from GetExpectedType will be the on-disk class.
+      // What we have in memory is given by GetCurrentClass.
+      if (expectedClass) {
+        if (TBranchElement* bre = dynamic_cast<TBranchElement*> (br)) {
+          TClass* newClass = bre->GetCurrentClass();
+          if (newClass && newClass != expectedClass) {
+            expectedClass = newClass;
+          }
+        }
+      }
+
       // If this is a primitive variable, and we're still not sure whether this
       // is a store for an object or a container, the answer is given...
       if( ( ! expectedClass ) &&
-- 
GitLab