[Bug libstdc++/115099] compilation error: format thread::id
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115099 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- I guess we shouldn't include in . There should be far more simple ways to obtain thread::id's text representation.
[Bug libstdc++/115059] Constraints/Mandates on the comparison operators of std::optional and std::variant are overly strict
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115059 --- Comment #2 from Jiang An --- (In reply to Jonathan Wakely from comment #1) > I don't want to change anything in libstdc++ here. Either > std::is_convertible should be sufficient to check "convertible to" > constraints, or "convertible to" should exclude these kind of games. Yeah. This is perphaps in the scope of LWG484 and LWG3105, but guaranteed copy elision doesn't seem discussed yet.
[Bug libstdc++/115059] New: Constraints/Mandates on the comparison operators of std::optional and std::variant are overly strict
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115059 Bug ID: 115059 Summary: Constraints/Mandates on the comparison operators of std::optional and std::variant are overly strict Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following example should compile in C++23/26 (or some other modes where explicit object parameters are available) due to CWG DR 2813 (https://cplusplus.github.io/CWG/issues/2813.html), given that [optional.relops] and [variant.relops] only require the result to be convertible to bool. ``` #include #include class PinnedBoolean { private: bool val_; PinnedBoolean(const PinnedBoolean&) = delete; PinnedBoolean& operator=(const PinnedBoolean&) = delete; public: constexpr explicit PinnedBoolean(bool b) noexcept : val_{b} {} constexpr operator bool(this PinnedBoolean x) noexcept { return x.val_; } }; static_assert(PinnedBoolean{true}); struct X { friend constexpr PinnedBoolean operator==(X, X) noexcept { return PinnedBoolean{true}; } friend constexpr PinnedBoolean operator!=(X, X) noexcept { return PinnedBoolean{false}; } }; static_assert(std::optional{} == std::optional{}); static_assert(std::variant{} == std::variant{}); ``` However, libc++ is currently applying stricter requirements (https://godbolt.org/z/Mc3bse5h7). Since CWG2813, both __boolean_testable and is_convertible_v are stricter than the plain "convertible to", because the implicit conversion from the result type to bool can be only well-formed for prvalues but not xvalues.
[Bug c++/114388] Behavioral change of typeid on xvalues since GCC 9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114388 --- Comment #10 from Jiang An --- Broken down into two smaller examples: https://godbolt.org/z/YhK7PqE6s ``` #include #include int main() { struct B { B() {} virtual ~B() { std::puts("C++11"); } }; struct C { B b; }; typeid(C().b); // unevaluated in C++98, evaluated in C++11 } ``` https://godbolt.org/z/on76q4Mx5 ``` #include int main() { struct B { B() {} B(const B&) { std::puts("C++98"); } }; struct D : B {}; struct BB { B b; }; struct DD { D d; }; true ? BB().b : DD().d; // additional copy in C++98, no copy or move in C++11 } ``` CWG2887 (https://cplusplus.github.io/CWG/issues/2887.html) is related.
[Bug libstdc++/114891] New: Unconditional use of std::is_pointer_interconvertible_base_of_v in makes the header unusable with Clang 18
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114891 Bug ID: 114891 Summary: Unconditional use of std::is_pointer_interconvertible_base_of_v in makes the header unusable with Clang 18 Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- Clang only supports the intrinsic for is_pointer_interconvertible_base_of_v since 19 (https://github.com/llvm/llvm-project/pull/88473). It seems that the uses of is_pointer_interconvertible_base_of_v is not strictly needed. Perhaps we should guard the uses with __cpp_lib_is_pointer_interconvertible to support old versions of Clang.
[Bug libstdc++/114866] & out_ptr in freestanding
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114866 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- It seems that the primary tempate of __is_shared_ptr should be made available in freestanding mode.
[Bug c++/114844] New: A trivial but noexcept(false) destructor is incorrectly considered non-throwing
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114844 Bug ID: 114844 Summary: A trivial but noexcept(false) destructor is incorrectly considered non-throwing Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: accepts-invalid, rejects-valid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- Currently, GCC incorrectly accepts the following code snippet (allowed by P1286R2), which conflicts with [except.spec]/6.2. ``` struct TrivialButPotentiallyThrowingDestructor { TrivialButPotentiallyThrowingDestructor() = default; ~TrivialButPotentiallyThrowingDestructor() noexcept(false) = default; }; static_assert(noexcept(TrivialButPotentiallyThrowingDestructor{}), "???"); ``` It's curious that other compilers except for EDG also get this wrong (https://godbolt.org/z/57jf98xhc).
[Bug libstdc++/114817] Wrong codegen for std::copy of "trivially copyable but not trivially assignable" type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114817 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #2 from Jiang An --- Bug 106547 seems somehow related.
[Bug libstdc++/89855] Inconsistent global namespace overload sets from #include
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89855 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #12 from Jiang An --- (In reply to Andrew Pinski from comment #1) > I there is a related defect report against the c++ standard about this exact > issue. I think this is LWG 2380 (https://cplusplus.github.io/LWG/issue2380).
[Bug libstdc++/114477] The user-defined constructor of filter_view::iterator is not fully compliant with the standard
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114477 --- Comment #5 from Jiang An --- (In reply to 康桓瑋 from comment #0) > Since P3059R0 is closed (although I feel bad about this) BTW, now I think this is somehow unfortunate. P3059 behaved like a follow-up paper of P2711 IMO. Both papers effectively suggested that "some design choices of C++23 views are better, let's apply them to C++20 views".
[Bug libstdc++/114477] The user-defined constructor of filter_view::iterator is not fully compliant with the standard
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114477 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- Constructors of the following types seemly need to be changed: basic_istream_view::_Iterator filter_view::_Iterator filter_view::_Sentinel transform_view::_Iterator join_view::_Sentinel lazy_split_view::_OuterIter split_view::_Iterator split_view::_Sentinel Currently libstdc++'s versions take pointers to the base views, while the standard requires to take references.
[Bug libstdc++/114417] std::experimental::simd is not a POD (by ABI definitions) and is always passed by reference instead of by value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114417 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #8 from Jiang An --- There're comments saying: > // The following ensures, function arguments are passed via the stack. > // This is important for ABI compatibility across TU boundaries I have no idea about why this was considered outweighting trivial copyability.
[Bug c++/114395] [c++20+] std::is_constructible_v result of const reference incorrect
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114395 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #10 from Jiang An --- I think this is basically CWG2709 (https://cplusplus.github.io/CWG/issues/2709.html). Given CWG2709 is closed as NAD, we should reject such initializations.
[Bug libstdc++/114400] The resolution of LWG3950 seems incorrectly implemented
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114400 --- Comment #4 from Jiang An --- (In reply to Jonathan Wakely from comment #1) > The resolution of LWG 3950 has not been implemented, at all. Hmm... r14-5349 seems "implementing the resolution" per the commit message. Perhaps I misread something.
[Bug libstdc++/114400] New: The resolution of LWG3950 seems incorrectly implemented
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114400 Bug ID: 114400 Summary: The resolution of LWG3950 seems incorrectly implemented Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following example fails to compile with libstdc++ due to ambiguity in overload resolution (https://godbolt.org/z/Ya5o4rrKj). ``` #include #include #include namespace test { template concept characterized_traits = requires { typename Traits::is_characterized; }; template struct test_traits : std::char_traits { using is_characterized = void; }; template struct traits_comparison_category { using type = std::weak_ordering; }; template requires requires { typename Traits::comparison_category; } struct traits_comparison_category { using type = Traits::comparison_category; static_assert(std::disjunction_v< std::is_same, std::is_same, std::is_same>); }; // N.B. std::type_identity_t is exactly used. template constexpr bool operator==( std::basic_string_view x, std::type_identity_t> y) noexcept { return x.size() == y.size() && x.compare(y) == 0; } template constexpr traits_comparison_category::type operator<=>( std::basic_string_view x, std::type_identity_t> y) noexcept { return static_cast::type>(x.compare(y) <=> 0); } using test_string_view = std::basic_string_view>; static_assert(test_string_view{} == test_string_view{}); static_assert(test_string_view{} == ""); static_assert("" == test_string_view{}); static_assert(test_string_view{} <=> test_string_view{} == std::strong_ordering::equal); static_assert(test_string_view{} <=> "" == std::strong_ordering::equal); static_assert("" <=> test_string_view{} == std::strong_ordering::equal); } ``` The resolution of LWG3950 (https://cplusplus.github.io/LWG/issue3950) uses `type_identity_t`, while libstdc++ currently uses `__type_identity_t`. The difference between two alias templates can be observed by partial ordering introduced by associated constraints. Related PR in MSVC STL: https://github.com/microsoft/STL/pull/4249
[Bug c++/114388] Behavioral change of typeid on xvalues since GCC 9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114388 --- Comment #7 from Jiang An --- (In reply to Jonathan Wakely from comment #5) > Prior to DR 616 the expression (true ? WrapB().b : WrapD().d) was a prvalue > of type B, created by copying the B (or slicing the D when the condition is > false). As an rvalue, it wasn't evaluated. That's true pre-N3055 and > post-N3055. > > DR 616 changed WrapB().b to be an xvalue, and the result of the expression > is B&& in C++1 (and const B& in C++98 I guess). > > In C++98 the const B& is an lvalue, and in C++11 the B&& is an xvalue which > is a glvalue. Either way, it's correct to treat it as a glvalue of > polymorphic type and evaluate it. > > So this change is not caused by N3055. And I think G++ is correct for both > C++98 and C++11. So INVALID. Pre-N3055 there were no xvalue branch in [expr.cond], and (later-called) xvalues were handled alongwith prvalues. I don't see anything in C++98 [expr.cond] adding const& when there's no const values. This example also shows that GCC hasn't been thinking that the result of the expression is const B& in C++98: https://godbolt.org/z/EPv65oY1W.
[Bug c++/114388] Behavioral change of typeid on xvalues since GCC 9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114388 --- Comment #3 from Jiang An --- (In reply to Richard Biener from comment #2) > So you say GCC 9+ are wrong with -std=c++98 but OK with -std=c++11 or newer > (the default)? Yes.
[Bug c++/114388] Behavioral change of typeid on xvalues since GCC 9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114388 --- Comment #1 from Jiang An --- Moreover, perhaps we should list N3055 in the implementation status page (https://gcc.gnu.org/projects/cxx-status.html) since it did contain behavioral change of typeid.
[Bug c++/114388] New: Behavioral change of typeid on xvalues since GCC 9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114388 Bug ID: 114388 Summary: Behavioral change of typeid on xvalues since GCC 9 Product: gcc Version: 9.5.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- IIUC this program behaves differently in C++98 and C++11 due to WG21 N3055 (https://wg21.link/n3055): ``` #include #include struct B { virtual ~B() { std::puts("~B"); } }; struct D : B {}; struct WrapB { B b; }; struct WrapD { D d; }; int main() { typeid(true ? WrapB().b : WrapD().d); } ``` Before C++11/N3055, the operand of the typeid expression shouldn't be evaluated because it's a rvalue. But since C++11 it should be evaluated because it's a glvalue of a polymorphic class type. It's curious that GCC behaves consistently on this in C++98 and C++11 modes. Per https://godbolt.org/z/7oGdjdMK7, it seems that GCC 8 (and former versions) applied the C++98 rules to C++11 and later modes, and GCC 9 (and later verions) applied the C++11 rules to C++98 mode. For later versions, I'm not sure whether this is a bug (in C++98 mode) or an intentional backporting.
[Bug libstdc++/114387] New: Explicitly declared destructor makes basic_format_context sometimes not movable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114387 Bug ID: 114387 Summary: Explicitly declared destructor makes basic_format_context sometimes not movable Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following code snippet doesn't compile when using libstdc++ (https://godbolt.org/z/x3v44PTbq). ``` #include #include #include #include template class sealed_output_iterator { private: CharT* p_; public: using difference_type = std::ptrdiff_t; explicit sealed_output_iterator(CharT* p) noexcept : p_{p} {} sealed_output_iterator(sealed_output_iterator&&) = default; sealed_output_iterator& operator=(sealed_output_iterator&&) = default; CharT& operator*() const noexcept { return *p_; } sealed_output_iterator& operator++() noexcept { ++p_; return *this; } sealed_output_iterator& operator++(int) noexcept { ++p_; return *this; } }; static_assert(std::movable>); static_assert(!std::copyable>); static_assert(std::output_iterator, const char&>); static_assert(std::movable, char>>); // ! ```' The reason seems to be that the explicitly declared destructor suppresses the implict declaration of move constructor and assignment operator. https://github.com/gcc-mirror/gcc/blob/c4845edfeaf44756ad9672e8d143f1c8f5c4c0f6/libstdc%2B%2B-v3/include/std/format#L3839 Per https://eel.is/c++draft/format.context, it seems that no specialization member functions of basic_format_context is suppressed, so perhaps libstdc++ should remove the explicit declaration of the destructor. However, it's unclear to me whether users are supposed to be able to default-construct/copy/move basic_format_context objects. So it may be wanted to delete copy functions, but this may need an LWG issues.
[Bug libstdc++/114354] std::shared_ptr constructor constraints are checked too late
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114354 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- The constraints were transformed from preconditions by LWG2874 (https://cplusplus.github.io/LWG/issue2874). So perhaps the actually issue is not having implemented LWG2874, and I think the constraints need to be implemented for C++17. The wording change in LWG2874 seems to be on the top of P0414R2 + P0497R0. I'm not sure what the "backported form of LWG2874" exactly is. Perhaps it's simply "This constructor shall not participate in overload resolution unless the expression delete p is well-formed and Y* is convertible to T*." (not considering whether T or Y is an array type)?
[Bug libstdc++/114336] Manual should document implementation-defined behaviour in C++20 and C++23
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114336 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- IMO the column number obtained from std::source_location::current is somehow curious and might be critical. Implementations behaves differently, and currently there doesn't seem any official documentation for this value.
[Bug libstdc++/77776] C++17 std::hypot implementation is poor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=6 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #14 from Jiang An --- (In reply to g.peterhoff from comment #11) > constexpr > * The hypot3 functions can thus be defined as _GLIBCXX_CONSTEXPR. I think it should be marked _GLIBCXX26_CONSTEXPR. (and we may also need to change bits/c++config)
[Bug c++/114163] Calling member function of an incomplete type compiles in gcc and does not compile in clang and msvc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114163 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #2 from Jiang An --- May be related to CWG2852. https://cplusplus.github.io/CWG/issues/2852.html
[Bug c++/114076] list-initialization with assignment expression triggers wrong template instanciation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114076 --- Comment #2 from Jiang An --- The "templatization" trick also works for GCC. https://godbolt.org/z/8PeMMzsbb ``` template struct holder { holder() = default; constexpr ~holder() { static_assert(sizeof(T) || true); } }; struct Incomplete; template // templated struct Class { Class(); ~Class(); holder a{}; // all accept holder b = {}; // all accept holder c = holder{}; // only Clang rejects }; int main() { [[maybe_unused]] Class v; // CTAD } ``` It's unclear to me what is not yet instantiated after the object definition.
[Bug c++/114076] list-initialization with assignment expression triggers wrong template instanciation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114076 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- Looks like a duplicate of Bug 104850 to me. GCC cares about the difference between direct/copy of initialization, not whether list-initialization or not (however, it's unfortunately that direct-non-list-initialization can't be used). > In case c, the rejection seems to me to be correct, since here the temporary > value must be destroyed by a destructor call. I don't see why there's even a temporary value since C++17. The prvalue is used to initialize the data member (via temporary materialization). The potential invocation of destructor should be in the body of constructors.
[Bug c++/104850] Instantiating a destructor for a template class too early, before the calling destructor is seen - rejects valid code
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104850 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #5 from Jiang An --- Clang started to accept this since Clang 16. https://godbolt.org/z/c6vGzTP48
[Bug c++/114078] New: operator new and operator delete are incorrectly acceptable as explicit object member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114078 Bug ID: 114078 Summary: operator new and operator delete are incorrectly acceptable as explicit object member functions Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: accepts-invalid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- GCC currently accepts this wrong program while it shouldn't (https://godbolt.org/z/7jGnGqYPM), because member operator new/operator delete are always static member functions. #include #include struct S { void* operator new(this std::size_t); void operator delete(this S*, std::destroying_delete_t); operator S*() const; operator std::size_t() const; }; int main() { S{}.operator new(); S{}.operator delete(std::destroying_delete); } Similar to https://github.com/llvm/llvm-project/issues/82249 which is fixed recently.
[Bug libstdc++/113782] constexpr on std::initializer_list, std::pair and std::tuple is non-conforming for C++11
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113782 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- May be related to PR 102916. Is there any policy for "backporting" constexpr?
[Bug libstdc++/114018] std::nexttoward is not implemented for C++23-FP-Types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114018 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #12 from Jiang An --- (In reply to Jakub Jelinek from comment #11) > But what about following: > #include > #include > > auto f = static_cast double)>(::nexttoward); > > This doesn't call std::nexttoward(std::float128_t, long double), just checks > if it is defined. The well-formedness is currently unspecified because std::nexttoward is not addressable (see [namespace.std]). I think such conversion should be ill-formed and libstdc++ is currently doing the right thing. No change needs to be done.
[Bug libstdc++/113060] std::variant converting constructor/assignment is non-conforming after P2280?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113060 --- Comment #8 from Jiang An --- (In reply to Giuseppe D'Angelo from comment #7) > Hi, > > > Note that this example adds a mediate function template > > (test_array_element_initializable) to "reduce" the non-constexpr-ness of > > std::declval. > > That's very clever, thank you! > > Is it _supposed_ to work, though? I had imagined (possibly erroneusly) that > once one places the call to `test_array_element_initializable` using > `declval` as an argument, it would disqualify the whole thing from being > usable in constant expressions. > > (It would help to have another compiler that implements P2280, so to do more > tests...) I think it's supposed to work. Enclosing std::declval calls don't matter because only the constantness in the trailing return type would affect overload resolution. Ah, we don't even need to call the function template or function pointers - it's sufficient to only detect the well-formedness of the function type. The simplest "fix" I found is changing `void_t{{std::declval<_Tp>()}})>` to `void_t decltype(_Arr<_Ti>{{std::forward<_Tp>(__t)}})>` , which seemingly works (https://godbolt.org/z/8M85zre5P).
[Bug libstdc++/113007] `std::variant` converting constructor and `operator=` compile while the C++ Standard says they must not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113007 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #8 from Jiang An --- (In reply to Pavel Novikov from comment #7) > Now it's time to file a bug in MSVC's standard library. This was by design. MSVC STL intendedly only enabled changes in P0608R3 since C++20 (https://github.com/microsoft/STL/pull/1629#issuecomment-778895630). But given the author of P0608R3 applied the changes to libc++ in C++17 mode, I think it makes more sense to treat it as a DR. I've opened this issue: https://github.com/microsoft/STL/issues/4412
[Bug libstdc++/113060] std::variant converting constructor/assignment is non-conforming after P2280?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113060 --- Comment #6 from Jiang An --- (In reply to Jiang An from comment #5) > `decltype(std::declval > decltype(_Arr<_Ti>{{std::forward<_Tp>(__t)}})>(std::declval<_Tp>()))` Typo, this should be `decltype(std::declval decltype(_Arr<_Ti>{{std::forward<_Tp>(__t)}})>()(std::declval<_Tp>()))`.
[Bug libstdc++/113060] std::variant converting constructor/assignment is non-conforming after P2280?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113060 --- Comment #5 from Jiang An --- Function pointers seem working (https://gcc.godbolt.org/z/Mbvfafdof). ``` template constexpr bool is_array_element_initializable_from = false; template constexpr bool is_array_element_initializable_from decltype((void) array_element_initialization_tester{{std::forward(t)}})>() (std::declval()))> = true; ``` So perhaps we can simply change `decltype(_Arr<_Ti>{{std::declval<_Tp>()}})` to `decltype(std::declval decltype(_Arr<_Ti>{{std::forward<_Tp>(__t)}})>(std::declval<_Tp>()))` to resolve this "bug".
[Bug libstdc++/113060] std::variant converting constructor/assignment is non-conforming after P2280?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113060 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #4 from Jiang An --- Hi, I found that we can support std::variant(IC{}) with C++17 core language rules (as modified by P2280R4), and thus P3146 should be updated. Proof-of-concept example (https://gcc.godbolt.org/z/174sx397f): ``` #include #include template struct array_element_initialization_tester { Ti elems[1]; }; template auto test_array_element_initializable(Tp&& t) -> decltype((void) array_element_initialization_tester{{std::forward(t)}}); template constexpr bool is_array_element_initializable_from = false; template constexpr bool is_array_element_initializable_from(std::declval()))> = true; template , int> = 0> void FUN(float); int main() { using IC = std::integral_constant; FUN(IC{}); IC ic; FUN(ic); } ``` Note that this example adds a mediate function template (test_array_element_initializable) to "reduce" the non-constexpr-ness of std::declval.
[Bug libstdc++/113851] New: boyer_moore_searcher and boyer_moore_horspool_searcher fail to accept ADL-incompatible element types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113851 Bug ID: 113851 Summary: boyer_moore_searcher and boyer_moore_horspool_searcher fail to accept ADL-incompatible element types Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following program doesn't compile with libc++ due to ADL which attempts to complete a bad type. ``` #include #include template struct holder { T t; }; struct incomplete; int main() { using validator = holder*; validator varr[1]{}; (void) std::search(varr, varr + 1, std::boyer_moore_searcher{varr, varr + 1}); (void) std::search(varr, varr + 1, std::boyer_moore_horspool_searcher{varr, varr + 1}); } ``` It seems that non-ADL-proof iterator operations are problematic, and all standard library implementations suffer from similar problems (https://godbolt.org/z/Ta6PafcnK).
[Bug c++/113563] Rejects capture of `this` in C++23 `this auto` lambda
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113563 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- (In reply to Arthur O'Dwyer from comment #0) > Btw, I do like that GCC eagerly and SFINAE-friendlily rejects `[&](this T) > {}`. I hope fixing this bug doesn't require undoing that feature. > (By "SFINAE-friendly" I mean https://godbolt.org/z/fK4f13343 ) > See also > https://quuxplusone.github.io/blog/2024/01/23/capturing-lambda-deducing-this/ Hmm... after reading CWG2672 (https://cplusplus.github.io/CWG/issues/2672.html), I think the SFINAE-friendliness is actually required since the parameter list of a lambda expression is in the immediate context (only the lambda body is excluded).
[Bug c++/113638] Array bounds of variable templates are not correctly deduced from initializers since GCC13
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113638 --- Comment #1 from Jiang An --- > The following code snippet is incorrectly processed since C++13. Typo: this should be "since GCC13".
[Bug c++/113638] New: Array bounds of variable templates are not correctly deduced from initializers since GCC13
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113638 Bug ID: 113638 Summary: Array bounds of variable templates are not correctly deduced from initializers since GCC13 Product: gcc Version: 13.2.1 Status: UNCONFIRMED Keywords: accepts-invalid, rejects-valid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following code snippet is incorrectly processed since C++13. Godbolt link: https://godbolt.org/z/xjEqnqodj ``` #include template constexpr int my_array[]{Is...}; static_assert(std::is_same_v), const int[5]>); // rejected since GCC13 static_assert(sizeof(my_array<1, 2, 3, 4, 5>) == sizeof(int) * 5); // rejected since GCC13 static_assert(std::is_same_v), const int[]>); // passes since GCC13, but should not ``` It seems that GCC gives up deducing the array bounds from initializers of variable templates since GCC13.
[Bug libstdc++/113522] std::swap cannot be called with explicit template argument std::array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113522 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #4 from Jiang An --- std::swap is not supposed to be called with explicitly specified template arguments. If the template arguments are not explicitly specified for std::swap, the correct overloads will be selected if you include currect headers, even when not all standard headers that declare std::swap overloads are included (the shape of overload set is unspecified in such cases). However, if you explicitly specify template arguments, there may be unintended (likely incorrect) overloads whose template arguments are no longer underdeduced to be selected. And then undesired implicit conversion can be trigged during overload resolution, which can make your program ill-formed. (In reply to Jonathan Wakely from comment #1) > This is silly code and there is no reason to support it. Hmm... currently it's specified in [algorithms.requirements] that > The well-formedness and behavior of a call to an algorithm with an > explicitly-specified template argument list is unspecified, except where > explicitly stated otherwise. (Added by P0896R4 and amended by LWG3419.) Should open an LWG issue to specify similar things for std::swap?
[Bug libstdc++/113470] New: Should std::tuple_size be a complete type?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113470 Bug ID: 113470 Summary: Should std::tuple_size be a complete type? Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following code snippet is currently showing implementation divergence (https://godbolt.org/z/P8oWqf5sT). MSVC STL's std::tuple_size is a complete type, while libstdc++'s and libc++'s are not. ``` #include // constexpr auto foo = sizeof(std::tuple_size);// Correctly rejected. constexpr auto bar = sizeof(std::tuple_size); // Should be well-formed? ``` It seems that MSVC STL's behavior is justified by https://eel.is/c++draft/contents#1 and https://eel.is/c++draft/tuple.syn, given that only the primary templates of std::tuple_size and std::tuple_element are marked `// not defined`. I'm not sure whether this should be considered as a bug. Perhaps an LWG issue is wanted.
[Bug libstdc++/113200] std::char_traits::move is not constexpr when the argument is a string literal
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113200 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #9 from Jiang An --- (In reply to Peter Dimov from comment #3) > I think that the compiler is correct; string literal address comparisons > aren't constant expressions. Clang gives the same error: > https://godbolt.org/z/xPWEf4z63. This looks weird... It seems that `+"abc" == +"def"` is never unspecified (must be false, but Clang rejects it in constant evaluation), while `"abcd" + 1 == +"bcd"` is unspecified. It's unclear to me whether we can practically detect all kinds of unspecifiedness in pointer comparision involving string literals.
[Bug c++/113141] New: ICE on conversion to reference in aggregate initialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113141 Bug ID: 113141 Summary: ICE on conversion to reference in aggregate initialization Product: gcc Version: 13.2.1 Status: UNCONFIRMED Keywords: ice-checking, ice-on-invalid-code Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following program triggers ICE since GCC 13 (https://godbolt.org/z/PaqWsG9s6): ``` int global_x{}; struct ConvToRef { operator int&() { return global_x; } }; struct Foo { int& r; }; int main() { Foo bar{ { ConvToRef{} } }; } ``` Clang considers this ill-formed and emits "non-const lvalue reference to type 'int' cannot bind to an initializer list temporary". If the type of r is changed to const int&, the program correctly compiles with GCC.
[Bug c++/103183] [11/12/13/14 Regression] ind[arr] produces an lvalue when arr is an array xvalue
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103183 --- Comment #5 from Jiang An --- Seems fixed together by commit r14-6753-g8dfc52a75d4d6c8be1c61b4aa831b1812b14a10e. https://godbolt.org/z/on3K451a5
[Bug c++/113047] dereferencing a null pointer in a constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113047 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #3 from Jiang An --- CWG2823 has been voted into the standard (see https://wg21.link/p3046r0, https://wg21.link/n4972). > Should it be possible to dereference a null pointer in a C++20 constant > expression? Now such derefencing is clearly UB and needs to cause constant evaluation failure (not only in C++20, IMO).
[Bug libstdc++/113074] std::to_address should be SFINAE safe
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113074 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #6 from Jiang An --- Currently only libc++'s std::to_address is SFINAE-friendly. I think we should submit an LWG issue, although it would be possibly closed as NAD.
[Bug libstdc++/111948] subrange modifies a const size object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111948 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #6 from Jiang An --- This is certainly a compiler bug. I've reduced it and reported Bug 112439.
[Bug c++/112439] New: Modification of a member overlapping with a [[no_unique_address]] member in the constructor is incorrectly rejected
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112439 Bug ID: 112439 Summary: Modification of a member overlapping with a [[no_unique_address]] member in the constructor is incorrectly rejected Product: gcc Version: 13.2.1 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- GCC starts (incorrectly) rejecting the following code snipped since GCC13 (https://godbolt.org/z/faqMahz34). It's wrong to emit an error for this because c is not const in the constructor body. ``` struct Empty {}; class Foo { public: constexpr Foo(int x, Empty y, int z) : a(x), b(y) { c = z; } private: int a{}; [[no_unique_address]] Empty b{}; [[no_unique_address]] int c{}; }; constexpr Foo r{1, {}, 3}; ``` It seems that the code is correctly accepted if b and c are made not to overlap.
[Bug libstdc++/110854] constructor of std::counting_semaphore is not constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110854 --- Comment #3 from Jiang An --- (In reply to Jiang An from comment #2) > The constructor of the internal __platform_semaphore class currently calls > sem_init, which make it incompatible with constexpr... It seems doable to make the ctor constexpr, but we need to use different strategies for different C libs.
[Bug c++/94264] Array-to-pointer conversion not performed on array prvalues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94264 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #5 from Jiang An --- Related: https://cplusplus.github.io/CWG/issues/2548.html
[Bug c++/111723] New: #pragma GCC system_header suppresses errors from narrowing conversions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111723 Bug ID: 111723 Summary: #pragma GCC system_header suppresses errors from narrowing conversions Product: gcc Version: 13.2.1 Status: UNCONFIRMED Keywords: accepts-invalid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- In the following program, the conversions are narrowing, but only the one for nonstd::in_fun_result is rejected. When -Wsystem-headers is used, then the narrowing conversion for std::ranges::in_fun_result are correctly diagnosed. But if -pedantic-errors and -Wsystem-headers are used together, some standard headers are rejected. Godbolt link: https://godbolt.org/z/fT7b16eoe ``` #include #include #include namespace nonstd { template struct in_fun_result { [[no_unique_address]] I in; [[no_unique_address]] F fun; template requires std::convertible_to && std::convertible_to constexpr operator in_fun_result() const& { return {in, fun}; } template requires std::convertible_to && std::convertible_to constexpr operator in_fun_result() && { return {std::move(in), std::move(fun)}; } }; } int main() { std::ranges::in_fun_result r1{}; std::ranges::in_fun_result r2 = r1; // should be error, but not diagnosed by default nonstd::in_fun_result r3{}; nonstd::in_fun_result r4 = r3; // error, rejected with -pedantic-errors } ``` It seems to me that #pragma GCC system_header shouldn't suppress errors from narrowing conversions, because the diagnostics are required by the standard.
[Bug libstdc++/111327] std::bind_front (and std::not_fn) doesn't always perfectly forward according to value category of the call wrapper object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111327 --- Comment #6 from Jiang An --- It seems that deleted operator() overloads in the return type of std::not_fn is only necessary since C++20. The changes were made in P0356R5. In C++17, the return type was nearly fully specified and didn't have deleted overloads. https://timsong-cpp.github.io/cppwp/n4659/func.not_fn#1
[Bug libstdc++/111327] std::bind_front (and std::not_fn) doesn't always perfectly forward according to value category of the call wrapper object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111327 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #5 from Jiang An --- The current fix doesn't seem sufficient (https://godbolt.org/z/rs5oYxjTc): #include #include struct Weird { void operator()() {} bool operator()() const { return true; } }; int main() { auto nf = std::not_fn(Weird{}); nf(); // should be rejected, but calls the const overload std::as_const(nf)(); }
[Bug libstdc++/111511] Incorrect ADL in std::to_array in GCC 11/12/13
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111511 --- Comment #5 from Jiang An --- (In reply to m.cencora from comment #2) > (In reply to Jonathan Wakely from comment #1) > > (In reply to Jiang An from comment #0) > > > Not sure whether this should be WONTFIX since the implementation is > > > fundamentally changed in GCC 14 (PR 110167). > > > > There's no reason we can't fix the old version in the release branches. > > > > I did notice this when rewriting it, but I didn't think to change the > > branches to avoid ADL there, because I plan to backport the new > > implementation eventually anyway. > > On a semi-related topic: > Can't we use __builtin_bit_cast as even simpler implementation of to_array > for trivial types? __builtin_bit_cast results in constant evaluation failure when the element type is or contains a pointer or a union, which heavily restricts its usability in to_array.
[Bug c++/111512] New: GCC's __builtin_memcpy can trigger ADL
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111512 Bug ID: 111512 Summary: GCC's __builtin_memcpy can trigger ADL Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- When using libstdc++ in GCC 14, the following program compiles with Clang but is rejected by GCC (https://godbolt.org/z/WKbe1c3v7). ``` #include #include struct incomplete; template struct holder { T t; }; using validator = holder*; int main() { validator a[1]{}; (void) std::to_array(a); (void) std::to_array(std::move(a)); } ``` The implementation can be made to work for GCC if `::` is added before the call to __builtin_memcpy (https://godbolt.org/z/6Mx11T3f9). So the reason for failure seems to be that GCC's __builtin_memcpy can trigger ADL like a real function.
[Bug libstdc++/111511] New: Incorrect ADL in std::to_array in GCC 11/12/13
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111511 Bug ID: 111511 Summary: Incorrect ADL in std::to_array in GCC 11/12/13 Product: gcc Version: 13.2.1 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following program is incorrectly rejected when using libstdc++ (https://godbolt.org/z/x6K6r5svM). ``` #include #include struct incomplete; template struct holder { T t; }; using validator = holder*; int main() { validator a[1]{}; (void) std::to_array(a); (void) std::to_array(std::move(a)); } ``` The error is caused by aunqualified calls to the `__to_array` internal function, which triggers ADL for `incomplete` and requires it to be complete. Not sure whether this should be WONTFIX since the implementation is fundamentally changed in GCC 14 (PR 110167).
[Bug c++/111379] comparison between unequal pointers to void should be illegal during constant evaluation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111379 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- There's (or will be) a new DR CWG2749 which tentatively ready now. https://cplusplus.github.io/CWG/issues/2749.html It seems that the old resolution in CWG2526 was wrong, and the comparison should be constexpr-friendly. BTW I don't think there was anything specifying that "the comparison would have *undefined* behaviour" before CWG2526.
[Bug libstdc++/106547] std::variant::emplace goes into an infinite recursion with certain weird trivially copyable types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106547 --- Comment #3 from Jiang An --- (In reply to Valentine Anderson from comment #2) > From what I understand, the key feature of trivially copyable types is that > memcpy‘ing an object of such a type onto another object is equivalent to a > copy assignment. So it is possible to trivially copy such an object, using > memcpy. The current standard wording only guarantees that such copy is OK when the destination object is already created. A trivially copyable class is usually also an implicit-lifetime class, so memcpy is usually sufficient to create that object. But there're also weird trivially copyable class that is not an implicit-lifetime class (e.g. the class may have deleted copy/move ctors and trivial assignment operators). Moreover, it doesn't seem suitable to use memcpy in the cases involved in this issue...
[Bug libstdc++/106547] std::variant::emplace goes into an infinite recursion with certain weird trivially copyable types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106547 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- Well, is_trivially_copyable looks like a red herring - it doesn't really mean that we can trivially copy such an object in some way.
[Bug libstdc++/111351] constexpr std::string objects permitted to escape constant evaluation when SSO
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111351 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #2 from Jiang An --- > This will result in user code which can be built or not based on whether > their string happens to fit within the SSO string length. I find that quite > unfortunate, since it is supposed to be an internal implementation > detail/optimization, and this makes it effectively part of the API that code > will grow to depend on. This comes from the nature of SSO and constexpr variables. I don't think it worthwhile to revert this PR (https://github.com/microsoft/STL/pull/1735) for MSVC STL - which makes the codes harder to understand and slows down the compilation. > As comparison, libc++ rejects all the above examples, by forcing the SSO-size > to zero in constant evaluation context, so that a pointer to an external > allocation is always used. libc++ is, unfortunately, currently unable to implement constexpr SSO, IIUC. I failed to find a constexpr-compatible way to determine libc++'s std::string is in short mode if the short mode were enabled in constant evaluation. (As a result, libc++'s string always uses long mode during constant evaluation.) https://github.com/llvm/llvm-project/blob/0954dc3fb9214b994623f5306473de075f8e3593/libcxx/include/string#L829-L837 Note that there's no tag outside of the union, so we can't know which variant member is active without causing constant evaluation failure - unless the mechanism of std::is_within_lifetime (https://wg21.link/p2641r4) gets implemented.
[Bug libstdc++/111358] libstdc++'s optional::and_then and optional::transform are not ADL-proof
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111358 --- Comment #1 from Jiang An --- Related issues: Monadic operations of expected are not ADL-proof per the uses of **this in [expected.object.monadic]. However, currently implementations make them ADL-proof by directly naming the union member, which is right IMO. P2407R5 (https://wg21.link/p2407r5) is changing value() to **this in [optional.monadic], which makes the monadic operations of optional not ADL-proof. I believe this is a mistake. I've mailed to LWG Chair to submit an LWG issue for these issues.
[Bug libstdc++/111358] New: libstdc++'s optional::and_then and optional::transform are not ADL-proof
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111358 Bug ID: 111358 Summary: libstdc++'s optional::and_then and optional::transform are not ADL-proof Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following program is incorrectly rejected when using libstdc++ (https://godbolt.org/z/eavTYjEdx): ``` #include namespace fvs { struct Foo {}; void operator*(std::optional) = delete; } int main() { std::optional{}.and_then( [](auto&&){ return std::optional{}; }); std::optional{}.transform( [](auto&&){ return 0; }); } ``` The reason of compilation error is that libstdc++ uses **this in and_then and transform functions, which triggers ADL and finds unwanted operator*(). These monadic operations are currently specified in [optional.monadic] with value(), so they should be ADL-proof.
[Bug c++/111299] lack of warning on dangling reference to temporary
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111299 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- > What ends up happening is that in order to bind x.value to the reference > parameter R&& r, we can't actually do that, so instead we create a temporary > initialized by copying x.value and we bind a reference to that temporary, > returning a Span pointing to... that. This looks like miscompilation. [[gnu::packed]] should have no effect here. Clang seemingly correctly compiles the function (https://godbolt.org/z/7x8fGcEM9).
[Bug libstdc++/111258] std::string cannot to be moved in constant evaluated expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111258 --- Comment #3 from Jiang An --- I've reduced the example and filed Bug 111284.
[Bug c++/111284] New: Some passing-by-value parameters are miscompiled since GCC 9
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111284 Bug ID: 111284 Summary: Some passing-by-value parameters are miscompiled since GCC 9 Product: gcc Version: 13.2.0 Status: UNCONFIRMED Keywords: accepts-invalid, rejects-valid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- GCC incorrectly rejects the following program since GCC 9 (https://godbolt.org/z/cGK1a1dqK): ``` class self_locator { public: self_locator() = default; constexpr self_locator(const self_locator&) noexcept : this_{this} {} constexpr self_locator& operator=(const self_locator&) noexcept { return *this; } constexpr bool valid() const noexcept { return this_ == this; } private: self_locator *this_ = this; }; constexpr bool demonstrator(self_locator x) noexcept { return x.valid(); } static_assert(demonstrator(self_locator{}), ""); static_assert([](self_locator x){ return x.valid(); }(self_locator{}), ""); ``` The `valid` member function should always return true. But if `self_locator` is passed by value, GCC can sometimes render the parameter in an inconsistent state (perhaps due to incorrect bitwise copy).
[Bug c++/111272] [13/14 Regression] Truncated error messages with -std=c++23 and -std=c++26
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111272 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #3 from Jiang An --- Due to P2448R2 (https://wg21.link/p2448r2), the posted example is totally valid since C++23.
[Bug libstdc++/111258] std::string cannot to be moved in constant evaluated expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111258 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #2 from Jiang An --- Perhaps this is a compiler bug and there's nothing wrong in the move constructor. GCC 13 also incorrectly rejects the following program (https://godbolt.org/z/Yn98KMKv5) ``` #include constexpr bool foo11(std::string s) { s.push_back('\0'); return true; } int main() { static_assert(foo11(std::string{})); } ``` with similar message: ``` : In function 'int main()': :12:24: error: non-constant condition for static assertion 12 | static_assert(foo11(std::string{})); | ~^~~ :12:24: in 'constexpr' expansion of 'foo11(std::__cxx11::basic_string())' :5:16: in 'constexpr' expansion of 's.std::__cxx11::basic_string::push_back(0)' /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/basic_string.h:1552:33: in 'constexpr' expansion of '((std::__cxx11::basic_string*)this)->std::__cxx11::basic_string::capacity()' :12:24: error: accessing 'std::__cxx11::basic_string_M_allocated_capacity' member instead of initialized 'std::__cxx11::basic_string_M_local_buf' member in constant expression Compiler returned: 1 ``` It seems that gcc currently miscompiles passing-by-value of non-trivially-copyable classes in constant evaluation.
[Bug c++/110342] [C++26] P2361R6 - Unevaluated strings
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110342 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #3 from Jiang An --- It seems that the paper also makes the GNU assembly syntax conforming. Should we make some other changes?
[Bug libstdc++/100249] missing forwarding std::__invoke result in ranges::is_permutation and ranges::clamp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100249 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #13 from Jiang An --- This is not completely fixed. See - https://github.com/microsoft/STL/issues/3970#issuecomment-1681524306 - https://gcc.godbolt.org/z/3fsdbTx5Y
[Bug c++/106094] Lifetime extension of temporary do not obey some rules of [class.temporary]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106094 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #6 from Jiang An --- CWG2666 may be related. https://cplusplus.github.io/CWG/issues/2666.html
[Bug c++/110981] New: constexpr variable definition that requires dynamic destruction should be rejected
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110981 Bug ID: 110981 Summary: constexpr variable definition that requires dynamic destruction should be rejected Product: gcc Version: 13.2.1 Status: UNCONFIRMED Keywords: accepts-invalid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following program is accepted by GCC and results in dynamic destruction codes (because the lifetime-extended unique_ptr temporary object is not trivially destructible and has no constant destruction) (https://godbolt.org/z/8e9Y9E9jf): ``` #include constexpr std::unique_ptr&& r = {}; int main() { r = std::make_unique(42); } ``` I think we should reject the definition of r due to CWG2529 (https://cplusplus.github.io/CWG/issues/2529.html). Also, a slightly different example is also currently accepted by GCC (https://godbolt.org/z/1rf768aKs): ``` #include struct S { std::unique_ptr&& r; }; constexpr S s{{}}; int main() { s.r = std::make_unique(42); } ``` This seemly also needs to be rejected, although there's an open CWG issue (https://cplusplus.github.io/CWG/issues/2702.html). The rationale should be that - every lifetime-extended temporary object created in the initialization of a constexpr variable needs to have constant destruction, and - such a non-const temporary object is not usable in constant expressions, so lvalue-to-rvalue conversion from any of its subobjects makes the destruction non-constant.
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #15 from Jiang An --- (In reply to Arthur O'Dwyer from comment #11) > @jwakely, I propose that this issue should be recategorized as a compiler > bug. (And I'm also voting effectively "NAD" on LWG3967.) Hmm... IMO given the current specification seems to be ambiguous, the status quo of GCC's __is_nothrow_* can be considered conforming even though they're obviously buggy (inconsistent).
[Bug c++/110912] False assumption that constructors cannot alias any of their parameters
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110912 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- The restriction agains aliasing was intended, see https://cplusplus.github.io/CWG/issues/2271.html. The status quo seems to be that in the body of `A::A(int )`, compilers can assume that the value of `x` won't be changed by a modification on `*this`, but not the other way around.
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #10 from Jiang An --- https://cplusplus.github.io/LWG/issue3967
[Bug libstdc++/110854] constructor of std::counting_semaphore is not constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110854 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #2 from Jiang An --- The constructor of the internal __platform_semaphore class currently calls sem_init, which make it incompatible with constexpr...
[Bug libstdc++/106611] std::is_nothrow_copy_constructible returns wrong result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 --- Comment #9 from Jiang An --- (In reply to Nikolas Klauser from comment #8) > I agree that the wording is a bit ambiguous, but GCC should decide on one > of them instead of returning different results between the type trait > builtins and the noexcept operator. The result of noexcept operator is unambiguously specified in the standard and GCC is already correct. So the suggestion is equivalent to detecting the exception specifications only. I've mailed the LWG Chair to submit an LWG issue that requests clarification of "is known not to throw any exceptions". FYI, there's at least one library implementor holding the same opinion as yours. https://quuxplusone.github.io/blog/2023/04/17/noexcept-false-equals-default/
[Bug c++/110822] [13/14 Regression] ICE on constexpr initialized with non-constant expression also accepts-invalid
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110822 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #3 from Jiang An --- This example is valid (or should be) for libstdc++. Given `constexpr std::string text = "Some text here"s;` in namespace scope ("being a global variable"), the std::string object, which has static storage duration, contains a pointer to its subobject, and doesn't hold any pointer to a dynamically allocated storage. Clang complains that the _M_construct function is not defined at the call point so a call to it should make constant evalution fail. _M_construct is actually defined later (in basic_string.tcc IIUC). There's an unreolved CWG issue about this. https://cplusplus.github.io/CWG/issues/2166.html
[Bug c++/108626] GCC doesn't deduplicate string literals for const char*const and const char[]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108626 --- Comment #9 from Jiang An --- See also CWG2753. https://cplusplus.github.io/CWG/issues/2753.html
[Bug c++/104095] g++ diagnosis may use non-standard terminology: "constant" instead of "literal", "integer" instead of "integral"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104095 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #2 from Jiang An --- C standard says "floating constant" while C++ standard says "floating-point literal". I wonder whether it makes sense for gcc to say different standardese terms for C and C++...
[Bug c++/110661] New: Weird handing for deleting a void* pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110661 Bug ID: 110661 Summary: Weird handing for deleting a void* pointer Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: accepts-invalid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- GCC accepts the following code snipped and says that " warning: deleting 'void*' is undefined". Godbolt link: https://godbolt.org/z/xKWTGrfPc ``` constexpr int test_delete_pvoid() { delete static_cast(new int); return 0; } constexpr int n = test_delete_pvoid(); ``` It's contradictory that GCC considers this undefined but accepts it in constant evaluation. Moreover, https://eel.is/c++draft/expr.delete#1 seemingly states that deleting a void* pointer is ill-formed.
[Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #4 from Jiang An --- (In reply to Andrew Pinski from comment #1) > I would have expected this to be undefined ... > So the static_assert could work or not. If this were undefined (not true IIUC), static_assert would be required not to work because the condition expression is not a constant expression ([expr.const]/5.8). We should keep in mind that all kinds of core UB that may occur within (tentative) constant evaluation (except for violation of [[assume]], currently) are not totally undefined, since they must cause constant evaluation failure. CWG issue should be submitted if such detection is unimplementable.
[Bug c++/110581] Weird error message for returning from a [[noreturn]] function in constant evaluation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110581 --- Comment #1 from Jiang An --- > We should say something about `[[noreturn]]` insead superfluous `volatile`. should be > We should say something about `[[noreturn]]` instead of superfluous > `volatile`. Sorry for copy-pasta...
[Bug c++/110581] New: Weird error message for returning from a [[noreturn]] function in constant evaluation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110581 Bug ID: 110581 Summary: Weird error message for returning from a [[noreturn]] function in constant evaluation Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- GCC rejects the following code snippet since GCC14, which is correct because the code raises UB in constant evaluation (https://godbolt.org/z/neP1MKnxY) [[noreturn]] constexpr void unreachable_like() {} constexpr int x = (unreachable_like(), 0); However, the current error message is weird and possibly misleading: > error: lvalue-to-rvalue conversion of a volatile lvalue 'unreachable_like' > with type 'void()' We should say something about `[[noreturn]]` insead superfluous `volatile`.
[Bug libstdc++/109941] [feat req] Add an option to mark STL types as nodiscard
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109941 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- FYI MSVC STL currently applies [[nodiscard]] to std::lock_guard and std::scoped_lock.
[Bug libstdc++/109922] : consider removing operator>> for istream >> setfill(c)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109922 --- Comment #3 from Jiang An --- > setfill and its friends I was wrong. Only setfill itself is so relaxed.
[Bug libstdc++/109922] : consider removing operator>> for istream >> setfill(c)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109922 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #2 from Jiang An --- In some prehistoric working drafts, several manipulators were required to return a single smanip type, and only the common base class (ios_base, or ios in earlier drafts) is used in the wording (e.g. https://open-std.org/JTC1/SC22/WG21/docs/wp/html/jun96/lib-iostreams.html), which made them usable with both both input and output. The requirements was removed by N0958 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/1996/N0958.pdf), and then setfill and its friends are only required to be usable with operator<<.
[Bug c++/109459] static_assert with operator""s causes internal compiler error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109459 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- Seems fixed recently: https://gcc.godbolt.org/z/zTWoT4rsY
[Bug libstdc++/109383] New: [QoI] std::type_index::operator<=> should not call __builtin_strcmp twice
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109383 Bug ID: 109383 Summary: [QoI] std::type_index::operator<=> should not call __builtin_strcmp twice Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The current the current implementation of type_index::operator<=> in libstdc++ is the following: ``` strong_ordering operator<=>(const type_index& __rhs) const noexcept { if (*_M_target == *__rhs._M_target) return strong_ordering::equal; if (_M_target->before(*__rhs._M_target)) return strong_ordering::less; return strong_ordering::greater; } ``` When the two referenced type_info are not equal, the current implementation may needed to call __builtin_strcmp twice (each in type_info::operator== and type_info::before). IIUC whenever it's necessary to call __builtin_strcmp from operator<=>, we should just call it once and return __builtin_strcmp(...) <=> 0. Perhaps it would be better to add a member function to type_info for convenience. It's a bit strange to me that while all implementations I investigated (libc++, libstdc++, and msvc stl) need to use strcmp/__builtin_strcmp for type_info comparison in some cases, currently none of them avoids calling it twice from type_index::operator<=>, although strcmp/__builtin_strcmp is already performing three-way comparison.
[Bug c++/109243] New: Side cast of pointer-to-member with UB is incorrectly accepted in constant evaluation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109243 Bug ID: 109243 Summary: Side cast of pointer-to-member with UB is incorrectly accepted in constant evaluation Product: gcc Version: 13.0 Status: UNCONFIRMED Keywords: accepts-invalid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following code snippet is incorrectly accepted by gcc (perhaps in all versions supporting constexpr) (Godbolt link: https://godbolt.org/z/GqodcGWPe): ``` struct B1 { char i; }; struct B2 { char j; }; struct D : B1, B2 {}; constexpr auto mp = static_cast(static_cast(::i)); ``` According to [expr.static.cast]/13, such static_cast (performing side cast) has undefined behavior, and should not be accepted as a constant (sub)expression. (Unfortunately, there're well-defined manners to create a non-null pointer-to-member with offset -1, see https://github.com/itanium-cxx-abi/cxx-abi/pull/163).
[Bug libstdc++/109203] sort(zip(v1, v2)) fails to compile
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109203 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #6 from Jiang An --- libstdc++ has (unfortunately?) implemented the tuple-or-pair strategy in P2321. The strategy is dropped by P2165. It seems that if std::tuple is unconditionally used, this issue will be resolved. This issue will also be resolved once LWG3865 gets implemented.
[Bug c++/70476] C++11: Function name declared in unnamed namespace extern "C" gets exernal linkage
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70476 --- Comment #15 from Jiang An --- (In reply to Maciej S. Szmigiero from comment #14) > > This is not so useful in practice because most compilers don't make extern > > "C" and extern "C++" differentiate function types (implying calling > > conventions etc.). > > The standard allows different calling conventions for "C" and "C++" language > linkage and that's what matters when writing standard-compliant code - one > shouldn't write to a particular implementation (or implementations). > The problem in pratice is that most implementations are not standard-compliant here. If you rely on the standard guarantee that extern "C" and extern "C++" make function types different, you probably get compilation errors. > > > All functions and variables whose names have external linkage and all > > > function types have a language linkage. > > > > which implies that a function with internal linkage doesn't have a language > > > linkage, and thus [dcl.link]/7 doesn't apply to it. > > Nothing in the above quote says that *only* these specified have a language > linkage, just that these explicitly enumerated sure do. I think the italic style is "the thing", which should mean that the term "language linkage" is introduced and restricted here.
[Bug c++/70476] C++11: Function name declared in unnamed namespace extern "C" gets exernal linkage
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70476 --- Comment #13 from Jiang An --- (In reply to Maciej S. Szmigiero from comment #11) > (In reply to Andrew Pinski from comment #9) > > Does these two functions the same name then? > > ``` > > namespace a { > >extern "C" void f(void); > > } > > > > namespace { > > extern "C" void f(void) {} > > } > > > > void g(void) > > { > > f(); > > a::f(); > > } > > > > ``` > > It seems counter intuitive that a::f and the ::f map to different functions. > > According to [dcl.link] "Two declarations for a function with C language > linkage with the same function name (ignoring the namespace names that > qualify it) that > appear in different namespace scopes refer to the same function", so it > would seem that both refer to the same function indeed. > > > Here is an example where GCC produces an assembly failure: > > > > namespace a { > >extern "C" void f(void){} > > } > > > > namespace { > > extern "C" void f(void) {} > > } > > If they are the same function then this shouldn't work (it would be a > re-definition). Oh, I think they shouldn't be the same function. [dcl.link]/1 says: > All functions and variables whose names have external linkage and all > function types have a language linkage. which implies that a function with internal linkage doesn't have a language linkage, and thus [dcl.link]/7 doesn't apply to it.
[Bug c++/70476] C++11: Function name declared in unnamed namespace extern "C" gets exernal linkage
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70476 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #12 from Jiang An --- It seems that the current specification is still broken for extern "C" functions with internal linkage.(In reply to Maciej S. Szmigiero from comment #8) > Having functions with "C" language linkage (calling convention, etc) but > internal linkage is useful for writing callbacks provided to C functions. > > It's not an significant issue, however, as one can get the same effect by > declaring the callback function "static" inside an "extern C" block. This is not so useful in practice because most compilers don't make extern "C" and extern "C++" differentiate function types (implying calling conventions etc.). There's a long battle story, and the divergence between the standard and implementations is not resolved yet. See https://cplusplus.github.io/CWG/issues/1555.html https://lists.isocpp.org/sg12/2020/04/0900.php
[Bug libstdc++/109049] std::declval gives wrong result for cv void
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109049 --- Comment #3 from Jiang An --- I've mailed to LWG Chair to request legitimation of libc++ and libstdc++'s current strategy.
[Bug c++/95701] undefined enum conversion accepted in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95701 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #2 from Jiang An --- This is CWG1766. https://cplusplus.github.io/CWG/issues/1766.html Clang implemented the required constant evaluation failures recently, but seemly decided to keep the behavior outside of constant evaluation unchanged. https://reviews.llvm.org/D130058 https://reviews.llvm.org/D131307 https://reviews.llvm.org/D131528
[Bug libstdc++/109024] [C++23][ranges][repeat_view] The default ctor unuseable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109024 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #1 from Jiang An --- See https://cplusplus.github.io/LWG/issue3796. We need to implement the resolution.
[Bug libstdc++/108974] std::barrier except completion function which is not manifestly noexcept
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108974 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #3 from Jiang An --- > is_nothrow_invocable_v shall be true. If implementation divergence is not intendedly permitted, I don't think it makes much sense to introduce UB in this way. I guess we should either turn it into a mandating requirement: > Instantiation of barrier is ill-formed > if is_nothrow_invocable_v is not true. Or relax the preconditions: > If any invocation to the completion function throws an exception, > the behavior is undefined. I've mailed to LWG Chair for this...
[Bug libstdc++/108846] std::copy, std::copy_n on potentially overlapping subobjects
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108846 --- Comment #6 from Jiang An --- > For example, assuming both sizeof(B) and sizeof(D) are 8, which means the last > 2 bytes of B are padding (true for common implementations on Itanium ABI): Oh, I forgot the strange design caused by CWG43 - this requires some non-C++98-POD mechanism for B (e.g. an explicitly default default constructor)...
[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #8 from Jiang An --- This seems a bug, not merely missing of optimization. The string_view object should always be statically initialized, because it has static storage duration and its initializer is a constant iniitializer.
[Bug libstdc++/108846] std::copy, std::copy_n on potentially overlapping subobjects
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108846 Jiang An changed: What|Removed |Added CC||de34 at live dot cn --- Comment #4 from Jiang An --- (In reply to Andrew Pinski from comment #2) > Related to https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2403 > but instead of language, it is the library methods. CWG2403 looks like an unfortunate result of ABI design. If any non-padding byte of a potentially-overlapping subobject X is actually overlapping with a padding byte of subobject Y, Y should be initialized before X, because all bytes of Y may be written in initialization. However, on Itanium ABI virtual base class subobjects violate such intuitive rule. But I think it's only closedly related to uninitialized memory algorithms (which perform initialization instead of assignment), and there's already a note saying that it's UB to use them to initialize potentially-overlapping objects ([specialized.algorithms.general]/3). (In reply to Andrew Pinski from comment #3) > Even https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2544 is > very much related. (As the submitter) I think this issue only legitimates current implementation of pointer arithmetic. For example, assuming both sizeof(B) and sizeof(D) are 8, which means the last 2 bytes of B are padding (true for common implementations on Itanium ABI): struct B { int32_t x; int16_t y; }; struct D : B { int16_t z; }; The current wording in [basic.compound]/3 requires that given `B b{};` and `D d{};`, `static_cast() + 1` represents the address of the byte at offset 6, which is almost unimplementable. However, subtraction between pointers are performed as usual for even for potentially-overlapping subobjects, which is correctly implemented. In the case of copy family algorithms, I believe it's OK to specially handle cases where last - first == 1. BTW, there's CWG2527 that is closed as NAD, which seemingly means that an array subobject can be potentially-overlapping, even if element subobjects can't.