[Bug c++/85517] New: std::variant exception safety problems
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
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
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
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))) ^~