[Bug c/51971] unclear/unverified restrictions on attribute((const|pure))

2021-04-17 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51971

David Stone  changed:

   What|Removed |Added

 CC||davidfromonline at gmail dot 
com

--- Comment #4 from David Stone  ---
Here are more examples that are currently unclear:

```
struct a {
[[gnu::const]] a(): m(1) {}
int m;
};
```

If you think of a constructor as a function (that is named after the type) that
returns a value of that type, then the default constructor of `a` can safely be
marked `gnu::const`. If you think of a constructor as a member function that
gets a hidden `this` pointer passed in and then writes into that memory, then
the default constructor of `a` cannot even be marked `gnu::pure`.

```
struct b {
b(): m(1) {}
~b() {}
int m;
};

[[gnu::const]] b make_b() {
return b();
}
```

Because `b` is not trivially destructible, the Itanium ABI requires that the
return value passed by invisible reference. Here, whether it follows the
requirements of the attribute depend on the calling convention of your platform
if you take the "writing to memory in the return address is a side effect"
view.

The following function is not even `gnu::pure`, but it is not immediately
obvious why and the documentation should probably mention exception handling:

```
int c() {
try {
throw 1;
} catch(int) {
return 1;
}
}
```

The issue here is that `c()` could be called in a destructor, and that
destructor could be called during stack unwinding while handling another
exception (in which case `std::terminate()` is called rather than this function
returning 1).

Finally, the documentation is also not clear on what happens if you violate the
requirements. Richard Biener's comment suggests that you get some somewhat
unspecified result (some unspecified number of your calls might be replaced by
the result of another call), and what you are communicating to the compiler is
statements about whether side effects matter to you. Another possible
interpretation is that the behavior of the program is undefined on violation.
These are two very different models for what the attributes mean, but I suspect
only the "undefined behavior" model ends up actually being workable in the long
run. Consider the following code:

```
int d() {
int x;
std::vector temporary_buffer;
// do some work
return x;
}
```

>From the perspective of the world, this is logically `gnu::const`, assuming we
don't run out of memory. From the "You might get fewer calls and some of your
side effects might get discarded" model, I'm perfectly happy if the compiler
remembers this result of calling the function and doesn't allocate and
deallocate memory multiple times. My code doesn't handle `std::bad_alloc` so
I'm fine with it calling `std::terminate` in that rare case, but I'm also fine
with it not calling `std::terminate` in cases where I didn't have enough
memory, but the result was effectively cached by the compiler. I suspect this
will cause strange bugs in the optimizer if users adopt this model:

```
int e() {
// After some inlining
std::allocator::__some_internal_call();
d();
std::allocator::__some_other_internal_call();
}
```

These internal calls might expect consistent state of the allocator that can be
violated if `d` calls `allocate()`. It seems like a safer model to just come
right out and say that the behavior of your program is undefined if you violate
these requirements.

[Bug c/51971] unclear/unverified restrictions on attribute((const|pure))

2021-04-19 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51971

--- Comment #5 from David Stone  ---
After compiling this code

```
struct s {
s();
};

s::s() {}

s g() {
return s();
}
```

with `-O3 -Wsuggest-attribute=pure -Wsuggest-attribute=const`

I get the output

```
: In function 's g()':
:7:3: warning: function might be candidate for attribute 'const'
[-Wsuggest-attribute=const]
7 | s g() {
  |   ^
Compiler returned: 0
```

[Bug c++/100295] New: Internal compiler error from generic lambda capturing parameter pack and expanding it in if constexpr

2021-04-27 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100295

Bug ID: 100295
   Summary: Internal compiler error from generic lambda capturing
parameter pack and expanding it in if constexpr
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following well-formed translation unit

```
template
void f(Ts... ts) {
auto lambda = [=](auto x) {
if constexpr (sizeof((..., ts), x) != 0) {
(..., ts);
}
};
lambda(0);
}

void g() {
f(0);
}
```

causes gcc to crash with

