[Bug c++/112769] ICE on valid code related to requires-expression

2023-11-30 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112769

--- Comment #1 from janpmoeller at gmx dot de ---
The following equivalent program does not trigger the ICE:

//
template
concept C = requires (U u) { T{u}; };

template
struct type
{
constexpr explicit type(T value)
{
}

template
constexpr explicit type(type value)
requires C>
{
}
};

template 
using alias = type<0, T>;

constexpr alias foo{123};
//

[Bug c++/112769] New: ICE on valid code related to requires-expression

2023-11-29 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112769

Bug ID: 112769
   Summary: ICE on valid code related to requires-expression
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: janpmoeller at gmx dot de
  Target Milestone: ---

All gcc versions since (and including) 11.2 reject the following valid C++20
code:

//
template
struct type
{
constexpr explicit type(T value)
{
}

template
constexpr explicit type(type value)
requires requires { T{value}; }
{
}
};

template 
using alias = type<0, T>;

constexpr alias foo{123};
//


The reported error is:

##
:11:18: internal compiler error: in add_outermost_template_args, at
cp/pt.cc:617
   11 | requires requires { T{value}; }
  |  ^~
0x1ce7bde internal_error(char const*, ...)
???:0
0x7290fc fancy_abort(char const*, int, char const*)
???:0
0x7879b6 tsubst_requires_expr(tree_node*, tree_node*, int, tree_node*)
???:0
0x783c90 tsubst_constraint(tree_node*, tree_node*, int, tree_node*)
???:0
0x783df1 tsubst_constraint_info(tree_node*, tree_node*, int, tree_node*)
???:0
0x8b1e90 do_auto_deduction(tree_node*, tree_node*, tree_node*, int,
auto_deduction_context, tree_node*, int, tree_node*)
???:0
0x7ccd01 cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int)
???:0
0x89fd5b c_parse_file()
???:0
0x98c5d9 c_common_parse_file()
???:0
Please submit a full bug report, with preprocessed source.
Please include the complete backtrace with any bug report.
See  for instructions.
Preprocessed source stored into /tmp/cclpGAjI.out file, please attach this to
your bugreport.
Compiler returned: 1
##

gcc-11.1 accepts the code.Here is a link to compiler explorer with the same
example: https://godbolt.org/z/aq1d53anv

Note that the first (non-template) constructor is required to make the code
valid, but it is not required to reproduce the issue. Removing it still leads
to the same ICE on gcc > 11.1, whereas gcc-11.1 (correctly) rejects it due to
failed argument deduction.

[Bug c++/108934] New: bit_cast'ing to long double errors out with "the argument cannot be interpreted" since gcc-12

2023-02-25 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108934

Bug ID: 108934
   Summary: bit_cast'ing to long double errors out with "the
argument cannot be interpreted" since gcc-12
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: janpmoeller at gmx dot de
  Target Milestone: ---

In gcc-trunk, gcc-12.2 and gcc-12.1, the following code fails to compile, while
gcc-11.3 accepts it:

/
#include 
#include 
#include 

using uint64_x_2_t = std::array;
using uint32_x_2_t = std::array;
using uint16_x_2_t = std::array;

static_assert(sizeof(long double) == sizeof(uint64_x_2_t));
static_assert(sizeof(double) == sizeof(uint32_x_2_t));
static_assert(sizeof(float) == sizeof(uint16_x_2_t));

constexpr long double testld = 42.42;
constexpr double testd = 42.42;
constexpr float testf = 42.42f;

constexpr uint64_x_2_t test_uint64_x_2_t{1u, 2u};
constexpr uint32_x_2_t test_uint32_x_2_t{1u, 2u};
constexpr uint16_x_2_t test_uint16_x_2_t{1u, 2u};

constexpr auto ld_to_uint64_x_2_t = std::bit_cast(testld); //
works! (reverse direction)
constexpr auto d_to_uint32_x_2_t = std::bit_cast(testd);
constexpr auto f_to_uint16_x_2_t = std::bit_cast(testf);

constexpr auto default_uint64_x_2_t_to_ld = std::bit_cast(uint64_x_2_t{}); // works! (default initialized)
constexpr auto default_uint32_x_2_t_to_d =
std::bit_cast(uint32_x_2_t{});
constexpr auto default_uint16_x_2_t_to_f =
std::bit_cast(uint16_x_2_t{});

