[Bug libstdc++/114260] std::formatter> formats as the previous day

2024-03-07 Thread howard.hinnant at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114260

--- Comment #2 from Howard Hinnant  ---
This:

2024-03-05 00:00:00
2024-03-04 23:59:33

looks like correct output to me.

sys_time and utc_time map to the same civil calendar date/time (except during a
leap second).  That is 2024-03-05 00:00:00 sys_time, converted to utc_time,
also should print out as 2024-03-05 00:00:00.

The only difference between sys_time and utc_time is that utc_time counts the
leap seconds since 1970 (27 at this point).  This means if you look at the
difference in .time_since_epoch(), utc_time will be 27 seconds longer, even
though it prints out as the same date and time.

Consequently, 2024-03-05 00:00:00 in utc_time is *not* a multiple of 86400s,
but rather 27s greater than a multiple of 86400s.  And all round(udays)
does is round the .time_since_epoch() to the nearest multiple of 86400s.  Which
in utc_time is 27s earlier, or 2024-03-04 23:59:33.

So in summary, if you make a change, and *don't* get this output, then you've
introduced a bug.

[Bug libstdc++/114244] Need to use round when parsing fractional seconds

2024-03-06 Thread howard.hinnant at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114244

--- Comment #4 from Howard Hinnant  ---
Not positive (because I don't know your code that well), but I think:

  __s = round<_Duration>(__fs);

will do it.

[Bug libstdc++/114244] New: Need to use round when parsing fractional seconds

2024-03-05 Thread howard.hinnant at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114244

Bug ID: 114244
   Summary: Need to use round when parsing fractional seconds
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: howard.hinnant at gmail dot com
  Target Milestone: ---

I'm not sure if this is a bug or just QOI.  But consider:

#include 
#include 
#include 


using time_point_t = std::chrono::sys_time;

time_point_t decrypt(std::string s) {
time_point_t tp;
std::istringstream in(s);
in >> parse("%Y%m%d-%T", tp);
return tp;
}

int main() {
std::cout << decrypt("20240304-13:00:00.002");
}

I expect the output to be:

2024-03-04 13:00:00.002

but it is:

2024-03-04 13:00:00.001

I believe the issue is the use of duration_cast or
time_point_cast somewhere under the parse (not sure exactly
where).  Since 0.002 is not exactly representable in floating point, we're
getting a truncate towards zero because this parses as just barely under 0.002.

I highly recommend the use of round when converting floating point
based durations and time_points to integral based.

[Bug libstdc++/114240] sys_days not being parsed with only a date in the stream

2024-03-05 Thread howard.hinnant at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114240

--- Comment #2 from Howard Hinnant  ---
In my date lib I just presumed 00:00:00 time of day when parsing time_points,
unless the parse produced another time of day.  Though I must admit that this
didn't come through in the spec.  So there is a little grey area here.

We're going to hit the same issue for other timepoints as well:  local_time,
utc_time, etc.

[Bug libstdc++/114240] New: sys_days not being parsed with only a date in the stream

2024-03-05 Thread howard.hinnant at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114240

Bug ID: 114240
   Summary: sys_days not being parsed with only a date in the
stream
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: howard.hinnant at gmail dot com
  Target Milestone: ---

#include 
#include 
#include 

int main(int argc, char**argv){

std::istringstream ssStart{"2024-01-01"};
std::istringstream ssEnd("2024-02-01");
ssStart.exceptions(std::ios::failbit);

std::chrono::sys_days tStart, tEnd;
ssStart >> std::chrono::parse("%Y-%m-%d ", tStart);
ssEnd >> std::chrono::parse("%Y-%m-%d ", tEnd);

auto tDays = tEnd-tStart;
std::cout << ssStart.str() << "," << ssEnd.str() << "," << tDays.count() <<
std::endl;
}

Expected output:

2024-01-01,2024-02-01,31

Actual output:

terminate called after throwing an instance of 'std::__ios_failure'
  what():  basic_ios::clear: iostream error

I expected this function: http://eel.is/c++draft/time.clock.system.nonmembers#6
to successfully parse the days-precision time_point because there is sufficient
information in the stream to form a valid date.

Demo: https://wandbox.org/permlink/FrtMteIddnb4ogpZ

[Bug libstdc++/78714] std::get_time / std::time_get::get does not accept full month name in %b

2020-01-26 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78714

Howard Hinnant  changed:

   What|Removed |Added

 CC||howard.hinnant at gmail dot com

--- Comment #1 from Howard Hinnant  ---
Here is a hopefully helpful algorithm for scanning a list of "keywords" for a
match:

https://github.com/HowardHinnant/date/blob/master/include/date/date.h#L4695-L4797

The keywords can be prefixes of one another, and the scan will match the
longest possible keyword.  The scan is case-insensitive.

Here is how it can be used:

https://github.com/HowardHinnant/date/blob/master/include/date/date.h#L4695-L4797

Here is how this bug is impacting real-world code, and estimates on how the
impact will increase with C++20:

https://github.com/HowardHinnant/date/wiki/FAQ#week_day_parse_bug
https://github.com/HowardHinnant/date/issues/539

[Bug libstdc++/71367] std::time_get does not implement 'r' or 'p'

2019-06-10 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71367

--- Comment #2 from Howard Hinnant  ---
Just so this point doesn't go unnoticed, parsing should be case-insensitive.

[Bug libstdc++/81468] New: is_constructible gives the wrong answer for time_point construction

2017-07-17 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81468

Bug ID: 81468
   Summary: is_constructible gives the wrong answer for time_point
construction
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: howard.hinnant at gmail dot com
  Target Milestone: ---

This should compile, but does not:

#include 
#include 

template 
using sys_time = std::chrono::time_point<std::chrono::system_clock,
Duration>;

int
main()
{
using namespace std;
using namespace std::chrono;
static_assert(!is_constructible<sys_time,
sys_time>{}, "");
//sys_time s{sys_time{123ms}};
}

[Bug c++/67631] brace initialization bug

2016-11-18 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67631

--- Comment #10 from Howard Hinnant  ---
Thanks much Jason!

[Bug c++/67631] brace initialization bug

2016-11-14 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67631

--- Comment #6 from Howard Hinnant  ---
Dropping the `explicit` specifier for the operator is an "over my dead body",
sorry.  That would be horrible.  The next best workaround is to "respell" the
explicit int operator() as `as_int() const`.  But then everyone has to remember
library-specific API for the operation instead of Uniform Initialization
Syntax.

[Bug c++/67631] brace initialization bug

2016-11-14 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67631

--- Comment #4 from Howard Hinnant  ---
This bug needs some attention because Howard Hinnant's date library is making
it common for people to hit this bug.

The date library:

https://github.com/HowardHinnant/date

This library is sufficiently popular and successful that it has been proposed
to the C++ committee for C++20.

Here is a short HelloWorld demonstrating the problem:

#include "date.h"
#include 

int
main()
{
using namespace date;
using namespace std::chrono;
year_month_day ymd = floor(system_clock::now());
auto y = int{ymd.year()};
std::cout << y << '\n';
}

You can try this out without installing the library at:

http://melpon.org/wandbox/permlink/PodYB3AwdYNFKbMv

Tip of trunk gcc gives:

prog.cc: In function 'int main()':
prog.cc:10:28: error: cannot convert 'date::year' to 'int' in initialization
 auto y = int{ymd.year()};
^

clang prints out the current year (UTC).

Changing the offending line to:

auto y = int(ymd.year());

is a workaround.  But people really like the Uniform Initialization Syntax
(using braces).

[Bug libstdc++/55917] Impossible to find/debug unhandled exceptions in an std::thread

2016-06-20 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55917

--- Comment #15 from Howard Hinnant  ---
To help clarify my proposal, here is a patch:

diff --git a/libstdc++-v3/src/c++11/thread.cc
b/libstdc++-v3/src/c++11/thread.cc
index 906cafa..cfca178 100644
--- a/libstdc++-v3/src/c++11/thread.cc
+++ b/libstdc++-v3/src/c++11/thread.cc
@@ -79,19 +79,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
   thread::__shared_base_type __local;
   __local.swap(__t->_M_this_ptr);

-  __try
-   {
- __t->_M_run();
-   }
-  __catch(const __cxxabiv1::__forced_unwind&)
-   {
- __throw_exception_again;
-   }
-  __catch(...)
-   {
- std::terminate();
-   }
-
+   __t->_M_run();
   return nullptr;
 }
   }