```
: In instantiation of ‘f(int):: [with auto:1 =
int]’:
:8:8:   required from ‘void f(Ts ...) [with Ts = {int}]’
:12:3:   required from here
:5:31: internal compiler error: trying to capture ‘ts#0’ in
instantiation of generic lambda
5 | (..., ts);
  |   ^~
0x9c9318 add_capture(tree_node*, tree_node*, tree_node*, bool, bool)
../../source/gcc/cp/lambda.c:637
0x9c9391 add_default_capture(tree_node*, tree_node*, tree_node*)
../../source/gcc/cp/lambda.c:697
0xaa68ef tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
../../source/gcc/cp/pt.c:20834
0xaa3ea8 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
../../source/gcc/cp/pt.c:20949
0xaaf3d7 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../source/gcc/cp/pt.c:19204
0xaae9d1 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../source/gcc/cp/pt.c:18229
0xaae9d1 gen_elem_of_pack_expansion_instantiation
../../source/gcc/cp/pt.c:12568
0xaae9d1 tsubst_pack_expansion(tree_node*, tree_node*, int, tree_node*)
../../source/gcc/cp/pt.c:13233
0xaa163f tsubst_fold_expr_pack
../../source/gcc/cp/pt.c:12646
0xaa163f tsubst_unary_left_fold
../../source/gcc/cp/pt.c:12685
0xaa163f tsubst_copy
../../source/gcc/cp/pt.c:17343
0xaa56f2 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
../../source/gcc/cp/pt.c:20962
0xaaf3d7 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../source/gcc/cp/pt.c:19204
0xab11f9 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../source/gcc/cp/pt.c:18274
0xab0aa3 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../source/gcc/cp/pt.c:18595
0xab4503 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../source/gcc/cp/pt.c:18564
0xab0aa3 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../source/gcc/cp/pt.c:18595
0xab0aa3 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../source/gcc/cp/pt.c:18595
0xab8308 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../source/gcc/cp/pt.c:18229
0xab8308 instantiate_body
../../source/gcc/cp/pt.c:25921
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See  for instructions.
Compiler returned: 1
```

[Bug c++/100721] New: Warn when assigning to temporary

2021-05-21 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100721

Bug ID: 100721
   Summary: Warn when assigning to temporary
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

I would like for there to be a warning that warns for the following code:

```
struct s {};

inline void f() {
s() = s();
}
```

I know that for a given type, I can prevent this from compiling if I give `s`
an lvalue-refererence-qualified assignment operator, but that requires writing
two assignment operators and two (sometimes three) constructors to get the
behavior I get today from not typing anything, and I have to apply it to every
type. It would be much nicer if I could just turn on a warning for this.

The only valid use case is if your assignment operator has a side effect that
you want.

[Bug c++/100721] Warn when assigning to temporary

2021-05-23 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100721

David Stone  changed:

   What|Removed |Added

 CC||davidfromonline at gmail dot 
com

--- Comment #1 from David Stone  ---
https://bugs.llvm.org/show_bug.cgi?id=50438 is the matching clang bug, so you
can coordinate on naming the flag.

[Bug tree-optimization/105189] [9/10/11/12 Regression] Wrong code with -O1

2022-04-06 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105189

David Stone  changed:

   What|Removed |Added

 CC||davidfromonline at gmail dot 
com

--- Comment #2 from David Stone  ---
Simplified reproducer: https://godbolt.org/z/vbvKzPchP

```
int a() { return -1; }

int f() {
return (unsigned)a() >= 0 && 1;
}
```

Interestingly, the bug does not occur for C code:
https://godbolt.org/z/7efs1aEEz

[Bug c++/98995] [11/12/13 Regression] Copy elision not applied to members declared with [[no_unique_address]]

2022-04-28 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98995

David Stone  changed:

   What|Removed |Added

 CC||davidfromonline at gmail dot 
com

--- Comment #6 from David Stone  ---
Until we get that ABI break, it would be nice if the error message explained
why this doesn't work.

[Bug c++/103783] Ambiguous overload between constrained static member and unconstrained non-static member