constexpr auto temp_uint64_x_2_t_to_ld = std::bit_cast(uint64_x_2_t{1u, 2u}); // <= fails
constexpr auto temp_uint32_x_2_t_to_d = std::bit_cast(uint32_x_2_t{1u,
2u});
constexpr auto temp_uint16_x_2_t_to_f = std::bit_cast(uint16_x_2_t{1u,
2u});

constexpr auto uint64_x_2_t_to_ld = std::bit_cast(test_uint64_x_2_t); // <= fails
constexpr auto uint32_x_2_t_to_d = std::bit_cast(test_uint32_x_2_t);
constexpr auto uint16_x_2_t_to_f = std::bit_cast(test_uint16_x_2_t);
/

The compile error for both offending lines is:
/usr/include/c++/12/bit:87:33: sorry, unimplemented: ‘__builtin_bit_cast’
cannot be constant evaluated because the argument cannot be interpreted

The strange thing is that this error only seems to appear if the array is
aggregate-initialized; default initialized arrays do not trigger the error.
float and double do not trigger the error either. Replacing std::array with a
struct aggregate type behaves the same as the array example above.

The reverse direction, i.e. bit_cast'ing from long double to array, seems to be
working fine.

The above example on compiler explorer: https://godbolt.org/z/ba5d6hEG1

[Bug c++/95298] [10/11/12/13 Regression] sorry, unimplemented: mangling record_type

2022-08-28 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95298

janpmoeller at gmx dot de changed:

   What|Removed |Added

 CC||janpmoeller at gmx dot de

--- Comment #6 from janpmoeller at gmx dot de ---
This still fails in 12.2 and recent trunk: https://godbolt.org/z/vebz3T6sh

I also encountered
- sorry, unimplemented: mangling reference_type
- sorry, unimplemented: mangling typename_type
on heavily templated code.

In the first case, transforming a function with signature
> template
> constexpr auto foo(Types&&... args) -> 
> tuple...>
into
> template
> constexpr auto foo(Types&&... args) -> decltype(auto)
made the compilation error go away.

In the second case, the similar transformation from
> template
> constexpr auto bar(Types&&... args) noexcept -> tuple
to
> template
> constexpr auto bar(Types&&... args) noexcept -> decltype(auto)
helped.

In a reduced example, I wasn't immediately able to reproduce the issue though.
If it helps, I will invest more time to reduce my failing code to a
reasonable-size reproduction.

[Bug c++/106174] New: c++20: compilation fails erroneously with "deallocation of already deallocated storage"

2022-07-03 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106174

Bug ID: 106174
   Summary: c++20: compilation fails erroneously with
"deallocation of already deallocated storage"
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: janpmoeller at gmx dot de
  Target Milestone: ---

The following c++20 source fails to compile on gcc 12.1 and current trunk:


#include 
#include 

struct test_vector
{
constexpr ~test_vector() noexcept
{
m_allocator.deallocate(m_begin, m_capacity);
}

constexpr test_vector(std::size_t n)
: m_begin(m_allocator.allocate(n))
, m_capacity(n)
{
}

constexpr test_vector(test_vector const& other)
: test_vector(other.m_capacity)
{
}

constexpr test_vector() = delete;
constexpr test_vector(test_vector&& other) noexcept = delete;
constexpr auto operator=(test_vector const& other) -> test_vector& =
delete;
constexpr auto operator=(test_vector&& other) noexcept -> test_vector& =
delete;

std::allocator m_allocator{};
int*m_begin;
std::size_t m_capacity;
};

static_assert( // This fails with "deallocation of already deallocated storage"
[]
{
std::array const values{test_vector(42)};
std::array const copy = values;
return true;
}());


The compiler outputs:
:46:6: error: non-constant condition for static assertion
   41 | []
  | ~~
   42 | {
  | ~ 
   43 | std::array const values{test_vector(42)};
  | ~
   44 | std::array const copy = values;
  | ~~~
   45 | return true;
  | 
   46 | }());
  | ~^~
In file included from
/opt/compiler-explorer/gcc-trunk-20220703/include/c++/13.0.0/memory:64,
 from :2:
:46:6:   in 'constexpr' expansion of '().()'
:46:5:   in 'constexpr' expansion of '((std::array*)(&
copy))->std::array::~array()'
/opt/compiler-explorer/gcc-trunk-20220703/include/c++/13.0.0/array:94:12:   in
'constexpr' expansion of '->test_vector::~test_vector()'
:8:31:   in 'constexpr' expansion of
'((test_vector*)this)->test_vector::m_allocator.std::allocator::deallocate(((test_vector*)this)->test_vector::m_begin,
((test_vector*)this)->test_vector::m_capacity)'
/opt/compiler-explorer/gcc-trunk-20220703/include/c++/13.0.0/bits/allocator.h:202:30:
error: deallocation of already deallocated storage
  202 | ::operator delete(__p);
  | ~^
Compiler returned: 1


Weirdly, the usage of std::array seems to be important here. I was unable to
reproduce this without the std::array. For example, the following variants
compile just fine:

// 1) This is accepted
test_vector const values(42);
test_vector const copy = values;

// 2) This is accepted
test_vector const values(42);
std::array const copy = {values};

// 3) This is accepted
std::array const values{test_vector(42)};
test_vector const copy = values[0];

The above test case is also available on compiler explorer:
https://godbolt.org/z/6xvx4fx6E

[Bug libstdc++/105440] New: c++20: std::string's destructor not a constant expression when it should

2022-04-30 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105440

Bug ID: 105440
   Summary: c++20: std::string's destructor not a constant
expression when it should
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: janpmoeller at gmx dot de
  Target Milestone: ---

The following valid c++20 program fails to compile on both gcc and clang when
compiled with libstdc++:

//
#include 
#include 

constexpr auto foo(char c){
std::array a{std::string{"foo"} + c};
return true;
}

static_assert(foo('a'));
//

The emitted error is:

//
:9:18: error: non-constant condition for static assertion
9 | static_assert(foo('a'));
  |   ~~~^
In file included from
/opt/compiler-explorer/gcc-trunk-20220430/include/c++/13.0.0/string:53,
 from :1:
:9:18:   in 'constexpr' expansion of 'foo(97)'
:7:1:   in 'constexpr' expansion of '(&
a)->std::array, 1>::~array()'
/opt/compiler-explorer/gcc-trunk-20220430/include/c++/13.0.0/array:99:12:   in
'constexpr' expansion of
'->std::__cxx11::basic_string::~basic_string()'
/opt/compiler-explorer/gcc-trunk-20220430/include/c++/13.0.0/bits/basic_string.h:795:19:
  in 'constexpr' expansion of
'((std::__cxx11::basic_string*)this)->std::__cxx11::basic_string::_M_dispose()'
/opt/compiler-explorer/gcc-trunk-20220430/include/c++/13.0.0/bits/basic_string.h:275:26:
error: '((& a) == )' is not a constant expression
  275 |   { return _M_data() == _M_local_data(); }
  |~~^~
Compiler returned: 1
//

The same program compiles with libc++, and on msvc. Also see the following
godbolt link for comparison:
https://godbolt.org/z/zfn1Pr7P1

[Bug c++/101315] C++20 lambdas in unevaluated context: erroneously fails with "incomplete type"

2021-07-08 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101315

--- Comment #1 from janpmoeller at gmx dot de ---
Just for reference, the clang bug report is
https://bugs.llvm.org/show_bug.cgi?id=51032.

[Bug c++/101315] New: C++20 lambdas in unevaluated context: erroneously fails with "incomplete type"

2021-07-04 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101315

Bug ID: 101315
   Summary: C++20 lambdas in unevaluated context: erroneously
fails with "incomplete type"
   Product: gcc
   Version: 11.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: janpmoeller at gmx dot de
  Target Milestone: ---

gcc 11.1 and gcc (trunk) fail to compile the following code with --std=c++20:

(1)

#include 
#include 

template  Fn>
struct foo_t {
  foo_t(Ptr ptr) {}
};

template 
using alias = foo_t;

template 
auto fun(T const& t) {
  return alias{t};
}

int main() {
  std::vector v;
  auto const error = fun(v);
}


Both versions of gcc state:

: In function 'int main()':
:19:14: error: 'const void error' has incomplete type
   19 |   auto const error = fun(v);
  |  ^
Compiler returned: 1