My colleague Miguel Portilla has tested this patch with the following code:

#include 
#include 

void a(int i);
void b(int i);
void c(int i);

int
main()
{
auto t = std::thread{a, 3};
t.join();
}

void
a(int i)
{
b(i-1);
}

void
b(int i)
{
c(i-1);
}

void
c(int i)
{
throw std::runtime_error("A good message");
}

And the stack dump looks like:

Thread 2 (Thread 0x7f090b47c740 (LWP 1865)):
#0  0x7f090b0688ed in pthread_join (threadid=139676803389184,
thread_return=0x0) at pthread_join.c:90
#1  0x7f090ad9c767 in __gthread_join (__value_ptr=0x0,
__threadid=)
at
/home/mickey/gcc-5.4.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:668
#2  std::thread::join (this=0x7ffd1dae6430) at
../../../../../libstdc++-v3/src/c++11/thread.cc:96
#3  0x00400f39 in main ()

Thread 1 (Thread 0x7f090a3fd700 (LWP 1866)):
#0  0x7f090a433267 in __GI_raise (sig=sig@entry=6) at
../sysdeps/unix/sysv/linux/raise.c:55
#1  0x7f090a434eca in __GI_abort () at abort.c:89
#2  0x7f090ad747dd in __gnu_cxx::__verbose_terminate_handler ()
at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95
#3  0x7f090ad72866 in __cxxabiv1::__terminate (handler=)
at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:47
#4  0x7f090ad728b1 in std::terminate () at
../../../../libstdc++-v3/libsupc++/eh_terminate.cc:57
#5  0x7f090ad72ac8 in __cxxabiv1::__cxa_throw (obj=0x7f0904000940, 
tinfo=0x604360 , 
dest=0x400ce0 ) at
../../../../libstdc++-v3/libsupc++/eh_throw.cc:87
#6  0x00400fdd in c(int) ()
#7  0x00400fa0 in b(int) ()
#8  0x00400f85 in a(int) ()
#9  0x00402574 in void std::_Bind_simple::_M_invoke<0ul>(std::_Index_tuple<0ul>) ()
#10 0x00402493 in std::_Bind_simple::operator()()
()
#11 0x00402432 in std::thread::_Impl::_M_run() ()
#12 0x7f090ad9c820 in std::execute_native_thread_routine (__p=)
at ../../../../../libstdc++-v3/src/c++11/thread.cc:82
#13 0x7f090b0676aa in start_thread (arg=0x7f090a3fd700) at
pthread_create.c:333
#14 0x7f090a504e9d in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:109