2022-01-02 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103783

--- Comment #3 from David Stone  ---
Fedor, it looks like that wording was changed to a non-normative note and
expanded in N4868 to say: "There cannot be a static and a non-static member
function with the same name, parameter-type-list, and trailing requires-clause
([over.load]).". https://timsong-cpp.github.io/cppwp/n4868/class.static.mfct#2.
Later versions of the standard (for C++23) removed the sentence entirely.

[Bug c++/103783] Ambiguous overload between constrained static member and unconstrained non-static member

2022-01-02 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103783

--- Comment #4 from David Stone  ---
A correction to my previous comment: n4868 is technically a C++23 working draft
(but claims to have only editorial fixes to the C++20 paper). However, I
believe the wording fixes to this section are intended to be a bug fix for
wording that was not updated when we added concepts and thus is the intended
C++20 behavior.

[Bug c++/103265] New: Default initializer on [[no_unique_address]] member initialized by lambda invoking guaranteed copy elision crashes gcc

2021-11-15 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103265

Bug ID: 103265
   Summary: Default initializer on [[no_unique_address]] member
initialized by lambda invoking guaranteed copy elision
crashes gcc
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following translation unit

```
struct non_movable {
non_movable() = default;
non_movable(non_movable &&) = delete;
};

struct holder {
holder() {}
[[no_unique_address]] non_movable m = [] { return non_movable(); }();
};

auto x = holder{};
```

causes gcc to crash with

```
during RTL pass: expand
: In constructor 'holder::holder()':
:7:18: internal compiler error: in assign_temp, at function.c:988
7 | holder() {}
  |  ^
0x205c6d9 internal_error(char const*, ...)
???:0
0x7d9c9f fancy_abort(char const*, int, char const*)
???:0
0xdf2dfc assign_temp(tree_node*, int, int)
???:0
0xc0a642 expand_call(tree_node*, rtx_def*, int)
???:0
0xd78607 expand_expr_real_1(tree_node*, rtx_def*, machine_mode,
expand_modifier, rtx_def**, bool)
???:0
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See  for instructions.
Compiler returned: 1
```

See it live: https://godbolt.org/z/8oPo1ba1f

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

[Bug c++/107853] New: Cannot create friend function template with variadic pack that depends on variadic pack

2022-11-23 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107853

Bug ID: 107853
   Summary: Cannot create friend function template with variadic
pack that depends on variadic pack
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following valid translation unit

```
template
concept c = true;

template
struct s {
template requires (... and c)
friend void f(Us...) {
}
};

auto x = s<>();
```

is rejected by gcc with the error message


```
: In instantiation of 'struct s<>':
:11:14:   required from here
:6:27: error: mismatched argument pack lengths while expanding 'c'
6 | template... Us>
  |   ^~
Compiler returned: 1
```

See it live: https://godbolt.org/z/4qGKP9K9a

Note that adding a single template parameter to the instantiated `s`, for
instance, `s`, causes gcc to ICE:

```
template
concept c = true;

template
struct s {
template requires (... and c)
friend void f(Us...) {
}
};

auto x = s();
```

```
: In instantiation of 'struct s':
:11:17:   required from here
:6:52: internal compiler error: in use_pack_expansion_extra_args_p, at
cp/pt.cc:12674
6 | template requires (... and c)
  |   ~^~
0x22f921e internal_error(char const*, ...)
???:0
0xa4d7bc fancy_abort(char const*, int, char const*)
???:0
0xac1bb0 tsubst_constraint(tree_node*, tree_node*, int, tree_node*)
???:0
0xac1c99 maybe_substitute_reqs_for(tree_node*, tree_node const*)
???:0
0xc7e28c instantiate_class_template(tree_node*)
???:0
0xccdb7f complete_type_or_maybe_complain(tree_node*, tree_node*, int)
???:0
0xcef1a8 build_functional_cast(unsigned int, tree_node*, tree_node*, int)
???:0
0xc26267 c_parse_file()
???:0
0xd61389 c_common_parse_file()
???:0
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.
Compiler returned: 1
```

