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

            Bug ID: 85821
           Summary: Chrono literal operators do not follow the standard
                    declarataions
           Product: gcc
           Version: 8.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: andreas.molzer at gmx dot de
  Target Milestone: ---

The literal operators provided by std::literals::chrono_literals are missing
their overloads for unsigned long long arguments.  They instead provide a
declaration for long double and a non-standard declaration with template
argument list.  This silently breaks valid code:

#include <chrono>
int main() {
    using namespace std::chrono_literals;
    auto time = operator""s(1ull);
}

Name resolution will only find the single matching overload and convert the
argument to long double.  This will result in a duration with unspecified
representation, in libstdc++ case a long double.  The standard would instead
require the result to be std::chrono::seconds with representation of an
unspecified integral type with a minimum number of bits. 

This can have various additional effects, including decltype(time)::max()
returning an invalid result, so that the normally perfectly valid

    std::chrono::seconds::rep max = decltype(time)::max()

will result in undefined behaviour due to the long double maximum value not
fitting inside the unsigned long long.

The following code should be rejected because overload resolution should not be
able to determine a best match:

#include <chrono>
int main() {
    using namespace std::chrono_literals;
    auto time = operator""s(0);  // int, no priority for conversion to ull or
ld
}

Reply via email to