[Bug libstdc++/55917] Impossible to find/debug unhandled exceptions in an std::thread

2016-05-20 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55917

Howard Hinnant  changed:

   What|Removed |Added

 CC||howard.hinnant at gmail dot com

--- Comment #14 from Howard Hinnant  ---
The main function is not wrapped in a try / catch and an unhandled exception on
the main thread still calls std::terminate() as required.

I believe that gcc already correctly implements the call to std::terminate()
for threads elsewhere, and with the same code that it does for main.  It is in
the function __cxa_throw, implemented by libsupc++.  Here is the specification:

http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-throw

which says in part:

> __Unwind_RaiseException begins the process of stack unwinding, described in 
> Section 2.5. In special cases, such as an inability to find a handler, 
> _Unwind_RaiseException may return. In that case, __cxa_throw will call 
> terminate, assuming that there was no handler for the exception.

And here is where it is implemented:

https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/eh_throw.cc#L87

As long as libsupc++ is being used on the platform, I think you are good to
remove the try/catch from execute_native_thread_routine.

Fwiw, this is what is done on libc++ / libc++abi (no try/catch at the top of
std::thread, and let __cxa_throw call terminate).  We get beautiful stack dumps
from threaded code over there. :-)

[Bug libstdc++/68190] [5/6 Regression] iterator mix up with set::find and heterogenous lookup