See it live: https://godbolt.org/z/3dfvb5ov3


Using terse syntax (`template... Us>`) has the same behavior.

[Bug c++/105623] [12/13 regression][rejects valid] invalid use of auto when deducing return type of base class template

2022-05-16 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105623

--- Comment #3 from David Stone  ---
Simplified reproduction:

```
auto g(auto fn) {
return fn();
}

template
struct base {
static auto value() {
return 0;
}
};

struct S : base {
static auto f() -> int {
return g(value);
}
};
```

See it live: https://godbolt.org/z/18n8M8oG9

An additional workaround is to explicitly take the address of the function in
line 14 of my reproducer: `return g(&value);`.

[Bug middle-end/105768] New: Missed optimization: shifting signed to unsigned range before comparison not removed

2022-05-29 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105768

Bug ID: 105768
   Summary: Missed optimization: shifting signed to unsigned range
before comparison not removed
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following translation unit:

```
#include 

inline unsigned to_unsigned(int value) {
return (unsigned)value + (unsigned)INT_MIN;
}

bool f(int lhs, int rhs) {
return to_unsigned(lhs) < to_unsigned(rhs);
}
```

when compiled with `-O3` optimizes to

```
f(int, int):
add esi, -2147483648
add edi, -2147483648
cmp edi, esi
setbal
ret
```

I would expect this to optimize to

```
f(int, int):
cmp edi, esi
setlal
ret
```

Essentially, I want gcc to recognize that a signed value + minimum signed
value, as an unsigned, has the same comparison semantics as just comparing the
original signed value.

This code pattern comes up in implementations of radix sort (specifically,
ska_sort) when it falls back to std::sort (for instance, because the range is
small).

See it live: https://godbolt.org/z/Gn4rxr3nY

[Bug c++/106211] New: Rejects valid with function template with non-deduced parameters from deduced parameters of another function template

2022-07-05 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106211

Bug ID: 106211
   Summary: Rejects valid with function template with non-deduced
parameters from deduced parameters of another function
template
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following valid translation unit

```
template
concept any = true;

void f() {
[](Ts...) {
return [](any auto..., auto) {};
}(0)(0, 0);
}
```

is rejected by gcc with the error message:

```
: In function 'void f()':
:7:13: error: no match for call to '(f()) (int, int)'
5 | [](Ts...) {
  | ~~~
6 | return [](any auto..., auto) {};
  | 
7 | }(0)(0, 0);
  | ^~
:6:24: note: candidate: 'template 
requires (... && any) f()'
6 | return [](any auto..., auto) {};
  |^
:6:24: note:   template argument deduction/substitution failed:
:7:13: note:   candidate expects 1 argument, 2 provided
5 | [](Ts...) {
  | ~~~
6 | return [](any auto..., auto) {};
  | 
7 | }(0)(0, 0);
  | ^~
Compiler returned: 1
```

See it live: https://godbolt.org/z/c7zxWEbxM

[Bug c++/106211] Rejects valid with function template with non-deduced parameters from deduced parameters of another function template

2022-07-06 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106211

David Stone  changed:

   What|Removed |Added

 CC||davidfromonline at gmail dot 
com

--- Comment #2 from David Stone  ---
I believe clang is correct here. Here is another version that is also rejected
by gcc and msvc, but accepted by clang:

```
template
concept any = true;

template
void f(Ts... ts) {
[](any auto..., auto) {}(ts..., 2);
}

void g() {
f(1);
}
```

Which looks basically the same. All three compilers accept if line 10 is
changed from `f(1);` to to `f();`. Further, all three compilers also accept
this minor modification:

```
template
void f(Ts... ts) {
[](Ts..., auto) {}(ts..., 2);
}

void g() {
f(1);
}
```

Further supporting the view that it's a bug in msvc as well, look at the error
message it gives: "expects 2 arguments - 2 provided". Clearly something fishy
is going on in those compiler internals.

[Bug c++/106211] Rejects valid with function template with non-deduced parameters from deduced parameters of another function template

