diff --git a/roofit/roofitcore/test/testNaNPacker.cxx b/roofit/roofitcore/test/testNaNPacker.cxx index c1f307ab60277..0d26663cafdb7 100644 --- a/roofit/roofitcore/test/testNaNPacker.cxx +++ b/roofit/roofitcore/test/testNaNPacker.cxx @@ -138,6 +138,59 @@ TEST(RooNaNPacker, PackedNaNPreservedAfterArithmetic) EXPECT_TRUE(rnp2.isNaNWithPayload()); // nothing can harm the PackedNaN EXPECT_EQ(rnp.getPayload(), rnp2.getPayload()); + + // multiply packed NaN by 0 + rnp2._payload = 0. * rnp.getNaNWithPayload(); + EXPECT_TRUE(rnp2.isNaNWithPayload()); + // PackedNaN pays no mind + EXPECT_EQ(rnp.getPayload(), rnp2.getPayload()); + + // the following tests have compiler dependent behavior + // (note that this behavior was tested for msvc as well, even though this + // whole test is currently disabled in msvc) +#if defined(__clang__) || defined(_MSC_VER) + // add packed NaN to regular NaN + rnp2._payload = std::numeric_limits::quiet_NaN() + rnp.getNaNWithPayload(); + // first NaN wins, though! now the payload is gone + EXPECT_FALSE(rnp2.isNaNWithPayload()); + // a quiet NaN has a "payload" of zero + EXPECT_EQ(0, rnp2.getPayload()); + + // ... other way around + rnp2._payload = rnp.getNaNWithPayload() + std::numeric_limits::quiet_NaN(); + EXPECT_TRUE(rnp2.isNaNWithPayload()); + // if it comes first, the PackedNaN does survive + EXPECT_EQ(rnp.getPayload(), rnp2.getPayload()); + + // multiply regular NaN with packed NaN + rnp2._payload = rnp.getNaNWithPayload() * std::numeric_limits::quiet_NaN(); + EXPECT_TRUE(rnp2.isNaNWithPayload()); + // if it comes first, the PackedNaN does survive + EXPECT_EQ(rnp.getPayload(), rnp2.getPayload()); + + // ... other way around + rnp2._payload = std::numeric_limits::quiet_NaN() * rnp.getNaNWithPayload(); + // same as with addition: the first NaN wins + EXPECT_FALSE(rnp2.isNaNWithPayload()); + // a quiet NaN has a "payload" of zero + EXPECT_EQ(0, rnp2.getPayload()); +#endif // defined(__clang__) || defined(_MSC_VER) +#if defined(__GNUC__) && !defined(__clang__) + // on gcc, a different NaN is preserved than in clang and msvc! + + // add packed NaN to regular NaN + rnp2._payload = rnp.getNaNWithPayload() + std::numeric_limits::quiet_NaN(); + // on gcc, the second NaN wins! now the payload is gone + EXPECT_FALSE(rnp2.isNaNWithPayload()); + // a quiet NaN has a "payload" of zero + EXPECT_EQ(0, rnp2.getPayload()); + + // ... other way around + rnp2._payload = std::numeric_limits::quiet_NaN() + rnp.getNaNWithPayload(); + EXPECT_TRUE(rnp2.isNaNWithPayload()); + // if it comes second, the PackedNaN does survive + EXPECT_EQ(rnp.getPayload(), rnp2.getPayload()); +#endif // __GNUC__ } #endif // !defined(_MSC_VER) || defined(R__ENABLE_BROKEN_WIN_TESTS)