[Bug target/113149] Function multiversioning prefers arch=x86-64-v3 to actual processors

2023-12-26 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113149

--- Comment #1 from Ed Catmur  ---
>From b4ca8bf55100eddeaa14a52f1bc8e73fac565d83 Mon Sep 17 00:00:00 2001
From: Ed Catmur 
Date: Tue, 26 Dec 2023 11:46:26 -0600
Subject: [PATCH] Swap P_PROC_AVX2 with P_X86_64_V3, etc.

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

Any processor with feature priority P_PROC_AVX2 necessarily supports at least
all of the x86-64-v3 psABI level, but almost certainly supports more
instructions; e.g. Haswell supports pclmul and rdrnd. So if there are
multiversion targets for arch=x86-64-v3 and e.g. arch=haswell, the target for
the specific processor should be preferred.

Similarly, swap P_PROC_AVX512F with P_X86_64_V4.
---
 gcc/common/config/i386/i386-cpuinfo.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/common/config/i386/i386-cpuinfo.h
b/gcc/common/config/i386/i386-cpuinfo.h
index 38fa7650de28f..593d71626e440 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -141,11 +141,11 @@ enum feature_priority
   P_PROC_FMA,
   P_BMI2,
   P_AVX2,
-  P_PROC_AVX2,
   P_X86_64_V3,
+  P_PROC_AVX2,
   P_AVX512F,
-  P_PROC_AVX512F,
   P_X86_64_V4,
+  P_PROC_AVX512F,
   P_PROC_DYNAMIC
 };

[Bug target/113149] New: Function multiversioning prefers arch=x86-64-v3 to actual processors

2023-12-26 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113149

Bug ID: 113149
   Summary: Function multiversioning prefers arch=x86-64-v3 to
actual processors
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since #101696, we can write

__attribute__ ((target ("arch=x86-64-v3")))
char const* f() { return "x86-64-v3"; }

But x86-64-v3 is preferred to any of the processors that support this feature
set, which seems backwards - even Haswell supports pclmul and rdrnd, which
aren't in x86-64-v3.

It feels that it should be OK to swap the ordering of P_PROC_AVX2 with
P_X86_64_V3, and P_PROC_AVX512F with P_X86_64_V4, in enum feature_priority.

[Bug c++/112354] New: mismatched types 'B' and 'B&' for generic lambda noexcept-specifier referencing enclosing function parameter

2023-11-02 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112354

Bug ID: 112354
   Summary: mismatched types 'B' and 'B&' for generic
lambda noexcept-specifier referencing enclosing
function parameter
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since 4.9.0,

template
struct B {
B();
B(B const&);
};
template void g(B, int);
auto f(B x) {
return [](auto y) noexcept(noexcept(g(x, y))) {
return 1;
};
}
int i = f({})(0);

fails with:

: In instantiation of 'f(B):: [with auto:1 =
int]':
:12:14:   required from here
   12 | int i = f({})(0);
  | ~^~~
