[Bug libstdc++/115099] compilation error: format thread::id

2024-05-16 Thread de34 at live dot cn via Gcc-bugs
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

2024-05-13 Thread de34 at live dot cn via Gcc-bugs
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

2024-05-12 Thread de34 at live dot cn via Gcc-bugs
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

2024-04-30 Thread de34 at live dot cn via Gcc-bugs
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

2024-04-29 Thread de34 at live dot cn via Gcc-bugs
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

2024-04-28 Thread de34 at live dot cn via Gcc-bugs
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

2024-04-25 Thread de34 at live dot cn via Gcc-bugs
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

2024-04-23 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-28 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-27 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-26 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-21 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-20 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-20 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-19 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-19 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-19 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-19 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-19 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-18 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-16 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-14 Thread de34 at live dot cn via Gcc-bugs
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

2024-03-03 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-29 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-23 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-23 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-23 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-23 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-21 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-21 Thread de34 at live dot cn via Gcc-bugs
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?

2024-02-19 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-19 Thread de34 at live dot cn via Gcc-bugs
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?

2024-02-19 Thread de34 at live dot cn via Gcc-bugs
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?

2024-02-19 Thread de34 at live dot cn via Gcc-bugs
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?

2024-02-19 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-09 Thread de34 at live dot cn via Gcc-bugs
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

2024-02-05 Thread de34 at live dot cn via Gcc-bugs
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

2024-01-28 Thread de34 at live dot cn via Gcc-bugs
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

2024-01-28 Thread de34 at live dot cn via Gcc-bugs
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

2024-01-25 Thread de34 at live dot cn via Gcc-bugs
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?

2024-01-17 Thread de34 at live dot cn via Gcc-bugs
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

2024-01-03 Thread de34 at live dot cn via Gcc-bugs
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

2023-12-25 Thread de34 at live dot cn via Gcc-bugs
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

2023-12-21 Thread de34 at live dot cn via Gcc-bugs
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

2023-12-18 Thread de34 at live dot cn via Gcc-bugs
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

2023-12-18 Thread de34 at live dot cn via Gcc-bugs
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

2023-11-08 Thread de34 at live dot cn via Gcc-bugs
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

2023-11-08 Thread de34 at live dot cn via Gcc-bugs
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

2023-10-16 Thread de34 at live dot cn via Gcc-bugs
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

2023-10-08 Thread de34 at live dot cn via Gcc-bugs
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

2023-10-07 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-28 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-21 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-21 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-21 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-21 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-11 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-11 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-11 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-11 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-10 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-10 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-05 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-04 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-04 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-04 Thread de34 at live dot cn via Gcc-bugs
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

2023-09-01 Thread de34 at live dot cn via Gcc-bugs
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

2023-08-24 Thread de34 at live dot cn via Gcc-bugs
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

2023-08-19 Thread de34 at live dot cn via Gcc-bugs
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]

2023-08-11 Thread de34 at live dot cn via Gcc-bugs
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

2023-08-10 Thread de34 at live dot cn via Gcc-bugs
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

2023-08-08 Thread de34 at live dot cn via Gcc-bugs
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

2023-08-07 Thread de34 at live dot cn via Gcc-bugs
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

2023-08-06 Thread de34 at live dot cn via Gcc-bugs
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

2023-08-03 Thread de34 at live dot cn via Gcc-bugs
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

2023-08-03 Thread de34 at live dot cn via Gcc-bugs
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

2023-07-28 Thread de34 at live dot cn via Gcc-bugs
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[]

2023-07-23 Thread de34 at live dot cn via Gcc-bugs
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"

2023-07-23 Thread de34 at live dot cn via Gcc-bugs
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

2023-07-13 Thread de34 at live dot cn via Gcc-bugs
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

2023-07-11 Thread de34 at live dot cn via Gcc-bugs
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

2023-07-07 Thread de34 at live dot cn via Gcc-bugs
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

2023-07-07 Thread de34 at live dot cn via Gcc-bugs
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

2023-05-23 Thread de34 at live dot cn via Gcc-bugs
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)

2023-05-22 Thread de34 at live dot cn via Gcc-bugs
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)

2023-05-22 Thread de34 at live dot cn via Gcc-bugs
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

2023-04-09 Thread de34 at live dot cn via Gcc-bugs
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

2023-04-02 Thread de34 at live dot cn via Gcc-bugs
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

2023-03-21 Thread de34 at live dot cn via Gcc-bugs
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

2023-03-20 Thread de34 at live dot cn via Gcc-bugs
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

2023-03-13 Thread de34 at live dot cn via Gcc-bugs
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

2023-03-12 Thread de34 at live dot cn via Gcc-bugs
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

2023-03-12 Thread de34 at live dot cn via Gcc-bugs
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

2023-03-07 Thread de34 at live dot cn via Gcc-bugs
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

2023-03-06 Thread de34 at live dot cn via Gcc-bugs
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

2023-03-05 Thread de34 at live dot cn via Gcc-bugs
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

2023-03-01 Thread de34 at live dot cn via Gcc-bugs
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

2023-02-20 Thread de34 at live dot cn via Gcc-bugs
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*)

2023-02-20 Thread de34 at live dot cn via Gcc-bugs
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

2023-02-20 Thread de34 at live dot cn via Gcc-bugs
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.

  1   2   >