https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94345

            Bug ID: 94345
           Summary: std::chrono overflows due to c++14 non-compliance
           Product: gcc
           Version: 9.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jaapaap at freemail dot hu
  Target Milestone: ---

The code below does not compile, as the introduction of operator+(const years&
x, const year& y) into the overload set causes the instantiation of the
chrono::duration converting constructor that tries to convert picoseconds to
years. Since C++14 this constructor has been specified to not participate in
overload resolution unless the conversion (factor) does not cause overflow (The
overflow clause was absent in C++11). It seems GCC hasn't implemented the
overflow clause. Thanks and credits go to Howard Hinnant for identifying this
during my discussion with him here:
https://gitter.im/HowardHinnant/date?at=5cb306ffa0790b29c9b4d3fd and who
provided the standalone minimum test case below.

#include <chrono>

namespace date {

using days = std::chrono::duration
    <int, std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>;

using weeks = std::chrono::duration
    <int, std::ratio_multiply<std::ratio<7>, days::period>>;

using years = std::chrono::duration
    <int, std::ratio_multiply<std::ratio<146097, 400>, days::period>>;


class year
{
};

constexpr year  operator+(const years&  x, const year& y) noexcept;

}  // namespace date

void this_compiles()
{
   using TDuration = std::chrono::duration<int64_t, std::nano>;
   TDuration d1, d2;
   using namespace date;
   TDuration d3 = d1 + d2;
}

void this_does_not_compile()
{
   using TDuration = std::chrono::duration<__int128_t, std::pico>;
   TDuration d1, d2;
   using namespace date; // removing this line makes it compile

   TDuration d3 = d1 + d2; // does not compile
}

int
main()
{
}

Reply via email to