:8:42: error: no matching function for call to 'g(B&&, int&)'
8 | return [](auto y) noexcept(noexcept(g(x, y))) {
  | ~^~
:6:24: note: candidate: 'template void g(B, int)'
6 | template void g(B, int);
  |^
:6:24: note:   template argument deduction/substitution failed:
:8:42: note:   mismatched types 'B' and 'B&'
8 | return [](auto y) noexcept(noexcept(g(x, y))) {
  | ~^~

[Bug c++/112341] New: error: insufficient contextual information to determine type on co_await result in function template

2023-11-01 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112341

Bug ID: 112341
   Summary: error: insufficient contextual information to
determine type on co_await result in function template
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

#include 
struct A { int j; };
struct B {
bool await_ready();
bool await_suspend(std::coroutine_handle<>);
A await_resume();
};
struct C {
struct promise_type {
std::suspend_always initial_suspend();
std::suspend_always final_suspend() noexcept;
void unhandled_exception();
C get_return_object();
void return_void();
};
};
C f(auto) { (co_await B()).j; }
void g() { f(0); }

: In function 'C f(auto:1)':
:17:14: error: insufficient contextual information to determine type
   17 | C f(auto) { (co_await B()).j; }
  | ~^

Writing 'auto&& a = co_await B(); a.j;' or even 'auto(co_await B()).j' accepts.

[Bug c++/111944] Spurious '' is used uninitialized in Boost.Variant2 (-Wuninitialized -Og)

2023-10-23 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111944

--- Comment #1 from Ed Catmur  ---
Correction, it does affect sanitizers (-O2 -fsanitize=address) as well as -Og.

[Bug c++/111944] New: Spurious '' is used uninitialized in Boost.Variant2 (-Wuninitialized -Og)

2023-10-23 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111944

Bug ID: 111944
   Summary: Spurious '' is used uninitialized in
Boost.Variant2 (-Wuninitialized -Og)
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since 12.1, with Boost 1.71 or later,

#include 
int main() {
boost::variant2::variant r;
r.emplace();
}

In member function 'constexpr void
boost::variant2::detail::variant_storage_impl, T1, T ...>::emplace_impl(boost::mp11::mp_true,
boost::mp11::mp_size_t, A&& ...) [with long unsigned int I = 1; A = {}; T1 =
boost::variant2::detail::none; T = {boost::variant2::monostate, int}]',
inlined from 'constexpr void
boost::variant2::detail::variant_storage_impl, T1, T ...>::emplace(boost::mp11::mp_size_t, A&& ...) [with long
unsigned int I = 1; A = {}; T1 = boost::variant2::detail::none; T =
{boost::variant2::monostate, int}]' at boost/variant2/variant.hpp:705:27,
inlined from 'constexpr void
boost::variant2::detail::variant_base_impl::emplace_impl(boost::mp11::mp_true, A&& ...) [with long unsigned int J =
1; U = boost::variant2::monostate; A = {}; T = {boost::variant2::monostate,
int}]' at boost/variant2/variant.hpp:902:20,
inlined from 'constexpr void
boost::variant2::detail::variant_base_impl::emplace(A&& ...)
[with long unsigned int I = 0; A = {}; T = {boost::variant2::monostate, int}]'
at boost/variant2/variant.hpp:921:33,
inlined from 'constexpr U& boost::variant2::variant::emplace(A&& ...)
[with U = boost::variant2::monostate; A = {}; E = void; T =
{boost::variant2::monostate, int}]' at boost/variant2/variant.hpp:1690:49:
boost/variant2/variant.hpp:696:9: warning: '' is used uninitialized
[-Wuninitialized]
  696 | *this = variant_storage_impl( mp11::mp_size_t(),
std::forward(a)... );
  | ^
boost/variant2/variant.hpp: In member function 'constexpr U&
boost::variant2::variant::emplace(A&& ...) [with U =
boost::variant2::monostate; A = {}; E = void; T = {boost::variant2::monostate,
int}]':
boost/variant2/variant.hpp:696:17: note: '' declared here
  696 | *this = variant_storage_impl( mp11::mp_size_t(),
std::forward(a)... );
  |
^~~

Boost.Variant2 has a suppression at this line for Wmaybe-uninitialized
referencing asan, (a) this isn't with sanitizer, and (b) it's Wuninitialized.
This only appears to affect -Og, though, so fairly minor.

[Bug c++/111840] New: =delete("can have a reason")?

2023-10-16 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111840

Bug ID: 111840
   Summary: =delete("can have a reason")?
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since 6.1, gcc accepts the following (without warnings at any level):

int f() = delete("should have a reason");

Much as I'd love to be able to write this, gcc seems to be slightly jumping the
gun, since P2573[1][2] hasn't been accepted yet and in fact wasn't even
proposed until almost 6 years after 6.1 was released.

1. https://github.com/cplusplus/papers/issues/1229
2. https://wg21.link/p2573r0

[Bug c++/111602] [11/12/13/14 Regression] "Error: symbol is already defined" for variable template dependent on default argument lambda of class dependent on local type used in sfinae and non-sfinae c

2023-09-26 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111602

--- Comment #2 from Ed Catmur  ---
(In reply to Andrew Pinski from comment #1)
> The local type of f() is not needed.

Thanks! I was confused since the local type is required in this similar
example:

template struct P
{
static constexpr bool value = true;
};
template constexpr bool P::value;
template struct E {};
struct F
{
template::value>>
F(T) {}
};
template struct C
{
C(F = []{}) {}
};
auto f()
{
struct T {} t;
return t;
}
template
decltype(T()) g()
{
return T();
}
int main()
{
g>();
}

[Bug c++/111602] New: "Error: symbol is already defined" for variable template dependent on default argument lambda used in sfinae and non-sfinae

2023-09-26 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111602

Bug ID: 111602
   Summary: "Error: symbol is already defined" for variable
template dependent on default argument lambda used in
sfinae and non-sfinae
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since gcc 8.1,

template constexpr bool V = true;
struct F { template> F(T) {} };
template struct C { C(F = []{}) {} };
template decltype(T()) g() { return T(); }
auto f() { struct T {} t; return t; };
int main() { g>(); }

compiled at -O0 (and -std=c++14 or above) causes assembler error:

/tmp/cccVZwwU.s: Assembler messages:
/tmp/cccVZwwU.s:106: Error: symbol `_Z1VIZN1CIZ1fvE1TEC4E1FEd_UlvE_E' is
already defined

The symbol demangles as 'V::C(F)::{default arg#1}::{lambda()#1}>'.

[Bug tree-optimization/111094] Spurious Wuninitialized swapping underlying bytes of object representation in move constructor

2023-08-21 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111094

Ed Catmur  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #4 from Ed Catmur  ---
Well, I feel like [basic.types.general] probably allows it.

But regardless, yeah, this is an opt-in diagnostic so it's fine if gcc warns on
things that are legal but dubious. We'll just have to be a bit smarter in how
we write this code. Thanks again.

[Bug middle-end/24639] [meta-bug] bug to track all Wuninitialized issues

2023-08-21 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
Bug 24639 depends on bug 111094, which changed state.

Bug 111094 Summary: Spurious Wuninitialized swapping underlying bytes of object 
representation in move constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111094

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

[Bug c++/111094] New: Spurious Wuninitialized swapping underlying bytes of object representation in move constructor

2023-08-21 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111094

Bug ID: 111094
   Summary: Spurious Wuninitialized swapping underlying bytes of
object representation in move constructor
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

struct S { short x, y; };
struct A {
A() {}
A(A&& rhs) {
auto p = reinterpret_cast();
auto q = reinterpret_cast();
for (int i = 0; i != sizeof s; ++i) {
auto t = p[i];
p[i] = q[i];
q[i] = t;
}
}
bool b = false;
S s;
};
A f() {
A a;
A b = static_cast(a);
return b;
}

at -O3 -Wall:

In constructor 'A::A(A&&)',
inlined from 'A f()' at :18:29:
:9:23: warning: '*(__vector(4) unsigned char*)((char*) + offsetof(A,
A::s.S::x))' is used uninitialized [-Wuninitialized]
9 | p[i] = q[i];
  |~~~^
: In function 'A f()':
:17:7: note: 'a' declared here
   17 | A a;
  |   ^

I'm reasonably sure that this usage of swapping underlying bytes is OK by
[basic.indet]/2.3.

(Motivation is e.g. optional with empty-on-move behavior and optimization for
trivial types.)

[Bug tree-optimization/111090] Bogus -Wuninitialized for trivial copy of nested struct with partially initialized array

2023-08-21 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111090

Ed Catmur  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #4 from Ed Catmur  ---
(In reply to Andrew Pinski from comment #2)
> I don't see how it is bogus as you admit it was only partially initialized
> even.  The act of copying is still an use IIRC.

Sorry, my bad. I reduced it past the point of usefulness and got myself
confused. Thanks.

[Bug middle-end/24639] [meta-bug] bug to track all Wuninitialized issues

2023-08-21 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
Bug 24639 depends on bug 111090, which changed state.

Bug 111090 Summary: Bogus -Wuninitialized for trivial copy of nested struct 
with partially initialized array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111090

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

[Bug c++/111090] Bogus -Wuninitialized for trivial copy of nested struct with partially initialized array

2023-08-21 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111090

--- Comment #1 from Ed Catmur  ---
uh, -O -Wall is necessary, obviously. https://godbolt.org/z/eT9dY467P

[Bug c++/111090] New: Bogus -Wuninitialized for trivial copy of nested struct with partially initialized array

2023-08-21 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111090

Bug ID: 111090
   Summary: Bogus -Wuninitialized for trivial copy of nested
struct with partially initialized array
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

struct A {
A() { buf[0] = 0; }
int buf[2];
};
struct B { A a; };
struct C {
C(B const& b) : b(b) {}
B b;
};
struct D {
D(C c) : c(c) {}
C c;
};
D f() { return D(C(B())); }

In constructor 'C::C(const B&)',
inlined from 'D f()' at :14:16:
:7:21: warning: '.B::a.A::a[1]' is used uninitialized
[-Wuninitialized]
7 | C(B const& b) : b(b) {}
  | ^~~~
: In function 'D f()':
:14:22: note: '' declared here
   14 | D f() { return D(C(B())); }
  |  ^

This appears to have started in 7.1.

[Bug c++/111016] New: Confusing "used in its own initializer" for non-dependent ad-hoc constraint

2023-08-14 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111016

Bug ID: 111016
   Summary: Confusing "used in its own initializer" for
non-dependent ad-hoc constraint
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

#include 
struct S { int i; };
static_assert(requires(S s) { requires std::destructible; });

In file included from :1:
include/c++/14.0.0/concepts:148:13:   required for the satisfaction of
'destructible'
include/c++/14.0.0/concepts:148:38: error: the value of
'std::__detail::__destructible' is not usable in a constant
expression
  148 | concept destructible = __detail::__destructible<_Tp>;
  |~~^~~
include/c++/14.0.0/concepts:127:22: note:
'std::__detail::__destructible' used in its own initializer
  127 |   constexpr bool __destructible = __destructible_impl<_Tp>;
  |  ^~

Obviously this is IFNDR, but it would be nice to emit a diagnostic which gives
some better clue to what is going on (e.g. "warning: constraint is
non-dependent"). Unfortunately both clang and MSVC accept with no diagnostic,
making this look like a gcc bug.

[Bug c/66425] (void) cast doesn't suppress __attribute__((warn_unused_result))

2023-08-10 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425

--- Comment #58 from Ed Catmur  ---
(In reply to Roman Krotov from comment #57)
> But I don't see any reasons not to implement the switch right now...
Making [[gnu::warn_unused_result]] mean the same as [[nodiscard]] would be a
reduction in expressivity.

> what about the projects
> what don't agree with the distinction of these 2 attributes? Or just want to
> be more compatible with clang?
They can use [[nodiscard]].

> Or they just may not agree with the choice of a library, that decided to put
> wur instead of nodiscard for a specific function.
Then they can write their own wrappers using [[nodiscard]].

[Bug c/66425] (void) cast doesn't suppress __attribute__((warn_unused_result))

2023-08-09 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425

--- Comment #55 from Ed Catmur  ---
(In reply to Roman Krotov from comment #54)
[[nodiscard]] is in C23, so we can expect that attribute to be adopted where
people intend that behavior (warning suppressible by cast to void) as opposed
to the nonportable [[gnu::warn_unused_result]] (warning not suppressible by
cast to void). So this problem will resolve itself, over time.

[Bug sanitizer/110835] [13/14 Regression] -fsanitize=address causes huge runtime slowdown from std::rethrow_exception not called

2023-07-28 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110835

--- Comment #6 from Ed Catmur  ---
Thanks, filed https://github.com/llvm/llvm-project/issues/64190 .

[Bug c++/110835] -fsanitize=address causes slowdown from std::rethrow_exception not called

2023-07-27 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110835

--- Comment #1 from Ed Catmur  ---
Motivation is
https://github.com/boostorg/exception/blob/b039b4ea18ef752d0c1684b3f715ce493b778060/include/boost/exception/detail/exception_ptr.hpp#L550
; the half-reduced code is:

#include 
struct S {};
int main() {
auto ep = boost::copy_exception(S());
for (int i = 0; i != 10; ++i)
try { boost::rethrow_exception(ep); } catch (...) {}
}

[Bug c++/110835] New: -fsanitize=address causes slowdown from std::rethrow_exception not called

2023-07-27 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110835

Bug ID: 110835
   Summary: -fsanitize=address causes slowdown from
std::rethrow_exception not called
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

#include 
std::exception_ptr p;
void f() {
  try { throw 1; } catch(char) { std::rethrow_exception(p); }
}
int main() {
  for (int i = 0; i != 10; ++i)
try { f(); } catch (...) { }
}

Compiled with -fsanitize=address (and at -O0 through -O3), this is roughly 30x
slower under gcc 13 than under gcc 12 (4.7s vs 0.15s on my Core i7 3 GHz).

Note that the std::rethrow_exception() is not called, but is still essential to
exhibit the bug. Also `f` needs to be a separate function (and not `static`).
At low optimization levels it can be an iife.

[Bug c++/110809] ICE: in unify, at cp/pt.cc:25226 with floating-point NTTPs

2023-07-25 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110809

--- Comment #5 from Ed Catmur  ---
The original code is valid. A reduced valid case would be:
```
template  struct S {};
template  struct bucket {};
template 
int find_indices_impl(bucket const &);
struct HashTable : bucket, 1>, bucket, 2> {};
auto t = find_indices_impl>(HashTable{});
```

[Bug c++/110809] New: ICE: in unify, at cp/pt.cc:25226 with floating-point NTTPs

2023-07-25 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110809

Bug ID: 110809
   Summary: ICE: in unify, at cp/pt.cc:25226 with floating-point
NTTPs
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

#include 
using A = double;
template struct S {};
auto x = boost::hana::make_map(
boost::hana::make_pair(boost::hana::type_c>, 1),
boost::hana::make_pair(boost::hana::type_c>, 2))[
boost::hana::type_c>];

/opt/compiler-explorer/libs/boost_1_82_0/boost/hana/detail/hash_table.hpp:51:62:
internal compiler error: in unify, at cp/pt.cc:25226
   51 | using type =
decltype(detail::find_indices_impl(std::declval()));
  |  
~~~^
0x246af2e internal_error(char const*, ...)
???:0
0xac8ab6 fancy_abort(char const*, int, char const*)
???:0
0xd01e11 fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node*
const*, unsigned int, tree_node*, unification_kind_t, int, conversion**, bool,
bool)
???:0
0xaf7db9 build_new_function_call(tree_node*, vec**, int)
???:0
0xd2379c finish_call_expr(tree_node*, vec**, bool,
bool, int)
???:0
0xcddfef tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0xcde6fc tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0xd06d50 instantiate_class_template(tree_node*)
???:0
0xd5954f complete_type_or_maybe_complain(tree_node*, tree_node*, int)
???:0
0xcdf1a7 tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0xcde6fc tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0xd06d50 instantiate_class_template(tree_node*)
???:0
0xd5954f complete_type_or_maybe_complain(tree_node*, tree_node*, int)
???:0
0xcdf1a7 tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0xcde6fc tsubst(tree_node*, tree_node*, int, tree_node*)
???:0
0xcd6618 instantiate_decl(tree_node*, bool, bool)
???:0
0xbb8461 maybe_instantiate_decl(tree_node*)
???:0
0xbb9ebf mark_used(tree_node*, int)
???:0
0xaf673e build_new_method_call(tree_node*, tree_node*, vec**, tree_node*, int, tree_node**, int)
???:0
0xd22eaf finish_call_expr(tree_node*, vec**, bool,
bool, int)
???:0

Changing `A` to `int` makes it compile, so this is a problem with
floating-point NTTPs.

[Bug c++/110493] 'is not a constant expression' for function-local static std::initializer_list with fsanitize=undefined

2023-06-30 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110493

--- Comment #4 from Ed Catmur  ---
Ah, thanks. So a workaround is something like:

void f() { static auto a = {((bool*)&(int const&)0, std::string())}; }

That's not too bad, then.

[Bug libstdc++/110493] New: 'is not a constant expression' for function-local static std::initializer_list with fsanitize=undefined

2023-06-29 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110493

Bug ID: 110493
   Summary: 'is not a constant expression' for function-local
static std::initializer_list with
fsanitize=undefined
   Product: gcc
   Version: 12.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since 12.3.0, under -fsanitize=undefined -std=c++20:

#include 
#include 
void f() {
static auto a = {std::string()};
}

error: '(((const std::__cxx11::basic_string*)(& )) != 0)' is
not a constant expression

Clearly this is an instance of bug 71962, but this is in fairly unexceptional
code and could make ubsan unusable; it's not obvious that this code should have
anything to do with constant evaluation.

Since it only appears in a point release I would hope it might be possible to
fix in library for this specific case, within ?

[Bug libstdc++/109976] New: error: is not a constant expression in std::equal() with _GLIBCXX_DEBUG

2023-05-25 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109976

Bug ID: 109976
   Summary: error: is not a constant expression in std::equal()
with _GLIBCXX_DEBUG
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

#define _GLIBCXX_DEBUG
#include 
#include 
constexpr bool f(std::string const& l, std::string const& r) {
return std::equal(l.data(), l.data() + l.size(), r.data(), r.data() +
r.size());
}
constexpr bool b = f("aa", "aa");

In file included from c++/14.0.0/debug/stl_iterator.h:32,
 from c++/14.0.0/bits/stl_iterator.h:3004,
 from c++/14.0.0/bits/stl_algobase.h:67,
 from c++/14.0.0/algorithm:60,
 from :2:
:7:21:   in 'constexpr' expansion of
'f(std::__cxx11::basic_string(((const char*)"aa"),
std::allocator()), std::__cxx11::basic_string(((const char*)"aa"),
std::allocator()))'
:5:22:   in 'constexpr' expansion of 'std::equal((& l)->std::__cxx11::basic_string::data(), ((&
l)->std::__cxx11::basic_string::data() + ((sizetype)(&
l)->std::__cxx11::basic_string::size())), (&
r)->std::__cxx11::basic_string::data(), ((&
r)->std::__cxx11::basic_string::data() + ((sizetype)(&
r)->std::__cxx11::basic_string::size('
c++/14.0.0/bits/stl_algobase.h:1679:7:   in 'constexpr' expansion of
'__gnu_debug::__valid_range(__first1, __last1)'
c++/14.0.0/debug/helper_functions.h:257:31:   in 'constexpr' expansion of
'__gnu_debug::__valid_range_aux(__first, __last, (_Integral(),
_Integral()))'
c++/14.0.0/debug/helper_functions.h:189:31:   in 'constexpr' expansion of
'__gnu_debug::__valid_range_aux(__first, __last,
(std::__iterator_category(__first), std::iterator_traits::iterator_category()))'
c++/14.0.0/debug/helper_functions.h:176:19:   in 'constexpr' expansion of
'__gnu_debug::__valid_range_aux(__first, __last,
(std::input_iterator_tag(), std::input_iterator_tag()))'
c++/14.0.0/debug/helper_functions.h:136:20: error: '(((const
char*)(&.std::__cxx11::basic_string::.std::__cxx11::basic_string_M_local_buf)) == 0)' is not a constant expression
  136 | { return __ptr == 0; }
  |  ~~^~~~

This appears to be caused by bug 109975, but I'm filing separately since it 
may be possible to fix in library.

The code is accepted if _GLIBCXX_DEBUG is not defined, since
__gnu_debug::__valid_range is not checked.

[Bug c++/109975] New: error: '(((int*)(&.X::a)) != 0)' is not a constant expression

2023-05-25 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109975

Bug ID: 109975
   Summary: error: '(((int*)(&.X::a)) != 0)' is not a
constant expression
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

struct X { int a[1]; };
constexpr bool b = (X{}.a != 0);

:7:27: error: '(((int*)(&.X::a)) != 0)' is not a constant
expression
7 | constexpr bool b = (X{}.a != 0);
  |~~~^

AFAICT this does not fall foul of anything in [expr.const]. Other compilers
accept, with a tautological-compare warning in the case of clang.
Similar to bug 71962, but this happens without enabling sanitizer.

[Bug c++/109958] [10/11/12/13/14 Regression] ICE: in build_ptrmem_type, at cp/decl.cc:11066 taking the address of bound static member function brought into derived class by using-declaration

2023-05-25 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109958

--- Comment #3 from Ed Catmur  ---
B::f is a static member function so yes, it's valid. A class member access
expression naming a static member function is an lvalue designating that
function, and it shouldn't make any difference that the function was found via
a using declaration.

[Bug c++/109958] New: ICE: in build_ptrmem_type, at cp/decl.cc:11066 taking the address of bound static member function brought into derived class by using-declaration

2023-05-24 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109958

Bug ID: 109958
   Summary: ICE: in build_ptrmem_type, at cp/decl.cc:11066 taking
the address of bound static member function brought
into derived class by using-declaration
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

struct B { static int f(); };
struct D : B { using B::f; };
void f(D d) {  }

: In function 'void f(D)':
:3:18: error: ISO C++ forbids taking the address of a bound member
function to form a pointer to member function.  Say '::f' [-fpermissive]
3 | void f(D d) {  }
  |~~^
:3:18: internal compiler error: in build_ptrmem_type, at
cp/decl.cc:11066
3 | void f(D d) {  }
  |  ^
0x23a0cee internal_error(char const*, ...)
???:0
0xa95fae fancy_abort(char const*, int, char const*)
???:0
0xd31f7f build_x_unary_op(unsigned int, tree_code, cp_expr, tree_node*, int)
???:0
0xc7ab2f c_parse_file()
???:0
0xdb9519 c_common_parse_file()
???:0

This appears to have been broken somewhere between 4.7.4 and 4.8.1.

[Bug preprocessor/109912] New: #pragma GCC diagnostic ignored "-Wall" is ignored

2023-05-19 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109912

Bug ID: 109912
   Summary: #pragma GCC diagnostic ignored "-Wall" is ignored
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: preprocessor
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

#pragma GCC diagnostic warning "-Wall"
#pragma GCC diagnostic ignored "-Wall"
int i = 0 | 1 & 2;

warning: suggest parentheses around arithmetic in operand of '|'
[-Wparentheses]
3 | int i = 0 | 1 & 2;
  | ~~^~~

The expected behavior would be for `diagnostic ignored "-Wall"` to suppress all
the warnings that were enabled by `diagnostic warning "-Wall"`. If this isn't
possible, it would be good to emit a diagnostic that `diagnostic ignored
"-Wall"` has no effect.

Clang does support this and appears to have always done so.

[Bug libstdc++/109882] New: -fsanitize=thread #include transitively includes sanitizer/common_interface_defs.h

2023-05-16 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109882

Bug ID: 109882
   Summary: -fsanitize=thread #include  transitively
includes sanitizer/common_interface_defs.h
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since 12.3.0, when compiled under tsan (-fsanitize=thread), #include 
transitively includes sanitizer/common_interface_defs.h:

#include 
#if defined SANITIZER_COMMON_INTERFACE_DEFS_H
#error :(
#endif

This is problematic for us because sanitizer/common_interface_defs.h has
#define __has_feature(x) 0
https://github.com/gcc-mirror/gcc/blame/5d85b5d649fff675ff00adcc99371bccf4ef5944/libsanitizer/include/sanitizer/common_interface_defs.h#L20

which makes our sanitizer detector incorrectly believe that __has_feature is
available and that tsan is not in fact present since
__has_feature(thread_sanitizer) evaluates to 0.

We will fix the order of checks to put `#ifdef __SANITIZE_THREAD__` first but
thought we should probably report this to help other users.

[Bug c++/109870] New: Miscomputation of return type of unevaluated lambda in type alias in template context

2023-05-15 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109870

Bug ID: 109870
   Summary: Miscomputation of return type of unevaluated lambda in
type alias in template context
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

template struct X {};
template
struct M {
using R = decltype([] { return 1; }());
template struct S { X p; };
};
M::S s;

9.1 through 14.0.0 trunk reject with:

: In instantiation of 'struct M::S':
:7:17:   required from here
:4:36: error: return-statement with a value, in function returning
'void' [-fpermissive]
4 | using R = decltype([] { return 1; }());
  |^

It appears the `U` type parameter in `M::S` is overwriting the lambda
deduced return type.

Possibly related to #92707, #103569

[Bug sanitizer/83780] False positive alignment error with -fsanitize=undefined with virtual base

2023-05-01 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83780

--- Comment #4 from Ed Catmur  ---
Clang has fixed this in
https://github.com/llvm/llvm-project/commit/4ddf140c00408ecee9d20f4470e69e0f696d8f8a
(12.0.0-rc1).

[Bug c++/109677] New: Access control bypass for function template default argument brace initialization of private default constructor

2023-04-28 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109677

Bug ID: 109677
   Summary: Access control bypass for function template default
argument brace initialization of private default
constructor
   Product: gcc
   Version: 13.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

gcc accepts-invalid:

struct B { private: B(); };
template int f(T = {});
int i = f();

This is mostly a curiosity, but it came up while trying to understand why a
misuse of the passkey pattern was seemingly working.

[Bug c++/109640] Spurious Wdangling-reference for argument to temporary lambda cast to rvalue reference

2023-04-26 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109640

--- Comment #2 from Ed Catmur  ---
Ah, so this is Bug 108165? That's a shame, we use (temporary) lambdas
extensively so I think we'd have to disable the warning entirely.

[Bug c++/109640] New: Spurious Wdangling-reference for argument to temporary lambda cast to rvalue reference

2023-04-26 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109640

Bug ID: 109640
   Summary: Spurious Wdangling-reference for argument to temporary
lambda cast to rvalue reference
   Product: gcc
   Version: 13.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

bool b() {
int a;
int&& i = [](int& r) -> int&& { return static_cast(r); }(a);
auto const l = [](int& r) -> int&& { return static_cast(r); };
int&& j = l(a);
return  == 
}

: In function 'bool b()':
:3:11: warning: possibly dangling reference to a temporary
[-Wdangling-reference]
3 | int&& i = [](int& r) -> int&& { return static_cast(r); }(a);
  |   ^
:3:68: note: the temporary was destroyed at the end of the full
expression 'b()::().b()::(a)'
3 | int&& i = [](int& r) -> int&& { return static_cast(r); }(a);
  |   ~^~~

The heuristic appears to be confused by the lambda itself being a temporary,
even though it is captureless.

[Bug c++/109070] New: ICE in class template member function overloads distinguished by non-functionally-equivalent constraints and return type

2023-03-08 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109070

Bug ID: 109070
   Summary: ICE in class template member function overloads
distinguished by non-functionally-equivalent
constraints and return type
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

template concept C = true;
template struct A {
int f() requires C<42> { return 1; }  // #1
unsigned f() requires true { return 2u; }  // #2
};
int main() {
int (A::*p)() = ::f;
unsigned (A::*q)() = ::f;
return (A().*p)() + (A().*q)();
}

:10:1: error: Two symbols with same comdat_group are not linked by the
same_comdat_group list.
   10 | }
  | ^
_ZN1AIiE1fEv/2 (unsigned int A::f() requires  true [with T = int])
  Type: function definition analyzed
  Visibility: semantic_interposition public weak comdat
comdat_group:_ZN1AIiE1fEv one_only
  previous sharing asm name: 1
  Address is taken.
  References: 
  Referring: main/0 (addr) 
  Function flags: body
  Called by: 
  Calls: 
_ZN1AIiE1fEv/1 (int A::f() requires  C<42> [with T = int])
  Type: function definition analyzed
  Visibility: semantic_interposition public weak comdat
comdat_group:_ZN1AIiE1fEv one_only
  next sharing asm name: 2
  Address is taken.
  References: 
  Referring: main/0 (addr) 
  Function flags: body
  Called by: 
  Calls: 
:10:1: internal compiler error: symtab_node::verify failed
0x247b73e internal_error(char const*, ...)
???:0
0xed5c22 symtab_node::verify_symtab_nodes()
???:0
0xef042b symbol_table::finalize_compilation_unit()
???:0

This is valid per [temp.over.link]/5, but that seems impossible to implement -
I've filed https://github.com/cplusplus/CWG/issues/256.

[Bug c++/79682] [concepts] ambiguous overload with functionally equivalent predicate constraints compiles

2023-03-08 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79682

Ed Catmur  changed:

   What|Removed |Added

 CC||ed at catmur dot uk

--- Comment #2 from Ed Catmur  ---
I think this was made IFNDR by CWG2603?

[Bug c++/70536] g++ doesn't emit DW_AT_name for DW_TAG_GNU_formal_parameter_pack

2023-02-04 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70536

--- Comment #6 from Ed Catmur  ---
Resubmitted:
https://gcc.gnu.org/pipermail/gcc-patches/2023-February/611366.html
Hopefully this time I'll remember to save the email for pinging.

[Bug c++/108468] New: ICE in most_specialized_partial_spec/builtin_guide_p in C++20 mode

2023-01-19 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108468

Bug ID: 108468
   Summary: ICE in most_specialized_partial_spec/builtin_guide_p
in C++20 mode
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since 11.1, the following ices in -std=c++20 and later:

template struct C { template static constexpr int x = 1; };
template template int C::x = 2;
int y = C<0>::x;

0x23ae54e internal_error(char const*, ...)
???:0
0xc5b614 deduction_guide_p(tree_node const*)
???:0
0xc5be2c builtin_guide_p(tree_node const*)
???:0
0xc82bdf most_specialized_partial_spec(tree_node*, int)
???:0
0xc83a76 instantiate_template(tree_node*, tree_node*, int)
???:0
0xc8c0d8 finish_template_variable(tree_node*, int)
???:0
0xcce05f finish_id_expression(tree_node*, tree_node*, tree_node*, cp_id_kind*,
bool, bool, bool*, bool, bool, bool, bool, char const**, unsigned int)
???:0

[Bug c++/70536] g++ doesn't emit DW_AT_name for DW_TAG_GNU_formal_parameter_pack

2023-01-13 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70536

--- Comment #5 from Ed Catmur  ---
PR: https://github.com/ecatmur/gcc/pull/5

[Bug c++/108390] New: ICE in fold_convert_loc, at fold-const.cc:2504 partial ordering between array types

2023-01-12 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108390

Bug ID: 108390
   Summary: ICE in fold_convert_loc, at fold-const.cc:2504 partial
ordering between array types
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

template long f(int(*)[t], T(*)[t]);
template int f(int(*)[i], T(*)[i]);
int n = f(0, 0);

:4:18: internal compiler error: in fold_convert_loc, at
fold-const.cc:2504
4 | int n = f(0, 0);
  | ~^~
0x23975be internal_error(char const*, ...)
???:0
0xa693ae fancy_abort(char const*, int, char const*)
???:0
0xc99848 more_specialized_fn(tree_node*, tree_node*, int)
???:0
0xa97529 build_new_function_call(tree_node*, vec**, int)
???:0
0xcb6fd4 finish_call_expr(tree_node*, vec**, bool,
bool, int)
???:0
0xc43be7 c_parse_file()
???:0
0xd7fd79 c_common_parse_file()
???:0

Godbolt says this is bad back to 8.1; before that it was ambiguous.

[Bug c++/107206] New: Bogus -Wuninitialized in std::optional

2022-10-10 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107206

Bug ID: 107206
   Summary: Bogus -Wuninitialized in std::optional
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since 12, at -std=c++17 -O -Wuninitialized:

#include 
struct X {
X() = default;
X(X const& r) : i(r.i) {}
int i;
};
struct Y {
Y() : x() {}
X x;
std::optional o;
};
struct Z {
Y y;
explicit Z(Y y) : y(y) {}
};
void f(Y const&);
void test() {
Y const y;
Z z(y);
z.y.o = 1;
auto const w = z;
f(w.y);
}

In copy constructor 'Y::Y(const Y&)',
inlined from 'void test()' at :19:10:
:7:8: warning: '*(int*)((char*) + offsetof(const Y,
Y::o.std::optional::.std::_Optional_base::))' is used uninitialized [-Wuninitialized]
7 | struct Y {
  |^
: In function 'void test()':
:18:13: note: 'y' declared here
   18 | Y const y;
  | ^

Most similar to #80635 and #86465, I think? Although this is -Wuninitialized,
not -Wmaybe-uninitialized.

[Bug c++/106712] Incorrect propagation of C++11 attributes to subsequent function declarations

2022-08-22 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106712

--- Comment #1 from Ed Catmur  ---
I believe this is happening because start_decl can modify prefix_attributes (by
first chaining it onto attributes, then passing the merged chain to
grokdeclarator  which can then chain onto that merged chain).  If the attribute
list is empty, prefix_attributes is NULL_TREE and so is not affected.

If so, the simplest fix would be for start_decl to copy_list(prefix_attributes)
prior to chaining it.

[Bug c++/106712] New: Incorrect propagation of C++11 attributes to subsequent function declarations

2022-08-22 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106712

Bug ID: 106712
   Summary: Incorrect propagation of C++11 attributes to
subsequent function declarations
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

In [[first-attribute]] int f [[second-attribute]](), g();

the [[first-attribute]] should apply to both f and g, the [[second-attribute]]
to f only:

> The attribute-specifier-seq appertains to each of the entities declared by 
> the declarators of the init-declarator-list.
http://eel.is/c++draft/dcl.dcl#dcl.pre-3.sentence-5

> The attribute-specifier-seq affects the type only for the declaration it 
> appears in, not other declarations involving the same type.
http://eel.is/c++draft/dcl.dcl#dcl.spec.general-1.sentence-3

However, gcc instead applies [[second-attribute]] to both functions, but only
if [[first-attribute]] is non-empty.

This can lead to rejects-valid:

[[gnu::cold]] int g() { return 1; }
[[gnu::cold]] int f [[gnu::fastcall]](), g(); // error: ambiguating new
declaration of 'int g()'

Or to miscompilation, e.g.:

[[gnu::cold]] int f [[gnu::const]](), g();
int g() {
static int i;
return ++i;
}
#include 
int main() { assert(g() + g() == 3); } // fails

Or erroneous warnings (with only standard attributes):

[[noreturn]] int f [[nodiscard]](), g();
int main() { g(); }

[Bug c++/106411] New: Wdangling-pointer for a class that cleans up on destruction

2022-07-22 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106411

Bug ID: 106411
   Summary: Wdangling-pointer for a class that cleans up on
destruction
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Reduced testcase:

#include 
void g(auto f1) {
auto f2 = std::move(f1);
}
struct F;
struct E {
F* f = nullptr;
};
struct F {
E* e;
explicit F(E* a) : e(a) { e->f = this; }
~F() {
if (e)
e->f = nullptr;
}
F(F&& rhs) : e(std::exchange(rhs.e, nullptr)) {
e->f = this;
}
};
int main() {
E e;
F f();
g(std::move(f));
}

At -O -Wall in 12.1 and current trunk 13.0.0:

In constructor 'F::F(F&&)',
inlined from 'void g(auto:1) [with auto:1 = F]' at :3:10,
inlined from 'int main()' at :23:6:
:17:14: warning: storing the address of local variable 'f2' in
'*__old_val.E::f' [-Wdangling-pointer=]
   17 | e->f = this;
  | ~^~
: In function 'int main()':
:3:10: note: 'f2' declared here
3 | auto f2 = std::move(f1);
  |  ^~
:3:10: note: '.F::e' declared here

It would be helpful if Wdangling-pointer could realize that the stored address
will be cleared when the local variable is destroyed.

Here `g` is reduced from `boost::asio::detail::executor_function::complete` and
`F` is reduced from our own callback type.  The above reduced testcase only
repros at -O but our unreduced code repros at -O3.

[Bug c++/106074] Spurious Wstringop-overflow for int-to-string with SSE4

2022-07-07 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106074

--- Comment #1 from Ed Catmur  ---
Another example, using Date 3.0.1:

#include 
void f(std::istream s) {
std::chrono::system_clock::time_point tp;
date::from_stream(s, "%Y", tp);
}

https://godbolt.org/z/fscqTd947

In file included from
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_pair.h:61,
 from
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:64,
 from
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/algorithm:60,
 from
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:44,
 from :1:
In function 'constexpr std::_Require >,
std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&,
_Tp&) [with _Tp = char]',
inlined from 'constexpr void std::iter_swap(_ForwardIterator1,
_ForwardIterator2) [with _ForwardIterator1 = char*; _ForwardIterator2 = char*]'
at
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:182:11,
inlined from 'constexpr void std::__reverse(_RandomAccessIterator,
_RandomAccessIterator, random_access_iterator_tag) [with _RandomAccessIterator
= char*]' at
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1107:18,
inlined from 'constexpr void std::reverse(_BIter, _BIter) [with _BIter =
char*]' at
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1134:21,
inlined from 'void date::detail::read(std::basic_istream<_CharT, _Traits>&,
int, Args&& ...) [with CharT = char; Traits = std::char_traits; Args =
{char&, const char&}]' at
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6513:21,
inlined from 'void date::detail::read(std::basic_istream<_CharT, _Traits>&,
CharT, Args&& ...) [with CharT = char; Traits = std::char_traits; Args =
{int&, char&, const char&}]' at
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6474:9:
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/move.h:205:11:
warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  205 |   __a = _GLIBCXX_MOVE(__b);
  |   ^
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h: In function 'void
date::detail::read(std::basic_istream<_CharT, _Traits>&, CharT, Args&& ...)
[with CharT = char; Traits = std::char_traits; Args = {int&, char&, const
char&}]':
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at
offset 19 into destination object 'buf' of size 11
 6506 | CharT buf[std::numeric_limits::digits10+2u] = {};
  |   ^~~
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at
offset [3, 11] into destination object 'buf' of size 11
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at
offset 19 into destination object 'buf' of size 11
In function 'constexpr std::_Require >,
std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&,
_Tp&) [with _Tp = char]',
inlined from 'constexpr void std::iter_swap(_ForwardIterator1,
_ForwardIterator2) [with _ForwardIterator1 = char*; _ForwardIterator2 = char*]'
at
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:182:11,
inlined from 'constexpr void std::__reverse(_RandomAccessIterator,
_RandomAccessIterator, random_access_iterator_tag) [with _RandomAccessIterator
= char*]' at
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1107:18,
inlined from 'constexpr void std::reverse(_BIter, _BIter) [with _BIter =
char*]' at
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1134:21,
inlined from 'void date::detail::read(std::basic_istream<_CharT, _Traits>&,
int, Args&& ...) [with CharT = char; Traits = std::char_traits; Args =
{char&, const char&}]' at
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6513:21,
inlined from 'void date::detail::read(std::basic_istream<_CharT, _Traits>&,
CharT, Args&& ...) [with CharT = char; Traits = std::char_traits; Args =
{int&, char&, const char&}]' at
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6474:9:
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/move.h:205:11:
warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  205 |   __a = _GLIBCXX_MOVE(__b);
  |   ^
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h: In function 'void
date::detail::read(std::basic_istream<_CharT, _Traits>&, CharT, Args&& ...)
[with CharT = char; Traits = std::char_traits; Args = {int&, char&, const
char&}]':
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at
offset 20 into destination object 'buf' of size 11
 6506 | CharT buf[std::numeric_limits::digits10+2u] = {};
  |   ^~~
/opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at
offset [4, 11] into destination object 'buf' of size 11

[Bug c++/106185] New: Spurious Wstringop-overflow in std::vector::resize

2022-07-04 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106185

Bug ID: 106185
   Summary: Spurious Wstringop-overflow in std::vector::resize
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Since 12.1.0:
At -O3 -std=c++20 -Werror=stringop-overflow:

#include 
void f() {
std::vector v;
v.resize(26);
v.resize(33);
v.resize(39);
v.resize(47);
v.resize(v.size() + 8);
}

In file included from gcc-12.1.0/include/c++/12.1.0/vector:60,
 from :1:
In function 'constexpr typename
__gnu_cxx::__enable_if::__value, void>::__type
std::__fill_a1(_Tp*, _Tp*, const _Tp&) [with _Tp = char]',
inlined from 'constexpr void std::__fill_a(_FIte, _FIte, const _Tp&) [with
_FIte = char*; _Tp = char]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:968:21,
inlined from 'constexpr _OutputIterator std::__fill_n_a(_OutputIterator,
_Size, const _Tp&, random_access_iterator_tag) [with _OutputIterator = char*;
_Size = long unsigned int; _Tp = char]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:1119:20,
inlined from 'constexpr _OI std::fill_n(_OI, _Size, const _Tp&) [with _OI =
char*; _Size = long unsigned int; _Tp = char]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:1148:29,
inlined from 'static constexpr _ForwardIterator
std::__uninitialized_default_n_1::__uninit_default_n(_ForwardIterator,
_Size) [with _ForwardIterator = char*; _Size = long unsigned int]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_uninitialized.h:663:29,
inlined from 'static constexpr _ForwardIterator
std::__uninitialized_default_n_1::__uninit_default_n(_ForwardIterator,
_Size) [with _ForwardIterator = char*; _Size = long unsigned int]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_uninitialized.h:655:9,
inlined from 'constexpr _ForwardIterator
std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator
= char*; _Size = long unsigned int]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_uninitialized.h:701:20,
inlined from 'constexpr _ForwardIterator
std::__uninitialized_default_n_a(_ForwardIterator, _Size, allocator<_Tp>&)
[with _ForwardIterator = char*; _Size = long unsigned int; _Tp = char]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_uninitialized.h:766:44,
inlined from 'constexpr void std::vector<_Tp,
_Alloc>::_M_default_append(size_type) [with _Tp = char; _Alloc =
std::allocator]' at gcc-12.1.0/include/c++/12.1.0/bits/vector.tcc:642:35,
inlined from 'constexpr void std::vector<_Tp, _Alloc>::resize(size_type)
[with _Tp = char; _Alloc = std::allocator]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:1011:21,
inlined from 'void f()' at :8:13:
gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:942:25: error: 'void*
__builtin_memset(void*, int, long unsigned int)' writing 7 bytes into a region
of size 4 overflows the destination [-Werror=stringop-overflow=]
  942 | __builtin_memset(__first, static_cast(__tmp),
__len);
  |
