[Bug c++/111504] compare operator not defined for recursive data types on C++20

2023-09-22 Thread xgao at nvidia dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111504

--- Comment #3 from Xiang Gao  ---
Cross posted at: https://github.com/llvm/llvm-project/issues/67056

[Bug c++/111504] compare operator not defined for recursive data types on C++20

2023-09-20 Thread xgao at nvidia dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111504

--- Comment #2 from Xiang Gao  ---
(In reply to Andrew Pinski from comment #1)
> Fails for the same reason with clang (both with libstdc++ and libc++) 
> 
> Are you sure this is valid C++ 20 code?

I am not 100% sure, but my understanding is, for the SFINAE in
  inline constexpr bool operator<(const DT& x, const DT& y)
The first condition
  hasLessThan::value
is just hasLessThan::value, which should be true, and (true
|| anything) is always true.

So the condition in SFINAE should be easily evaluated as true. So the operator<
for DynamicType should be defined.

And if operator< is defined, then the operator<=> of std::vector
should also be defined. This can be validated by changing the definition of
operator< by only keeping the first condition:

template <
typename DT,
typename = std::enable_if_t<
(hasLessThan::value)>>
inline constexpr bool operator<(const DT& x, const DT& y) {
  // implementation omitted
  return true;
}

and then both g++ and clang++ will pass.

I do observe the same error on clang, but this https://cpp.sh/ seems to compile
without problem on C++20.

[Bug c++/111504] New: compare operator not defined for recursive data types on C++20

2023-09-20 Thread xgao at nvidia dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111504

Bug ID: 111504
   Summary: compare operator not defined for recursive data types
on C++20
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xgao at nvidia dot com
  Target Milestone: ---

Related bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111316

The following code works on C++17 but not C++20:

#include 
#include 
#include 

template 
static auto hasLessThanHelper(int)
-> decltype(std::declval() < std::declval(), std::true_type{});

template 
static auto hasLessThanHelper(long) -> std::false_type;

template 
struct hasLessThan : decltype(hasLessThanHelper(0)) {};

struct DynamicType {
  using T1 = int64_t;
  using T2 = std::vector;
};

template <
typename DT,
typename = std::enable_if_t<
(hasLessThan::value ||
 hasLessThan::value ||
 hasLessThan::value ||
 hasLessThan::value)>>
inline constexpr bool operator<(const DT& x, const DT& y) {
  // implementation omitted
  return true;
}

int main() {
  using DT = DynamicType;
  // This assert works on C++17, but fails on C++20
  static_assert(hasLessThan, std::vector>::value);
}

[Bug c++/111316] New: std::vector's operator < does not work with recursive data type

2023-09-06 Thread xgao at nvidia dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111316

Bug ID: 111316
   Summary: std::vector's operator < does not work with recursive
data type
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xgao at nvidia dot com
  Target Milestone: ---

Created attachment 55847
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55847=edit
minimum repro

The attached minimal repro does not work on g++ on C++20, but it works with g++
on C++17 and clang++ on both C++17 and C++20. See the code for detail:

Error message:

/usr/include/c++/13.2.1/compare:1216:18: error: satisfaction of atomic
constraint ‘requires{{__t < __u} -> decltype(auto) [requires
std::__detail::__boolean_testable<, >];{__u < __t} ->
decltype(auto) [requires std::__detail::__boolean_testable<, >];}
[with _Tp = _Tp; _Up = _Up]’ depends on itself

[Bug c++/111314] New: Can not deduct parameter pack as a single type

2023-09-06 Thread xgao at nvidia dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111314

Bug ID: 111314
   Summary: Can not deduct parameter pack as a single type
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xgao at nvidia dot com
  Target Milestone: ---

The following code does not work:

#include 

template 
struct Template {};

template  typename, typename>
struct DynamicType {};

template 
struct is_dynamic_type : std::false_type {};

template  typename Template, typename... Ts>
struct is_dynamic_type> : std::true_type {};

template 
constexpr bool is_dynamic_type_v = is_dynamic_type::value;

// This fails:
static_assert(is_dynamic_type_v>);

int main() {}

[Bug libstdc++/110594] New: std::variant's converting constructor does not resolve alternative correctly

2023-07-08 Thread xgao at nvidia dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110594

Bug ID: 110594
   Summary: std::variant's converting constructor does not resolve
alternative correctly
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xgao at nvidia dot com
  Target Milestone: ---

Created attachment 55502
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55502=edit
minimum repro

According to https://en.cppreference.com/w/cpp/utility/variant/variant, I would
expect the attached program to output:

int64_t: 1
variant is int

However, I am getting:

int64_t: 1
variant is complex

gcc-9 seems to have the correct behavior for the attached program, however, the
implementation of std::variant in gcc-9 has another problem that the following
example in that cppreference.com page does not work:

std::variant z = 0; // OK, holds long
 // float and double are not candidates

Thanks to the help of jjsjann123 (https://github.com/jjsjann123), this is
potentially related to the SFINAE in the "variant" header:

  // Helper used to check for valid conversions that don't involve narrowing.
  template struct _Arr { _Ti _M_x[1]; };

seems that this will block int64_t from being selected as shown in
https://godbolt.org/z/Gcr4j53rd. However, the following code is totally valid:

int64_t x[] = {size_t(1)};

so probably that SFINAE might be wrong.