From 3c75605ff9bbb28fb35e9c70fa6f7ccadd63d520 Mon Sep 17 00:00:00 2001
From: scott snyder <snyder@bnl.gov>
Date: Fri, 21 Apr 2017 05:30:19 +0200
Subject: [PATCH] LArByteStream: Avoid undefined behavior.

Left-shift of a negative value is undefined.
Rewrite to use multiplication, which is well-defined
(and compiles to the same thing on x86_64).



Former-commit-id: 06fe30e13776eee1c272cfe60893ff3921d02b7a
---
 .../LArByteStream/LArRodBlockPhysicsV5.h          | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRodBlockPhysicsV5.h b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRodBlockPhysicsV5.h
index a1498194340..78a8ae4c7d2 100644
--- a/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRodBlockPhysicsV5.h
+++ b/LArCalorimeter/LArCnv/LArByteStream/LArByteStream/LArRodBlockPhysicsV5.h
@@ -366,7 +366,10 @@ return ( (ch&0x7) << 4) | ( (ch&0x38) >>2 ) | ((ch&0x40)>>6);
 inline void LArRodBlockPhysicsV5::setEx(double Ex){ 
 
         int32_t copy=(int32_t)Ex;
-	copy=(copy<<9);
+        // Write as multiplication, not as left shift, since left-shifting
+        // a negative number is undefined in C++.
+        // Compiles to the same code on x86_64.
+        copy *= (1<<9);
 	uint16_t* to_push = (uint16_t*)&copy;
         if ( m_TimeQualityBlock.size()>=6 ){
                 m_TimeQualityBlock[0]=to_push[0];
@@ -378,7 +381,10 @@ inline void LArRodBlockPhysicsV5::setEx(double Ex){
 inline void LArRodBlockPhysicsV5::setEy(double Ey){
 
         int32_t copy=(int32_t)Ey;
-	copy=(copy<<9);
+        // Write as multiplication, not as left shift, since left-shifting
+        // a negative number is undefined in C++.
+        // Compiles to the same code on x86_64.
+        copy *= (1<<9);
 	uint16_t* to_push = (uint16_t*)&copy;
         if ( m_TimeQualityBlock.size()>=6 ){
                 m_TimeQualityBlock[2]=to_push[0];
@@ -390,7 +396,10 @@ inline void LArRodBlockPhysicsV5::setEy(double Ey){
 inline void LArRodBlockPhysicsV5::setEz(double Ez){
 
         int32_t copy=(int32_t)Ez;
-	copy=(copy<<9);
+        // Write as multiplication, not as left shift, since left-shifting
+        // a negative number is undefined in C++.
+        // Compiles to the same code on x86_64.
+        copy *= (1<<9);
 	uint16_t* to_push = (uint16_t*)&copy;
         if ( m_TimeQualityBlock.size()>=6 ){
                 m_TimeQualityBlock[4]=to_push[0];
-- 
GitLab