^~~
In file included from
gcc-12.1.0/include/c++/12.1.0/x86_64-linux-gnu/bits/c++allocator.h:33,
 from gcc-12.1.0/include/c++/12.1.0/bits/allocator.h:46,
 from gcc-12.1.0/include/c++/12.1.0/vector:61:
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const
void*) [with _Tp = char]',
inlined from 'constexpr _Tp* std::allocator< 
>::allocate(std::size_t) [with _Tp = char]' at
gcc-12.1.0/include/c++/12.1.0/bits/allocator.h:183:40,
inlined from 'static constexpr _Tp*
std::allocator_traits >::allocate(allocator_type&,
size_type) [with _Tp = char]' at
gcc-12.1.0/include/c++/12.1.0/bits/alloc_traits.h:464:28,
inlined from 'constexpr std::_Vector_base<_Tp, _Alloc>::pointer
std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = char;
_Alloc = std::allocator]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:378:33,
inlined from 'constexpr void std::vector<_Tp,
_Alloc>::_M_default_append(size_type) [with _Tp = char; _Alloc =
std::allocator]' at gcc-12.1.0/include/c++/12.1.0/bits/vector.tcc:650:45,
inlined from 'constexpr void std::vector<_Tp, _Alloc>::resize(size_type)
[with _Tp = char; _Alloc = std::allocator]' at
gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:1011:21,
inlined from 'void f()' at :5:13:
gcc-12.1.0/include/c++/12.1.0/bits/new_allocator.h:137:55: note: at offset [48,
52] into destination object of size 52 allocated by 'operator new'
  137 | return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp)));
  |   ^