2022-07-06 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106211

--- Comment #4 from David Stone  ---
The types for the first parameters of the inner lambda are deduced in my first
two examples, but the arity is fixed in all of them -- equal to the arity of
the outer function.

Also, `return [](any auto, auto) {};` is perfectly valid. It accepts one
argument that satisfies `any` (which is any type), and another argument
that matches anything -- in other words, two arguments.

[Bug c++/99018] Comparing address of array element not considered a constant expression in certain contexts

2021-08-02 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99018

--- Comment #3 from David Stone  ---
The error message looks suspiciously similar to
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85944. Perhaps it's the same bug?

[Bug c++/101777] New: Copying array of non-trivial type during constant evaluation is incorrect

2021-08-04 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101777

Bug ID: 101777
   Summary: Copying array of non-trivial type during constant
evaluation is incorrect
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following well-formed translation unit

```
struct value {
constexpr value():
m_value(new int())
{
}

constexpr value(value const &):
m_value(new int())
{
}

value(value &&) = delete;
void operator=(value const &) = delete;
void operator=(value &&) = delete;

constexpr ~value() {
delete m_value;
}

private:
int * m_value;
};

struct array {
value m[1];
};

constexpr bool test() {
auto a = array();
auto b = a;
return true;
}

static_assert(test());
```

Fails with the message

```
:34:19: error: non-constant condition for static assertion
   34 | static_assert(test());
  |   ^~
:34:19:   in 'constexpr' expansion of 'test()'
:32:1:   in 'constexpr' expansion of '(& b)->array::~array()'
:24:8:   in 'constexpr' expansion of '->value::~value()'
:17:24: error: deallocation of already deallocated storage
   17 | delete m_value;
  |^~~
Compiler returned: 1
```

Compiler explorer: https://godbolt.org/z/bcWf3sr4f

I suspect this is another case where some part of the constant evaluation
assumes an operation is trivial even though it is not (assuming copying array
members is trivial would cause this issue).

[Bug c/111617] New: Unnecessary instructions generated when comparing mixed-sign small integers

2023-09-27 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111617

Bug ID: 111617
   Summary: Unnecessary instructions generated when comparing
mixed-sign small integers
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

Compiling with `-std=c2x -O3`

```c
bool a(signed char x, unsigned char y) {
return x == y;
}

bool b(short x, unsigned short y) {
return x == y;
}

bool c(int x, unsigned y) {
return x == y;
}

bool d(long x, unsigned long y) {
return x == y;
}

bool e(long long x, unsigned long long y) {
return x == y;
}
```

causes gcc to generate

```asm
a:
movsx   edi, dil
movzx   esi, sil
cmp edi, esi
seteal
ret
b:
movsx   edi, di
movzx   esi, si
cmp edi, esi
seteal
ret
c:
cmp edi, esi
seteal
ret
d:
cmp rdi, rsi
seteal
ret
e:
cmp rdi, rsi
seteal
ret
```

The `movsx` and `movzx` seem unnecessary, and are not emitted by clang.

See it live: https://godbolt.org/z/dfc93f7Pv

[Bug libstdc++/115119] New: Typo in _Grapheme_cluster_view::_Iterator::operator++(int)

2024-05-16 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115119

Bug ID: 115119
   Summary: Typo in
_Grapheme_cluster_view::_Iterator::operator++(int)
   Product: gcc
   Version: 14.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following code in unicode.h:

```c++
constexpr _Iterator
operator++(int)
{
  auto __tmp = *this;
  ++this;
  return __tmp;
}
```


Should instead be:

```c++
constexpr _Iterator
operator++(int)
{
  auto __tmp = *this;
  ++*this;
  return __tmp;
}
```

(`++*this` instead of `++this`).

[Bug c++/112355] New: Internal compiler error when exporting using declaration of function template

2023-11-02 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112355

Bug ID: 112355
   Summary: Internal compiler error when exporting using
declaration of function template
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following mostly valid code:

```cxx
module;

namespace n {

template
void f() {
}

}

export module m;

export using n::f;
```

causes gcc to crash with

```console
:3:1: error: global module fragment contents must be from preprocessor
inclusion
3 | namespace n {
  | ^
:13:17: internal compiler error: tree check: expected none of
template_decl, have template_decl in do_nonmember_using_decl, at
cp/name-lookup.cc:4853
   13 | export using n::f;
  | ^
0x8fbb6e tree_not_check_failed(tree_node const*, char const*, int, char const*,
...)
gcc/source/gcc/tree.cc:8986
0x76f1d4 tree_not_check(tree_node*, char const*, int, char const*, tree_code)
gcc/source/gcc/tree.h:3607
0x76f1d4 do_nonmember_using_decl
gcc/source/gcc/cp/name-lookup.cc:4853
0xb63549 finish_nonmember_using_decl(tree_node*, tree_node*)
gcc/source/gcc/cp/name-lookup.cc:6297
0xb6d974 finish_using_decl
gcc/source/gcc/cp/parser.cc:21908
0xbb482f cp_parser_using_declaration
gcc/source/gcc/cp/parser.cc:22072
0xbc8653 cp_parser_declaration
gcc/source/gcc/cp/parser.cc:15335
0xbc85d4 cp_parser_module_export
gcc/source/gcc/cp/parser.cc:15080
0xbc85d4 cp_parser_declaration
gcc/source/gcc/cp/parser.cc:15276
0xbc908a cp_parser_toplevel_declaration
gcc/source/gcc/cp/parser.cc:15356
0xbc908a cp_parser_translation_unit
gcc/source/gcc/cp/parser.cc:5218
0xbc908a c_parse_file()
gcc/source/gcc/cp/parser.cc:50627
0xd0f8e1 c_common_parse_file()
gcc/source/gcc/c-family/c-opts.cc:1278
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.
Compiler returned: 1
```

See it live: http://desktop:10240/z/nj5q1b

(the crash still exists if the global module fragment comes from an #include, I
just made it this way to have a single-file reproduction)

[Bug c++/112355] Internal compiler error when exporting using declaration of function template

2023-11-02 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112355

David Stone  changed:

   What|Removed |Added

 CC||davidfromonline at gmail dot 
com

--- Comment #1 from David Stone  ---
Looks like this is a new bug in trunk. Works in 13.2

[Bug c++/106849] internal compiler error: tree check: expected none of template_decl, have template_decl in do_nonmember_using_decl, at cp/name-lookup.cc:4841

2023-11-02 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106849

--- Comment #2 from David Stone  ---
Looks like it works in 13.2 but fails in trunk.

13.2: https://godbolt.org/z/d54ToW7zW
trunk: https://godbolt.org/z/eej9d7ccM

[Bug c++/106849] internal compiler error: tree check: expected none of template_decl, have template_decl in do_nonmember_using_decl, at cp/name-lookup.cc:4841

2023-11-02 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106849

--- Comment #3 from David Stone  ---
Oh, as per https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112355#c3 it's just
that the 13.2 build isn't checked, so it's not a new bug.

[Bug other/118637] New: gcc fails to optimize unsigned division by 2 to shift right by 1

2025-01-23 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118637

Bug ID: 118637
   Summary: gcc fails to optimize unsigned division by 2 to shift
right by 1
   Product: gcc
   Version: 15.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: other
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following code:

```c++
unsigned log2_divide(unsigned x) {
unsigned result = 0;
while (x /= 2) {
++result;
}
return result;
}

unsigned log2_shift(unsigned x) {
unsigned result = 0;
while (x >>= 1) {
++result;
}
return result;
}
```

when compiled with `-O3` generates

```asm
log2_divide(unsigned int):
cmp edi, 1
jbe .L4
shr edi
xor eax, eax
.L3:
mov edx, edi
add eax, 1
shr edi
cmp edx, 1
jne .L3
ret
.L4:
xor eax, eax
ret
log2_shift(unsigned int):
mov eax, edi
shr eax
je  .L7
bsr eax, eax
add eax, 1
.L7:
ret
```