2015-11-03 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68190

--- Comment #9 from Howard Hinnant  ---
Untested fix suggested:

#if __cplusplus > 201103L   
  template
auto
find(const _Kt& __x) -> decltype(iterator{_M_t._M_find_tr(__x)})
{ return iterator{_M_t._M_find_tr(__x)}; }  

  template
auto
find(const _Kt& __x) const ->
decltype(const_iterator{_M_t._M_find_tr(__x)})  
{ return const_iterator{_M_t._M_find_tr(__x)}; }
#endif

[Bug libstdc++/68190] New: iterator mix up with set::find and heterogenous lookup

2015-11-02 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68190

Bug ID: 68190
   Summary: iterator mix up with set::find and heterogenous lookup
   Product: gcc
   Version: 5.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: howard.hinnant at gmail dot com
  Target Milestone: ---

This fails to compile because template  set::find is returning the
wrong iterator type (I think).

#include 

struct Comparator
{
using is_transparent = std::true_type;

bool
operator() (int x, unsigned y) const
{
return x < y;
}


bool
operator() (unsigned x, int y) const
{
return x < y;
}


bool
operator() (int x, int y) const
{
return x < y;
}

};

int
main()
{
std::set<int, Comparator> s;
s.insert(1);
auto iter = s.find(1u);
iter = s.erase(iter);
}

[Bug libstdc++/68190] iterator mix up with set::find and heterogenous lookup

2015-11-02 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68190

--- Comment #2 from Howard Hinnant  ---
LWG 103 isn't the issue.

http://melpon.org/wandbox/permlink/MzOWaFpvFRtgaa7t

C::iterator is   std::_Rb_tree_const_iterator
C::const_iterator is std::_Rb_tree_const_iterator
C::find(1u) returns  std::_Rb_tree_iterator

s.erase returns a std::_Rb_tree_const_iterator which can not be converted
into a std::_Rb_tree_iterator.

If C::find(1u) returned a C::iterator (as specified in 23.4.6.1) instead of a
std::_Rb_tree_iterator, this bug would be fixed.

[Bug c++/67631] New: brace initialization bug

2015-09-18 Thread howard.hinnant at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67631

Bug ID: 67631
   Summary: brace initialization bug
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: howard.hinnant at gmail dot com
  Target Milestone: ---

I expect this program to compile and not assert when run:

#include 

template 
void
test(const U& uo)
{
T t{uo};
U u{t};
assert(u == uo);
t = T{uo};
u = U{t};
assert(u == uo);
}

class X
{
unsigned char data_;
public:
explicit X(unsigned data)
: data_(data)
{}

explicit operator unsigned() const {return data_;}

friend bool operator==(const X& x, const X& y)
{
return x.data_ == y.data_;
}
};

int
main()
{
test(X{3});
}

I get:

prog.cc: In instantiation of 'void test(const U&) [with T = unsigned int; U =
X]':
prog.cc:34:24:   required from here
prog.cc:10:7: error: cannot convert 'const X' to 'unsigned int' in
initialization
 t = T{uo};
   ^


[Bug libstdc++/54316] [C++11] move constructor for stringstream

2014-03-19 Thread howard.hinnant at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316

--- Comment #8 from Howard Hinnant howard.hinnant at gmail dot com ---
Here:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1862.html#27.4.4%20-%20Class%20template%20basic_ios

is a good list of what needs to be done.  It is an old paper, so it needs to be
cross-checked against N3936.  But the differences (if any) should be few and
minor.

The changes in this part of the standard are confusing to understand, because
of the use of virtual inheritance.  However if one just blindly follows the
recipe, backed up by a few unit tests, things will just work.  The more
difficult parts are the concrete streambufs:  basic_filebuf and
basic_streambuf.  Once those are in place, the streams just fall into place
with very little code.


[Bug libstdc++/54316] [C++11] move constructor for stringstream

2014-03-18 Thread howard.hinnant at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316

Howard Hinnant howard.hinnant at gmail dot com changed:

   What|Removed |Added

 CC||howard.hinnant at gmail dot com

--- Comment #6 from Howard Hinnant howard.hinnant at gmail dot com ---
Can I offer technical assistance?