cc1plus: some warnings being treated as errors

[Bug middle-end/103993] -Wismatched-new-delete due to difference in inlining decisions

2022-06-29 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103993

--- Comment #4 from Ed Catmur  ---
And another example, provoked by throwing new (this only happens at -Og):

#include 
struct D {
D();
static void* operator new (std::size_t s) {
if (void* p = ::malloc(s))
return p;
throw "bad_alloc";
}
static void operator delete (void* p) { ::free(p); }
};
int main() { new D; }

[Bug c++/106074] New: Spurious Wstringop-overflow for int-to-string with SSE4

2022-06-24 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106074

Bug ID: 106074
   Summary: Spurious Wstringop-overflow for int-to-string with
SSE4
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Code adapted from
https://github.com/capnproto/capnproto/blob/be7a80b4add706ddaeb41689221146b86c3e0f5f/c%2B%2B/src/kj/string.c%2B%2B#L157-L203
:

auto f(short i) {
  struct R { char data[6]; } result;
  bool negative = i < 0;
  unsigned u = i;
  if (negative)
u = -u;
  unsigned char reverse[5];
  unsigned char* p = reverse;
  if (u == 0)
*p++ = 0;
  else
for (; u > 0; u /= 10)
  *p++ = u % 10;
  char* p2 = result.data;
  if (negative)
*p2++ = '-';
  while (p > reverse) {
#ifdef ASSUME
if (p2 >= ()[1]) __builtin_unreachable();
#endif
*p2++ = '0' + *--p;
  }
  if (p2 < ()[1])
*p2 = '\0';
  return result;
}