I would expect `log2_divide` to generate the same code as `log2_shift`.

See it live: https://godbolt.org/z/fahr3Moe3

[Bug middle-end/91883] Division by a constant could be optimized for known variables value range

2024-12-24 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91883

David Stone  changed:

   What|Removed |Added

 CC||davidfromonline at gmail dot 
com

--- Comment #2 from David Stone  ---
Here's another example:

```c++
int baseline(int x) {
return x / 3;
}

int assumed(int x) {
[[assume(x >= 0)]];
return x / 3;
}

int goal(unsigned x) {
return x / 3;
}
```

when compiled with gcc at -O3 generates

```
baseline(int):
movsx   rax, edi
sar edi, 31
imulrax, rax, 1431655766
shr rax, 32
sub eax, edi
ret
assumed(int):
movsx   rax, edi
sar edi, 31
imulrax, rax, 1431655766
shr rax, 32
sub eax, edi
ret
goal(unsigned int):
mov eax, edi
mov edx, 2863311531
imulrax, rdx
shr rax, 33
ret
```

See it live: https://godbolt.org/z/nMPfxchM4

[Bug c++/118863] New: Cannot #include in global module fragment with -fsanitize=undefined

2025-02-13 Thread davidfromonline at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118863

Bug ID: 118863
   Summary: Cannot #include  in global module fragment
with -fsanitize=undefined
   Product: gcc
   Version: 15.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davidfromonline at gmail dot com
  Target Milestone: ---

The following code

```c++
module;

#include 

export module m;
```

when compiled with `-std=c++23 -fmodules-ts -fsanitize=undefined` causes gcc to
fail with

```console
:5:8: internal compiler error: in tree_node, at cp/module.cc:9767
5 | export module m;
  |^~
0x2914845 diagnostic_context::diagnostic_impl(rich_location*,
diagnostic_metadata const*, diagnostic_option_id, char const*, __va_list_tag
(*) [1], diagnostic_t)
???:0
0x292b916 internal_error(char const*, ...)
???:0
0xacf882 fancy_abort(char const*, int, char const*)
???:0
0xc572ad depset::hash::find_dependencies(module_state*)
???:0
0xc57c4a module_state::write_begin(elf_out*, cpp_reader*, module_state_config&,
unsigned int&)
???:0
0xc59454 finish_module_processing(cpp_reader*)
???:0
0xbdb7c3 c_parse_final_cleanups()
???:0
0xe51ad8 c_common_parse_file()
???:0
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.
Compiler returned: 1
```

https://godbolt.org/z/vrzh3WvTc

This can be reduced to

```c++
module;

constexpr bool is_constant_evaluated() noexcept {
if consteval {
return true;
} else {
return false;
}
}

template
struct s {
s() {
is_constant_evaluated();
}
};

extern template struct s;

s a;

export module m;
```

Which fails with

```console
:3:1: warning: global module fragment contents must be from
preprocessor inclusion [-Wglobal-module]
3 | constexpr bool is_constant_evaluated() noexcept {
  | ^
:22:8: internal compiler error: in tree_node, at cp/module.cc:9767
   22 | export module m;
  |^~
0x2914845 diagnostic_context::diagnostic_impl(rich_location*,
diagnostic_metadata const*, diagnostic_option_id, char const*, __va_list_tag
(*) [1], diagnostic_t)
???:0
0x292b916 internal_error(char const*, ...)
???:0
0xacf882 fancy_abort(char const*, int, char const*)
???:0
0xc572ad depset::hash::find_dependencies(module_state*)
???:0
0xc57c4a module_state::write_begin(elf_out*, cpp_reader*, module_state_config&,
unsigned int&)
???:0
0xc59454 finish_module_processing(cpp_reader*)
???:0
0xbdb7c3 c_parse_final_cleanups()
???:0
0xe51ad8 c_common_parse_file()
???:0
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.
Compiler returned: 1
```

https://godbolt.org/z/G1b15b858