[Bug c++/85517] New: std::variant exception safety problems

2018-04-24 Thread zhangxy at google dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85517

Bug ID: 85517
   Summary: std::variant exception safety problems
   Product: gcc
   Version: 7.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: zhangxy at google dot com
  Target Milestone: ---

There are several issues with the implementation of std::variant related to
exception safety:
1. Copy assignment
According to [variant.assign] 23.7.3.3 (2.4): if either
is_nothrow_copy_constructible_v or !is_nothrow_move_constructible_v
is true, equivalent to emplace(get(rhs)).

Failure case 1) If Tj is nothrow copy constructible, it should be equivalent to
emplace() which destroys the current content and invoke Tj's copy ctor.
However, the current implementation always copy constructs a temporary variant
and invoke the move constructor. This is unnecessary.

Failure case 2) If Tj's copy ctor throws, *this should be
valueless_by_exception() because emplace() first destroys then invokes the copy
ctor. Since the current implementation copy constructs a temporary variant
first, it has strong guarantee while the standard requires basic guarantee.

2. Conversion assignment operator=(T&&)
According to [variant.assign] 23.7.3.3 (11.3): if is_nothrow_constructible == false && is_nothrow_move_constructible == true, equivalent to
operator=(variant(std::forward(t))).

Failure case: If Tj has a nothrow move constructor, the standard requires
strong guarantee (that a temporary variant be created first and move it into
*this). The current implementation always invokes emplace(), which has only
basic guarantee.

[Bug c++/83689] New: Internal compiler error using is_trivially_default_constructible on array of nontrivially-destructible types

2018-01-04 Thread zhangxy at google dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83689

Bug ID: 83689
   Summary: Internal compiler error using
is_trivially_default_constructible on array of
nontrivially-destructible types
   Product: gcc
   Version: 7.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: zhangxy at google dot com
  Target Milestone: ---

The following code triggers internal compiler error (see
https://godbolt.org/g/dXRbdK for more details and comparison with clang):

/opt/compiler-explorer/gcc-7.2.0/include/c++/7.2.0/type_traits: In
instantiation of 'struct std::is_trivially_constructible':
/opt/compiler-explorer/gcc-7.2.0/include/c++/7.2.0/type_traits:1373:12:  
required from 'struct
std::is_trivially_default_constructible'
31 : :31:84:   required from here
/opt/compiler-explorer/gcc-7.2.0/include/c++/7.2.0/type_traits:1366:12:
internal compiler error: in build_value_init_noctor, at cp/init.c:483
 struct is_trivially_constructible
^~
mmap: Invalid argument

```
#include 

class NontrivialDefaultCtor {
 public:
  NontrivialDefaultCtor() {}
};

void f() {
  using NontrivialDefaultCtor10 = NontrivialDefaultCtor[10];
 
static_assert(!std::is_trivially_default_constructible::value,
  "This should be false");
}
```

[Bug c++/84866] New: Incorrectly instantiating move ctor when a union's move constructor is implicitly deleted

2018-03-14 Thread zhangxy at google dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84866

Bug ID: 84866
   Summary: Incorrectly instantiating move ctor when a union's
move constructor is implicitly deleted
   Product: gcc
   Version: 7.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: zhangxy at google dot com
  Target Milestone: ---

Please see https://godbolt.org/g/5VTrtz for a reduced test case.

The reasoning is: if is_move_constructor() is true, I should be able to move
construct a T (even though it might be using the copy ctor).

Note:
- The bug seems to be exist since early versions (tried 4.9).
- The bug is not relevant to the standard versions, i.e. -std=c++11 or
-std=c++17.
- The bug only occurs when a type (with trivial copy ctor and nontrivial move
ctor) is nested in a union, not when it is at top level of the union.

[Bug libstdc++/82262] New: std::hash>::operator() missing remove_const_t

2017-09-19 Thread zhangxy at google dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82262

Bug ID: 82262
   Summary: std::hash>::operator()  missing
remove_const_t
   Product: gcc
   Version: 7.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: zhangxy at google dot com
  Target Milestone: ---

std::hash> specialization doesn't work with const-qualified
type. I think the problem is that std::remove_const_t is missing.

For example, the following code will result in compiler error:

#include 

void Foo() {
std::hash> h;
std::optional o(1);
size_t v = h(o);
}

/opt/compiler-explorer/gcc-7.2.0/include/c++/7.2.0/optional: In instantiation
of 'std::size_t std::__optional_hash_call_base<_Tp, 
>::operator()(const std::optional<_Tp>&) const [with _Tp = const int; bool
 = true; std::size_t = long unsigned int]':
6 : :6:19:   required from here
/opt/compiler-explorer/gcc-7.2.0/include/c++/7.2.0/optional:1009:37: error:
could not convert '()' from '' to 'std::__hash_enum'
   noexcept(noexcept(hash<_Tp> {}(*__t)))
 ^~