When compiled with -O3 -msse4, from 12.1.0 through 13.0.0 20220619:

: In function 'auto f(short int)':
:21:11: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
   21 | *p2++ = '0' + *--p;
  | ~~^~~~
:2:19: note: at offset 6 into destination object 'f(short
int)::R::data' of size 6
2 |   struct R { char data[6]; } result;
  |   ^~~~
:2:30: note: at offset 7 into destination object 'result' of size 6
2 |   struct R { char data[6]; } result;
  |  ^~
:2:19: note: at offset 6 into destination object 'f(short
int)::R::data' of size 6
2 |   struct R { char data[6]; } result;
  |   ^~~~
:2:19: note: at offset 6 into destination object 'f(short
int)::R::data' of size 6
:2:30: note: at offset 7 into destination object 'result' of size 6
2 |   struct R { char data[6]; } result;
  |  ^~
:2:19: note: at offset 6 into destination object 'f(short
int)::R::data' of size 6
2 |   struct R { char data[6]; } result;
  |   ^~~~
:2:19: note: at offset 6 into destination object 'f(short
int)::R::data' of size 6
:2:30: note: at offset 7 into destination object 'result' of size 6
2 |   struct R { char data[6]; } result;
  |  ^~
:2:19: note: at offset 6 into destination object 'f(short
int)::R::data' of size 6
2 |   struct R { char data[6]; } result;
  |   ^~~~
:2:19: note: at offset 6 into destination object 'f(short
int)::R::data' of size 6
:2:30: note: at offset 7 into destination object 'result' of size 6
2 |   struct R { char data[6]; } result;
  |  ^~
:2:19: note: at offset 6 into destination object 'f(short
int)::R::data' of size 6
2 |   struct R { char data[6]; } result;
  |   ^~~~

Adding the assumption at line 19 (-DASSUME) works around this.

[Bug c++/105918] New: Spurious Warray-bounds in std::to_chars

2022-06-10 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105918

Bug ID: 105918
   Summary: Spurious Warray-bounds in std::to_chars
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

#include 
template
std::to_chars_result toChars(char (& buf)[N], int number) {
char temp[N];
std::to_chars_result result = std::to_chars(temp, temp + N, number);
if (result.ec != std::errc())
return result;
char* it = temp;
char* end = result.ptr;
std::size_t i = 0u;
while (i != N && it != end)
buf[i++] = *it++;
if (i != N)
buf[i] = '\0';
return std::to_chars_result{.ptr = buf + (result.ptr - temp), .ec =
std::errc()};
}
#include 
struct ar {
struct V { bool value; } value;
std::unique_ptr s;
};
void f(...);
ar g();
ar evaluate(bool value) {
ar res{value};
if (res.value.value)
return res;
return g();
}
#define CHECK(P) f(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, evaluate(P), 0, 0, 0, 0, 0, 0,
0, 0, 0 );
int main() {
char s3[3];
auto res3 = toChars(s3, 12);
CHECK((res3.ec == std::errc()));
CHECK((s3[0] == '1'));
CHECK((s3[1] == '2'));
CHECK((s3[2] == '\0'));
char s1[1];
auto res1 = toChars(s1, 12);
CHECK((res1.ec != std::errc()));
}

Compiled at -O3 -Warray-bounds:

In file included from include/c++/12.1.0/charconv:42,
 from :1:
In function 'void std::__detail::__to_chars_10_impl(char*, unsigned int, _Tp)
[with _Tp = unsigned int]',
inlined from 'std::__detail::__integer_to_chars_result_type<_Tp>
std::__detail::__to_chars_10(char*, char*, _Tp) [with _Tp = unsigned int]' at
include/c++/12.1.0/charconv:225:35,
inlined from 'std::__detail::__integer_to_chars_result_type<_Tp>
std::__to_chars_i(char*, char*, _Tp, int) [with _Tp = int]' at
include/c++/12.1.0/charconv:351:32,
inlined from 'std::to_chars_result std::to_chars(char*, char*, int, int)'
at include/c++/12.1.0/charconv:370:1,
inlined from 'std::to_chars_result toChars(char (&)[N], int) [with int N =
1]' at :7:48:
include/c++/12.1.0/bits/charconv.h:95:22: warning: array subscript 1 is outside
array bounds of 'char [1]' [-Warray-bounds]
   95 |   __first[1] = __digits[__num + 1];
  |   ~~~^~~
: In function 'std::to_chars_result toChars(char (&)[N], int) [with int
N = 1]':
:6:10: note: at offset 1 into object 'temp' of size 1
6 | char temp[N];
  |  ^~~~
:6:10: note: at offset 2 into object 'temp' of size 1
Compiler returned: 0

[Bug c/105585] [12/13 Regression] Spurious stringop-overflow warning with

2022-05-12 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105585

--- Comment #2 from Ed Catmur  ---
Affected code: https://github.com/abseil/abseil-cpp/issues/1175
The proposed patch to abseil-cpp corresponds to adding an assumption that `b`
is true above.

[Bug c/105585] [12/13 Regression] Spurious stringop-overflow warning with

2022-05-12 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105585

--- Comment #1 from Ed Catmur  ---
Flags: -O1 -Wstringop-overflow=1
https://godbolt.org/z/8r8roz7Pa

[Bug c/105585] New: [12/13 Regression] Spurious stringop-overflow warning with

2022-05-12 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105585

Bug ID: 105585
   Summary: [12/13 Regression] Spurious stringop-overflow warning
with 
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Reduced (from code in abseil-cpp):

#include 
struct S {
  int i;
  std::atomic a;
};
S* q();
void f();
void g(bool b) {
  auto p = b ? q() : nullptr;
  ++p->a;
  if (p)
f();
}

In file included from atomic:41,
 from :1:
In member function 'std::__atomic_base<_IntTp>::__int_type
std::__atomic_base<_IntTp>::operator++() [with _ITp = int]',
inlined from 'void g(bool)' at :10:3:
bits/atomic_base.h:385:34: warning: 'unsigned int __atomic_add_fetch_4(volatile
void*, unsigned int, int)' writing 4 bytes into a region of size 0 overflows
the destination [-Wstringop-overflow=]
  385 |   { return __atomic_add_fetch(&_M_i, 1, int(memory_order_seq_cst));
}
  |~~^

[Bug tree-optimization/105545] [12/13 Regression] Warning for string assignment with _GLIBCXX_ASSERTIONS since r12-3347-g8af8abfbbace49e6

2022-05-12 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105545

Ed Catmur  changed:

   What|Removed |Added

 CC||ed at catmur dot uk

--- Comment #3 from Ed Catmur  ---
I don't think _GLIBCXX_ASSERTIONS is necessary; you just need -Werror=restrict
and -O2 (not sure what exactly). https://godbolt.org/z/TvfYzbcf6

[Bug c++/105425] New: ambiguous template instantiation with hana::when

2022-04-28 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105425

Bug ID: 105425
   Summary: ambiguous template instantiation with hana::when
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

Simplified:

template struct when;
template constexpr int B = 1;
template struct A;
template struct A> {}; // fallback
template struct A == 1>> {};
A> a;

"B<0> == 1" is sufficiently complex (?) to trigger the bug (it doesn't need to
be dependent on C) but "B<0>" on its own isn't.

This affects hana since it uses the when pattern heavily.

Per godbolt 11.3.0 is good, 12.0.1 20220426 is bad.

[Bug libstdc++/105027] New: Missing constraints on std::bit_cast

2022-03-22 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027

Bug ID: 105027
   Summary: Missing constraints on std::bit_cast
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

[bit.cast] Constraints (nb. prior to P1719R2 these were specified as SFINAE,
but they have been there since the start):
(1.1) sizeof(To) == sizeof(From) is true;
(1.2) is_­trivially_­copyable_­v is true; and
(1.3) is_­trivially_­copyable_­v is true.

#include 
template
concept BitCastable = requires(U u) { std::bit_cast(u); };
static_assert(BitCastable); // OK
static_assert(BitCastable); // #1: different size
struct A { A(A const&); int i; };
static_assert(BitCastable); // #2: not trivially copyable

#1 and #2 are erroneously accepted although the corresponding call to
std::bit_cast would fail internally; MSVC and clang (with libc++) correctly
reject.

static_assert(BitCastable); // #3: see below
int f();
long l = std::bit_cast(f); // #4

By my reading of [temp.deduct] #3 should be a hard error, since sizeof(int())
is not only invalid; it is not SFINAE. However, compilers that allow it (gcc
everywhere, MSVC and clang as SFINAE) should then reject either by SFINAE, or
as having the incorrect size, or since function types are not trivially
copyable; gcc/libstdc++ does not and also accepts #4, decaying the function
reference to a function pointer; clang/libstdc++ rejects within its own
__builtin_bit_cast.

[Bug c++/104996] [10/11/12 Regression] Overload resolution over rvalue/const lvalue array reference parameters for an init. list argument incorrectly picks the const lvalue ref. overload

2022-03-22 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104996