The issue seems to somehow be related to the alias. Replacing the definition of
fun() with this code results in successful compilation:
(2)

template 
auto fun(T const& t) {
  return foo_t{t};
}


Specifying the return type of fun() explicitly results in a different error:
(3)

template 
auto fun(T const& t) -> alias {
  return alias{t};
}

: In function 'int main()':
:19:22: error: 'fun' was not declared in this scope
   19 |   auto const error = fun(v);
  |  ^~~
Compiler returned: 1

I believe all three variants to be valid c++20.

clang (trunk) compiles versions (1) and (2) of the code, (3) results in a
frontend crash (I'm going to file a bug report against clang for that as well.
I'll comment it here for reference after I'm done).
Also see this link to godbolt: https://godbolt.org/z/r9GMfxzEo

[Bug c++/97751] New: C++20 NTTP: class template argument deduction failed

2020-11-07 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97751

Bug ID: 97751
   Summary: C++20 NTTP: class template argument deduction failed
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: janpmoeller at gmx dot de
  Target Milestone: ---

The following code results in a hard compile error in gcc-10.2 and the latest
trunk:

/
template 
struct use_as_nttp {};

template 
struct has_nttp {};

template 
using has_nttp_2 = has_nttp;
/

This is the output:

#
:8:34: error: class template argument deduction failed:
8 | using has_nttp_2 = has_nttp;
  |  ^
:8:34: error: no matching function for call to
'use_as_nttp(use_as_nttp<...auto...>)'
:2:8: note: candidate: 'template use_as_nttp()-> use_as_nttp'
2 | struct use_as_nttp {};
  |^~~
:2:8: note:   template argument deduction/substitution failed:
:8:34: note:   candidate expects 0 arguments, 1 provided
8 | using has_nttp_2 = has_nttp;
  |  ^
:2:8: note: candidate: 'template use_as_nttp(use_as_nttp)->
use_as_nttp'
2 | struct use_as_nttp {};
  |^~~
:2:8: note:   template argument deduction/substitution failed:
:8:34: note:   mismatched types 'use_as_nttp' and
'use_as_nttp<...auto...>'
8 | using has_nttp_2 = has_nttp;
  |  ^
Compiler returned: 1
#

gcc was invoked with "-std=c++20 -Wall -Wextra -Wpedantic". The error can also
be observed on compiler explorer: https://godbolt.org/z/xbPrjj

I believe that this is valid C++20 and should compile (but not generate any
assembly, since none of the types are actually instantiated).

[Bug c++/97749] New: ICE: Segmentation Fault on C++20 NTTP

2020-11-06 Thread janpmoeller at gmx dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97749

Bug ID: 97749
   Summary: ICE: Segmentation Fault on C++20 NTTP
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: janpmoeller at gmx dot de
  Target Milestone: ---

The following code results in an ICE when compiled with gcc-10.2 or the latest
trunk:

/
#include 
#include 

template
struct fixed_string
{
char buf[N + 1]{};
constexpr fixed_string(char const* s) { std::copy_n(s, N, buf); }
constexpr operator char const *() const { return buf; }
constexpr operator std::string_view() const { return buf; }
};
template
fixed_string(char const (&)[N]) -> fixed_string;

template
struct foo;

template
struct bar;

template
struct bar>
{};

int main()
{
bar> foobar;
}
/

This is the output:

#
:22:24: internal compiler error: Segmentation fault
   22 | struct bar>
  |^~~
0x1be3959 internal_error(char const*, ...)
???:0
0x6ad485 resolve_args(vec*, int)
???:0
0x89f9af do_auto_deduction(tree_node*, tree_node*, tree_node*, int,
auto_deduction_context, tree_node*, int)
???:0
0x8bf5ac lookup_template_class(tree_node*, tree_node*, tree_node*, tree_node*,
int, int)
???:0
0x91439d finish_template_type(tree_node*, tree_node*, int)
???:0
0x87a2ac c_parse_file()
???:0
0x9f0f52 c_common_parse_file()
???:0
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See  for instructions.
ASM generation compiler returned: 1
#

gcc was invoked with "-std=c++20 -Wall -Wextra -Wpedantic". The error can also
be observed on compiler explorer: https://godbolt.org/z/7abb75

I believe that this is valid C++20 and should compile.