--- Comment #5 from Ed Catmur  ---
Posted https://gcc.gnu.org/pipermail/gcc-patches/2022-March/592154.html

[Bug c++/104996] [10/11/12 Regression] Overload resolution over rvalue/const lvalue array reference parameters for an init. list argument incorrectly picks the const lvalue ref. overload

2022-03-21 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104996

--- Comment #4 from Ed Catmur  ---
(In reply to Patrick Palka from comment #2)
> We started rejecting the commented out static_assert after
> r10-3740-g89e0a492af5bec.

Thanks, that accords with my analysis - the branch in call.cc:compare_ics that
should be refined to take only if the two arrays have same element type was
added there.

[Bug c++/104996] Overload resolution over rvalue/const lvalue array reference parameters for an init. list argument incorrectly picks the const lvalue ref. overload

2022-03-21 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104996

--- Comment #1 from Ed Catmur  ---
This should fix it:

https://github.com/gcc-mirror/gcc/compare/master...ecatmur:pr-104996

Please test and report back.

[Bug c++/69623] Invalid deduction of non-trailing template parameter pack

2022-03-15 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69623

--- Comment #8 from Ed Catmur  ---
(In reply to jim x from comment #7)
> 
> auto f(auto..., auto a, auto...) { return a; }
> 
> IIUC, this is just disallowed since all arguments would only match the first
> function parameter pack.

Maybe? But all 4 major compilers currently permit it (with identical behavior),
so is it worth breaking existing code by disallowing it?

[Bug c++/69623] Invalid deduction of non-trailing template parameter pack

2022-03-14 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69623

Ed Catmur  changed:

   What|Removed |Added

 CC||ed at catmur dot uk

--- Comment #6 from Ed Catmur  ---
There is a fairly well-known idiom for extracting a specific element of an
argument pack:

auto f(auto..., auto a, auto...) { return a; }
template struct any { any(auto) {} };
template
auto g(std::index_sequence, auto... a) { return f...>(a...); }
template
auto h(auto... a) { return g(std::make_index_sequence(), a...); }

I believe the intent of http://eel.is/c++draft/temp#param-14.sentence-3 is that
this idiom should work; per http://eel.is/c++draft/temp#param-example-7 (as in
comment #5) a function template secondary template parameter pack is only
disallowed if it is nondeducible.  In the original description of this ticket
(not comment #5, which I agree is disallowed) T is specifiable and U is
deducible, so both are OK.

> [...] A template parameter pack of a function template shall not be followed 
> by another template parameter unless that template parameter can be deduced 
> from the parameter-type-list ([dcl.fct]) of the function template or has a 
> default argument ([temp.deduct]). [...]

Or is the intent that T must be explicitly specified, i.e. that f can be called
as f<>() but not as f(), pace
http://eel.is/c++draft/temp#arg.explicit-4.sentence-3 ?

> If all of the template arguments can be deduced, they may all be omitted; in 
> this case, the empty template argument list <> itself may also be omitted.

[Bug c++/70536] g++ doesn't emit DW_AT_name for DW_TAG_GNU_formal_parameter_pack

2022-03-13 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70536

--- Comment #4 from Ed Catmur  ---
Posted: https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591678.html

[Bug c++/77465] [DR909] rejected C-style cast involving casting away constness from result of conversion operator

2022-03-13 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77465

--- Comment #4 from Ed Catmur  ---
Branch: https://github.com/gcc-mirror/gcc/compare/master...ecatmur:so-66816741

[Bug c++/70536] g++ doesn't emit DW_AT_name for DW_TAG_GNU_formal_parameter_pack

2022-03-12 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70536

--- Comment #3 from Ed Catmur  ---
Updated: https://github.com/gcc-mirror/gcc/compare/master...ecatmur:pr-70536

[Bug c++/77465] [DR909] rejected C-style cast involving casting away constness from result of conversion operator

2021-12-30 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77465

--- Comment #3 from Ed Catmur  ---
Sent patches to mailing list:
https://gcc.gnu.org/pipermail/gcc-patches/2021-December/587495.html

[Bug c++/92944] [concepts] redefinition error when using constrained structure template inside namespace

2021-12-17 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92944

--- Comment #2 from Ed Catmur  ---
Sorry, meant to link this:
https://quuxplusone.github.io/blog/2021/10/27/dont-reopen-namespace-std/

[Bug c++/92944] [concepts] redefinition error when using constrained structure template inside namespace

2021-12-14 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92944

--- Comment #1 from Ed Catmur  ---
This becomes problematic when N::Q is std::hash; we are encouraged not to
reopen namespace std but to specialize std::hash from the root namespace.

Example:

#include 
template constexpr bool P = false;
template constexpr bool Q = false;
template requires P struct std::hash { std::size_t operator()(T)
{ return 1; } };
template requires Q struct std::hash { std::size_t operator()(U)
{ return 2; } };
struct S {};
template<> constexpr bool P = true;
int i = std::hash()(S());

clang and MSVC correctly accept this.

[Bug c++/102047] ICE in template_parms_to_args passing lambda-quoted constraint to meta-concept

2021-08-24 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102047

--- Comment #1 from Ed Catmur  ---
cf. https://bugs.llvm.org/show_bug.cgi?id=51604

[Bug c++/102047] New: ICE in template_parms_to_args passing lambda-quoted constraint to meta-concept

2021-08-24 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102047

Bug ID: 102047
   Summary: ICE in template_parms_to_args passing lambda-quoted
constraint to meta-concept
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

template concept A = true;
template concept M = requires {
L.template operator()();
};
template concept C = requires(T t) {
{ t.x } -> M<[](){}>;
};
struct S { double x; };
static_assert(C);

g++
(Compiler-Explorer-Build-gcc-8ca7fa84a3af355c3e2bbda2acc61934c16078b2-binutils-2.36.1)
12.0.0 20210823 (experimental)

6:18: internal compiler error: Segmentation fault
6 | { t.x } -> M<[](){}>;
  |  ^
0x1de2c99 internal_error(char const*, ...)
0x99d20d template_parms_to_args(tree_node*)
0x9e74ea tsubst_lambda_expr(tree_node*, tree_node*, int, tree_node*)
0x9db8d0 tsubst_template_arg(tree_node*, tree_node*, int, tree_node*)
0x7d702a constraints_satisfied_p(tree_node*, tree_node*)
0x9a6a67 do_auto_deduction(tree_node*, tree_node*, tree_node*, int,
auto_deduction_context, tree_node*, int)
0x7d6fe2 tsubst_requires_expr(tree_node*, tree_node*, int, tree_node*)
0x7d7088 evaluate_concept_check(tree_node*)
0x7c26f4 maybe_constant_value(tree_node*, tree_node*, bool)
0xa2b65d finish_static_assert(tree_node*, tree_node*, unsigned int, bool, bool)
0x980395 c_parse_file()
0xb05462 c_common_parse_file()

Clang also ICEs; MSVC accepts.

Possibly related to #99465.

[Bug c++/101988] New: Accepts invalid new-expression of array of deduced class template

2021-08-19 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101988

Bug ID: 101988
   Summary: Accepts invalid new-expression of array of deduced
class template
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

template struct A { A(T); };
auto p = new A[]{1};

g++
(Compiler-Explorer-Build-gcc-f0fca213bc52644ba896da622b35842a6157bd98-binutils-2.36.1)
12.0.0 20210818 (experimental) accepts (it allocates and constructs a single
`A`.

gcc 11.2 and below rejects, correctly: error: creating array of 'A<...auto...>'

Per [expr.new]/2 the invented declaration should be:
A[] x{1};
which is ill-formed.

nb. clang ICEs on this (https://bugs.llvm.org/show_bug.cgi?id=51547)

[Bug sanitizer/100878] enabling UBSAN leads to false positive `'this' pointer is null` when casting lambda to function pointer

2021-07-20 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100878

--- Comment #1 from Ed Catmur  ---
Per godbolt, this appears to be fixed on trunk: https://godbolt.org/z/xxz8ecxzK

g++
(Compiler-Explorer-Build-gcc-48e8a7a677b8356df946cd12fbb215538828e747-binutils-2.36.1)
12.0.0 20210707 (experimental)

[Bug c++/99994] New: internal compiler error: trying to capture 'f' in instantiation of generic lambda within constraints_satisfied_p

2021-04-09 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4

Bug ID: 4
   Summary: internal compiler error: trying to capture 'f' in
instantiation of generic lambda within
constraints_satisfied_p
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

In godbolt gcc 11.0.1 20210408:

int main() {
auto f = [](int) { return true; };
return [&](auto i) requires (f(sizeof(i))) { return 99; }(12);
}

In substitution of 'template main():: [with
auto:1 = int]':
3:62:   required from here
3:35: internal compiler error: trying to capture 'f' in instantiation of
generic lambda
3 | return [&](auto i) requires (f(sizeof(i))) { return 99; }(12);
  | ~~^~~~
0x1d00959 internal_error(char const*, ...)
0x800866 add_capture(tree_node*, tree_node*, tree_node*, bool, bool)
0x800bfa add_default_capture(tree_node*, tree_node*, tree_node*)
0x73fdda constraints_satisfied_p(tree_node*, tree_node*)
0x955913 fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node*
const*, unsigned int, tree_node*, unification_kind_t, int, conversion**, bool,
bool)
0x6e2ace build_op_call(tree_node*, vec**, int)
0x981ab5 finish_call_expr(tree_node*, vec**, bool,
bool, int)
0x8e224d c_parse_file()
0xa612e2 c_common_parse_file()

Without the default-capture the program is rejected with

note: constraints not satisfied
[...]
error: 'f' is not captured

which I think is incorrect since `f` is not odr-used; clang and MSVC accept
either way.

[Bug c++/97402] New: Value of dependent partial-concept-id is not usable in a constant expression

2020-10-13 Thread ed at catmur dot uk via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97402

Bug ID: 97402
   Summary: Value of dependent partial-concept-id is not usable in
a constant expression
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

#include 
template void f(T x) {
std::same_as auto y = x;
}
int main() { f(1); }

In file included from :1:
: In instantiation of 'void f(T) [with T = int]':
:5:17:   required from here
.../gcc-trunk-20201013/include/c++/11.0.0/concepts:57:15:   required for the
satisfaction of '__same_as<_Tp, _Up>' [with _Tp = int; _Up = T]
.../gcc-trunk-20201013/include/c++/11.0.0/concepts:57:32: error: the value of
'std::is_same_v' is not usable in a constant expression
   57 |   concept __same_as = std::is_same_v<_Tp, _Up>;
  |   ~^~~
In file included from .../gcc-trunk-20201013/include/c++/11.0.0/concepts:44,
 from :1:
.../gcc-trunk-20201013/include/c++/11.0.0/type_traits:3220:25: note:
'std::is_same_v' used in its own initializer
 3220 |   inline constexpr bool is_same_v = __is_same(_Tp, _Up);
  | ^
:3:26: error: deduced initializer does not satisfy placeholder
constraints
3 | std::same_as auto y = x;
  |  ^
:3:26: note: constraints not satisfied

https://godbolt.org/z/qGT5xe

Changing std::same_as to std::same_as makes it compile OK.

Feels a little like 96410.

[Bug c++/96675] New: tautological-compare warning emitted for NTTP bitwise comparison

2020-08-18 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96675

Bug ID: 96675
   Summary: tautological-compare warning emitted for NTTP bitwise
comparison
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

template
constexpr bool f(char d) {
return 'a' <= c && c <= 'z' ? (d | 0x20) == c :
'A' <= c && c <= 'Z' ? (d & ~0x20) == c :
d == c;
}
static_assert(f<'p'>('P'));

In instantiation of 'constexpr bool f(char) [with char c = 'p']':
:7:21:   required from here
:4:44: warning: bitwise comparison always evaluates to false
[-Wtautological-compare]
4 | 'A' <= c && c <= 'Z' ? (d & ~0x20) == c :
  |^~~~

Per godbolt, this happened somewhere between 10.1.0 and 10.2.0.

Motivation is
https://github.com/capnproto/capnproto/commit/c38629e5a4b8ce9561b81cb23ea5fc39cbd93eb7

[Bug c++/95349] Using std::launder(p) produces unexpected behavior where (p) produces expected behavior

2020-05-29 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95349

--- Comment #12 from Ed Catmur  ---
(In reply to Richard Biener from comment #11)
> Note that for C++ types you can apply memcpy to the placement new is not
> needed since object re-use terminates lifetime of the previous object and
> starts lifetime of a new one.

Under P0593R6 it has the effect of implicitly creating objects on demand.
Effectively it is supposed to "curse" the double and "bless" the subsequent
uint64_t. Invoking P0593 may be jumping the gun since it's still in LWG, but
Richard (Smith) wants it retroactively applied to C++20 IS as a DR, and that
could still happen.

> Note that while your example performs memcpy dances you are probably
> after a solution that elides all generated code?

Sure, I assume that memcpy of anything smaller than a page will be elided :)

> Note that I do not belive making your examples work as you intend is
> possible in an actual implementation without sacrifying all
> type-based alias analysis.

Ouch. You might be asked to if and when P0593 goes in (again, assuming I've
understood it correctly). Would it be appropriate to find out what Ville
thinks?

[Bug c++/95349] Using std::launder(p) produces unexpected behavior where (p) produces expected behavior

2020-05-29 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95349

--- Comment #9 from Ed Catmur  ---
(In reply to Jonathan Wakely from comment #4)
> I don't know the answer, and I don't know why it's useful to try this anyway.

If I'm reading P0593 correctly (I may not be), this would be a valid
implementation of start_lifetime_as:

template
inline T* start_lifetime_as(void* p) {
std::byte storage[sizeof(T)];
std::memcpy(storage, p, sizeof(T));
auto q = new (p) std::byte[sizeof(T)];
std::memcpy(q, storage, sizeof(T));
auto t = reinterpret_cast(q);
return std::launder(t);
}

But this has the same issue: https://godbolt.org/z/YYtciP

[Bug c++/95344] New: Wparentheses (assignment used as truth value) on parenthesized ternary conditional E2

2020-05-26 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95344

Bug ID: 95344
   Summary: Wparentheses (assignment used as truth value) on
parenthesized ternary conditional E2
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

void f(int i) {
bool b = false;
if (i == 99 ? (b = true) : false)
;
}

warning: suggest parentheses around assignment used as truth value
[-Wparentheses]
3 | if (i == 99 ? (b = true) : false)
  |  ~~~^~~

Per Godbolt, issue exists from 9.1 through current trunk (11.0).

[Bug c++/82099] internal compiler error: in type_throw_all_p, at cp/except.c:1186 when using a function pointer for templated predicate

2020-04-02 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82099

Ed Catmur  changed:

   What|Removed |Added

 CC||ed at catmur dot uk

--- Comment #6 from Ed Catmur  ---
Workaround: force computation of noexcept of predicate before it is required:

noexcept(+baz);

or simply

baz;

[Bug c++/36566] Cannot bind packed field

2020-03-03 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

--- Comment #11 from Ed Catmur  ---
(In reply to rene.rahn from comment #10)
> I know this is quite old now. But can someone explain me why using `#pragma
> pack(push, 1)` does work then? 

`#pragma pack` has sharper edges. It will let you take unaligned
pointers/references, but they will break on architectures that enforce
alignment or under ubsan, and the compiler won't try to save you. This is for
compatibility with other (older) compilers that behave similarly.

nb.

Since 4.7 `short& pit(oj.s);` gives error: cannot bind packed field
'oj.Squeeze::s' to 'short int&' (comment #1).

Since 9.1 `short* ppit();` and `VerticallyChallenged();` give
warning: taking address of packed member of 'Squeeze' may result in an
unaligned pointer value [-Waddress-of-packed-member] (comment #3).

And the typedef `using un_short = short __attribute__((aligned(1)));` (comment
#6) gives a way to form references and pointers to these fields and pass them
around. (Note that you have to cast the field access at point of use.)

So I think this can be RESOLVED FIXED version 9.1.

[Bug c++/92015] New: internal compiler error: in cxx_eval_array_reference, at cp/constexpr.c:2568

2019-10-07 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92015

Bug ID: 92015
   Summary: internal compiler error: in cxx_eval_array_reference,
at cp/constexpr.c:2568
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ed at catmur dot uk
  Target Milestone: ---

when indexing a char array initialized from a string literal in constexpr
context:

struct S1 { char c[6] {'h', 'e', 'l', 'l', 'o', 0}; };
struct S2 { char c[6] = "hello"; };
static_assert(S1{}.c[0] == 'h');// OK
static_assert(S2{}.c[0] == 'h');// ICE

Expected: both static_asserts pass.

According to Godbolt, this ICE was introduced between 8.3 and 9.1, and is still
present in 10.0.

[Bug c++/80667] [c++1z] ice segfault on partial specialization with non-type template parameter

2019-06-19 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80667

--- Comment #3 from Ed Catmur  ---
Agreed, gcc is OK since 7.2, selecting the latter partial specialization (as
with -std=c++14). OK to mark as fixed.

[Bug c++/80871] Template partial ordering considered non-ambiguous with deduced and non-deduced parameter packs

2019-02-18 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80871

Ed Catmur  changed:

   What|Removed |Added

 CC||ed at catmur dot uk

--- Comment #2 from Ed Catmur  ---
See also #80438

[Bug c++/80871] Template partial ordering considered non-ambiguous with deduced and non-deduced parameter packs

2019-02-18 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80871

--- Comment #3 from Ed Catmur  ---
Sorry. See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80438

[Bug c++/80438] Variadic template class argument deduction failure from variadic constructor deduction guide

2019-02-18 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80438

Ed Catmur  changed:

   What|Removed |Added

 CC||ed at catmur dot uk

--- Comment #2 from Ed Catmur  ---
Workaround: add an N=1+ deduction guide:

// existing
template 
foo(Us...) -> foo;
// additional, for g++
template 
foo(U, Us...) -> foo;

[Bug c++/66476] Erroneous initializer_list lifetime extension from temporary initializer_list

2018-05-24 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66476

Ed Catmur  changed:

   What|Removed |Added

 Status|REOPENED|RESOLVED
 Resolution|--- |INVALID

--- Comment #3 from Ed Catmur  ---
Ah wait, guaranteed copy elision since C++17 should fix this, right? So g++ is
actually correct now, even if it was wrong before.

[Bug c++/66476] Erroneous initializer_list lifetime extension from temporary initializer_list

2018-05-24 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66476

Ed Catmur  changed:

   What|Removed |Added

 Status|RESOLVED|REOPENED
 Resolution|INVALID |---

--- Comment #2 from Ed Catmur  ---
Yes... but the initializer_list that the array backs is itself temporary; it
has lifetime only for the duration of the call to the copy constructor. 

From https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48562#c6 :

> I think that a warning against "({...})" would be useful too
>// fine
>initializer_list a{1, 2, 3};
>// this is bad
>initializer_list b({1, 2, 3});
> Second one is bad because it will destroy the array after initializing 'b', 
> and won't lengthen the lifetime (because it will use the copy/move
> constructor).

[Bug c/66425] (void) cast doesn't suppress __attribute__((warn_unused_result))

2018-05-16 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425

Ed Catmur  changed:

   What|Removed |Added

 CC||ed at catmur dot uk

--- Comment #34 from Ed Catmur  ---
Note that a logical negation prior to cast to void is sufficient to suppress
the warning:

  int void_cast_should_not_warn() {
 (void) !foo();
 // ^-- here
 return 0;
  }