[Bug c++/108238] returns_nonnull attribute with auto return type fails to compile

2023-01-19 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108238

--- Comment #2 from Barnabás Pőcze  ---
Here is a change that I believe might address this. It seems to work but I have
never done anything in gcc, so probably has shortcomings.

The error points to the return expression, like this:

  asd2.cpp: In function ‘auto f2()’:
  asd2.cpp:9:20: error: ‘returns_nonnull’ attribute on a function not returning
a pointer
  9 | auto f2() { return 42; }
|^~

---

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 4667f6de311..50f5ad6b8f1 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -5761,8 +5761,9 @@ static tree
 handle_returns_nonnull_attribute (tree *node, tree name, tree, int,
  bool *no_add_attrs)
 {
+  auto type_code = TREE_CODE (TREE_TYPE (*node));
   // Even without a prototype we still have a return type we can check.
-  if (TREE_CODE (TREE_TYPE (*node)) != POINTER_TYPE)
+  if (type_code != POINTER_TYPE && type_code != TEMPLATE_TYPE_PARM)
 {
   error ("%qE attribute on a function not returning a pointer", name);
   *no_add_attrs = true;
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 1656d02d6d1..b3ae608b350 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12305,6 +12305,10 @@ apply_deduced_return_type (tree fco, tree return_type)
   if (return_type == error_mark_node)
 return;

+  tree returns_nonnull = lookup_attribute("returns_nonnull", TYPE_ATTRIBUTES
(TREE_TYPE (fco)));
+  if (returns_nonnull && TREE_CODE (return_type) != POINTER_TYPE)
+error ("% attribute on a function not returning a
pointer");
+
   if (DECL_CONV_FN_P (fco))
 DECL_NAME (fco) = make_conv_op_name (return_type);

[Bug c++/107532] [13 Regression] -Werror=dangling-reference false positives in libcamera-0.0.1

2023-02-01 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107532

Barnabás Pőcze  changed:

   What|Removed |Added

 CC||pobrn at protonmail dot com

--- Comment #8 from Barnabás Pőcze  ---
Here is another very simple example that only uses STL types:
https://gcc.godbolt.org/z/43cKxdqr3

  void f(const std::vector& v)
  {
  const int& r = std::span(v)[0];
  }

[Bug tree-optimization/108802] New: missed inlining of call via pointer to member function

2023-02-15 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108802

Bug ID: 108802
   Summary: missed inlining of call via pointer to member function
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
  Target Milestone: ---

See https://gcc.godbolt.org/z/j833EGfGY

struct A {
int f(int x) { return 2 * x; }
};

int f1() {
A a;
return [&](auto&& f) { return (a.*f)(42); } (&A::f);
}

clang optimizes `f1()` to `return 84`, but gcc does not do so. This seems to
have been changed somewhere between gcc 9 and 10 because 9.5 does the inlining
but 10.1 does not do it.

[Bug c++/107532] [13 Regression] -Werror=dangling-reference false positives in libcamera-0.0.1

2023-03-10 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107532

--- Comment #17 from Barnabás Pőcze  ---
The simple test case with std::span still triggers the warning:
https://gcc.godbolt.org/z/43cKxdqr3. I feel that without deeper code analysis
such a warning will generate too many false positives and people will simply
turn it off.

[Bug c++/105667] [C++20] lambas in template argument sometimes causes an ICE (seg fault)

2022-09-04 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105667

Barnabás Pőcze  changed:

   What|Removed |Added

 CC||pobrn at protonmail dot com

--- Comment #6 from Barnabás Pőcze  ---
Another snippet that I believe triggers the same issue:

template
struct get { };

template
struct thing {
using T = decltype([](auto) { });

static constexpr auto value = [](auto) {
return get();
}(0);
};

thing<0> X;

---

In this case template_parms_to_args() is called with a nullptr.

template_parms_to_args (parms=0x0) at /usr/src/debug/gcc/gcc/cp/pt.cc:4912

tsubst_template_decl (t=0x77177280, args=, complain=3,
lambda_fntype=0x7717b738) at /usr/src/debug/gcc/gcc/cp/pt.cc:14543

tsubst_lambda_expr (t=, args=0x77171d80, complain=3,
in_decl=0x77173800) at /usr/src/debug/gcc/gcc/cp/pt.cc:19855

tsubst_copy_and_build (t=, args=0x77171d80,
complain=, in_decl=0x77177000, function_p=,
integral_constant_expression_p=false) at /usr/src/debug/gcc/gcc/cp/pt.cc:21446

tsubst (t=0x771760a8, args=0x77171d80, complain=3,
in_decl=0x77177000) at /usr/src/debug/gcc/gcc/cp/pt.cc:16400

tsubst_template_args (t=0x77171a20, args=args@entry=0x77171d80,
complain=complain@entry=3, in_decl=in_decl@entry=0x77177000) at
/usr/src/debug/gcc/gcc/cp/pt.cc:13580

[...]

---

GCC 12.2.0, but GCC trunk on Compiler Explorer also exhibits the same issue (as
do GCC 11.1, 11.2, 11.3, 12.1, and 12.2)

[Bug middle-end/104151] [10/11/12/13 Regression] x86: excessive code generated for 128-bit byteswap

2022-09-06 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104151

Barnabás Pőcze  changed:

   What|Removed |Added

 CC||pobrn at protonmail dot com

--- Comment #15 from Barnabás Pőcze  ---
Sorry, I haven't found a better issue. But I think the example below exhibits
the same or a very similar issue.

I would expect the following code

void f(unsigned char *p, std::uint32_t x, std::uint32_t y)
{
p[0] = x >> 24;
p[1] = x >> 16;
p[2] = x >>  8;
p[3] = x >>  0;

p[4] = y >> 24;
p[5] = y >> 16;
p[6] = y >>  8;
p[7] = y >>  0;
}

to be compiled to something along the lines of

f(unsigned char*, unsigned int, unsigned int):
bswap   esi
bswap   edx
mov DWORD PTR [rdi], esi
mov DWORD PTR [rdi+4], edx
ret

however, I get scores of bitwise operations instead if `-fno-tree-vectorize` is
not specified.

https://gcc.godbolt.org/z/z51K6qorv

[Bug sanitizer/95137] Sanitizers seem to be missing support for coroutines

2022-01-30 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95137

Barnabás Pőcze  changed:

   What|Removed |Added

 CC||pobrn at protonmail dot com

--- Comment #46 from Barnabás Pőcze  ---
(In reply to stream009 from comment #42)
> I got strange compile error when I use coroutine with UBSAN.
> 
> The weird thing is error is reported in compile time not runtime.
> The code compile fine without UBSAN.
> [...]
> === begin compile error ===
> : In function 'void _Z5errori.actor(error(int)::_Z5errori.frame*)':
> :21:9: warning: '' may be used uninitialized
> [-Wmaybe-uninitialized]
>21 | co_return;
>   | ^
> :21:9: note: '' was declared here
>21 | co_return;
>   | ^
> === end compile error ===

I am not familiar with the internals of gcc at all, but it appears that this is
due to incorrect code generation. When ubsan is not used, the generated gimple
looks like this:

if (_13 == 0) goto ; else goto ;
:
_14 = &frame_ptr->__p;
result::promise_type::return_void (_14);
goto final.suspend;
:
_15 = &frame_ptr->__p;
result::promise_type::return_void (_15);

when ubsan is used, however:

if (_8 == 0) goto ; else goto ;
:
D.9938 = &frame_ptr->__p;
.UBSAN_NULL (D.9938, 4B, 0);
result::promise_type::return_void (D.9938);
goto final.suspend;
:
.UBSAN_NULL (D.9938, 4B, 0);
result::promise_type::return_void (D.9938);

`D.9938` is not initialized, and I guess hence the warning.

---

I have noticed that this does not happen on
f6f2d6cfec1c2fe9570b98211be58329d8d7749b, so out of curiosity I tried to bisect
gcc:

> git bisect start
> # new: [f6f2d6cfec1c2fe9570b98211be58329d8d7749b] Daily bump.
> git bisect new f6f2d6cfec1c2fe9570b98211be58329d8d7749b
> # old: [7ca388565af176bd4efd4f8db1e5e9e11e98ef45] Update ChangeLog and 
> version files for release
> git bisect old 7ca388565af176bd4efd4f8db1e5e9e11e98ef45
> # old: [250f234988b6231669a720c52101d3686d645072] testsuite: Fix up 
> gcc.target/s390/zero-scratch-regs-1.c
> git bisect old 250f234988b6231669a720c52101d3686d645072
> # old: [79513dc0b2d980bfd1b109d0d502de487c02b894] compiler: don't pad 
> zero-sized trailing field in results struct
> git bisect old 79513dc0b2d980bfd1b109d0d502de487c02b894
> # new: [1b62cddcf091fb8cadf575246a7d3ff778650a6b] Fix ipa-modref pure/const 
> discovery
> git bisect new 1b62cddcf091fb8cadf575246a7d3ff778650a6b
> # new: [247bac507e63b32d4dc23ef1c55f300aafea24c6] libstdc++: Simplify 
> std::basic_regex::assign
> git bisect new 247bac507e63b32d4dc23ef1c55f300aafea24c6
> # new: [d5f8abe1d3f718a75cbff0a453c1d961be5939b7] Use on-demand ranges in 
> ssa_name_has_boolean_range before querying nonzero bits.
> git bisect new d5f8abe1d3f718a75cbff0a453c1d961be5939b7
> # new: [7d79c3ebc3f3f6f8aecf83726c97474ae5cfe957] Don't record string 
> concatenation data for 'RESERVED_LOCATION_P'
> git bisect new 7d79c3ebc3f3f6f8aecf83726c97474ae5cfe957
> # new: [8137be3958be4e5421c283cce3e5b50dbb80b84e] mips: Fix macro typo
> git bisect new 8137be3958be4e5421c283cce3e5b50dbb80b84e
> # old: [caef5203d64e61da506909d58890035af32a6239] Fix internal error on 
> pointer-to-pointer binding in LTO mode
> git bisect old caef5203d64e61da506909d58890035af32a6239
> # new: [cc1e28878a228b6c4a0872e56d97ac88971b7725] libstdc++: Check for TLS 
> support on mingw cross-compilers
> git bisect new cc1e28878a228b6c4a0872e56d97ac88971b7725
> # new: [70ee703c479081ac2ea67eb67041551216e66783] coroutines: Make proxy vars 
> for the function arg copies.
> git bisect new 70ee703c479081ac2ea67eb67041551216e66783
> # old: [bd55fa102715c7442c050b193dadfdb5337e2377] Fix PR ada/101970
> git bisect old bd55fa102715c7442c050b193dadfdb5337e2377
> # old: [f008fd3a480e3718436156697ebe7eeb47841457] c++: Fix 
> __is_*constructible/assignable for templates [PR102305]
> git bisect old f008fd3a480e3718436156697ebe7eeb47841457
> # old: [de07cff96abd43f6f65dcf333958899c2ec42598] c++: empty union member 
> activation during constexpr [PR102163]
> git bisect old de07cff96abd43f6f65dcf333958899c2ec42598
> # skip: [c5a735fa9df7eca4666c8da5e51ed9c5ab7cc81a] coroutines: Expose 
> implementation state to the debugger.
> git bisect skip c5a735fa9df7eca4666c8da5e51ed9c5ab7cc81a
> # only skipped commits left to test
> # possible first new commit: [70ee703c479081ac2ea67eb67041551216e66783] 
> coroutines: Make proxy vars for the function arg copies.
> # possible first new commit: [c5a735fa9df7eca4666c8da5e51ed9c5ab7cc81a] 
> coroutines: Expose implementation state to the debugger.

Unfortunately, when I got to c5a735fa9df7eca4666c8da5e51ed9c5ab7cc81a, it did
not build; I am not sure where I had gone wrong:

> g++ -std=c+

[Bug c++/108238] New: returns_nonnull attribute with auto return type fails to compile

2022-12-27 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108238

Bug ID: 108238
   Summary: returns_nonnull attribute with auto return type fails
to compile
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
  Target Milestone: ---

See the following example code (https://gcc.godbolt.org/z/76vPhPe6z):

[[gnu::returns_nonnull]]
auto f() {
return new int(42);
}

It produces the following error:

:2:8: error: 'returns_nonnull' attribute on a function not
returning a pointer
2 | auto f() {
  |^

I think this should compile.

[Bug c++/113835] New: compiling std::vector with const size in C++20 is slow

2024-02-08 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113835

Bug ID: 113835
   Summary: compiling std::vector with const size in C++20 is slow
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
  Target Milestone: ---

Consider the following code:

#include 
const std::size_t N = 1'000'000;
std::vector x(N);
int main() {}

Then:

$ hyperfine 'g++ -std=c++20 -O2 x.cpp' 'g++ -std=c++17 -O2 x.cpp'
Benchmark 1: g++ -std=c++20 -O2 x.cpp
  Time (mean ± σ):  4.945 s ±  0.116 s[User: 4.676 s, System: 0.229
s]
  Range (min … max):4.770 s …  5.178 s10 runs

Benchmark 2: g++ -std=c++17 -O2 x.cpp
  Time (mean ± σ): 491.3 ms ±  24.0 ms[User: 440.9 ms, System: 46.3
ms]
  Range (min … max):   465.6 ms … 538.0 ms10 runs

Summary
  g++ -std=c++17 -O2 x.cpp ran
   10.07 ± 0.55 times faster than g++ -std=c++20 -O2 x.cpp

If you remove the `const` from `N`, the runtime will be closer to C++17 levels.

`-ftime-report` suggests that "constant expression evaluation" is the reason. I
imagine this is related to C++20 making std::vector constexpr.

[Bug c++/115219] New: ICE on conditionally noexcept class operator delete

2024-05-24 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115219

Bug ID: 115219
   Summary: ICE on conditionally noexcept class operator delete
   Product: gcc
   Version: 14.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
  Target Milestone: ---

Consider the following piece of C++ code:

```
#include 
#include 

template
struct B {
static void *
operator new(std::size_t s, std::size_t)
{ return ::operator new(s); }

static void
operator delete(void *)
noexcept(std::is_nothrow_destructible_v)
{ }
};

struct A : B { };

void test() {
new (42) A();
}
```

gcc 14.1.1 and trunk (on CE) trigger the following ICE (
https://gcc.godbolt.org/z/z7av1Mf3Y ):

```
: In function 'void test()':
:19:16: internal compiler error: in type_throw_all_p, at
cp/except.cc:1234
   19 | new (42) A();
  |^
0x268e9ac internal_error(char const*, ...)
???:0
0xa5b247 fancy_abort(char const*, int, char const*)
???:0
0xb08bb3 fnptr_conv_p(tree_node*, tree_node*)
???:0
0xaa0ae6 instantiate_type(tree_node*, tree_node*, int)
???:0
0xa75b7e build_op_delete_call(tree_code, tree_node*, tree_node*, bool,
tree_node*, tree_node*, int)
???:0
0xb82ab0 build_new(unsigned int, vec**,
tree_node*, tree_node*, vec**, int, int)
???:0
0xc63d8a c_parse_file()
???:0
0xdb95b9 c_common_parse_file()
???:0
```

Removing the conditional noexcept specification makes the ICE go away.

Here is a more detailed stack trace from the arch linux build of gcc (about
14.1.1):

```
Breakpoint 1, internal_error (gmsgid=gmsgid@entry=0x2b4b860 "in %s, at %s:%d")
at /usr/src/debug/gcc/gcc/gcc/diagnostic.cc:2227
2227{
(gdb) bt
#0  internal_error (gmsgid=gmsgid@entry=0x2b4b860 "in %s, at %s:%d") at
/usr/src/debug/gcc/gcc/gcc/diagnostic.cc:2227
#1  0x00703e88 in fancy_abort (file=0x2b5c798
"/usr/src/debug/gcc/gcc/gcc/cp/except.cc", line=1234, function=0x2aa87dc
"type_throw_all_p") at /usr/src/debug/gcc/gcc/gcc/diagnostic.cc:2353
#2  0x006b97f2 in type_throw_all_p (type=) at
/usr/src/debug/gcc/gcc/gcc/cp/except.cc:1231
#3  type_throw_all_p (type=) at
/usr/src/debug/gcc/gcc/gcc/cp/except.cc:1231
#4  noexcept_conv_p (to=0x76c24498, from=0x76a15930) at
/usr/src/debug/gcc/gcc/gcc/cp/cvt.cc:2130
#5  fnptr_conv_p (to=, from=) at
/usr/src/debug/gcc/gcc/gcc/cp/cvt.cc:2157
#6  0x0072a772 in instantiate_type (lhstype=0x76c24498,
rhs=0x76a10690, complain=0) at /usr/src/debug/gcc/gcc/gcc/cp/class.cc:9085
#7  0x0072cede in build_op_delete_call (code=DELETE_EXPR,
addr=0x76a1e1e0, size=0x76e212d0, global_p=,
placement=0x76a1b340, alloc_fn=0x76de9700, complain=3)
at /usr/src/debug/gcc/gcc/gcc/cp/call.cc:7893
#8  0x00804299 in build_new_1
(placement=placement@entry=0x7fffcd78, type=,
nelts=, nelts@entry=0x0, init=init@entry=0x7fffcd70, 
globally_qualified_p=globally_qualified_p@entry=false,
complain=complain@entry=3) at /usr/src/debug/gcc/gcc/gcc/cp/init.cc:3784
#9  0x008055ca in build_new (loc=64384747, placement=0x7fffcd78,
type=, nelts=0x0, init=0x7fffcd70, use_global_new=0,
complain=3) at /usr/src/debug/gcc/gcc/gcc/cp/init.cc:4054
#10 0x00867ab7 in cp_parser_new_expression
(parser=parser@entry=0x76fb4dc8) at
/usr/src/debug/gcc/gcc/gcc/cp/parser.cc:9659
#11 0x0086258b in cp_parser_unary_expression (parser=0x76fb4dc8,
pidk=, address_p=, cast_p=,
decltype_p=)
at /usr/src/debug/gcc/gcc/gcc/cp/parser.cc:9245
#12 0x00864664 in cp_parser_binary_expression
(parser=parser@entry=0x76fb4dc8, cast_p=cast_p@entry=false,
no_toplevel_fold_p=no_toplevel_fold_p@entry=false,
decltype_p=decltype_p@entry=false, 
prec=prec@entry=PREC_NOT_OPERATOR, pidk=pidk@entry=0x0) at
/usr/src/debug/gcc/gcc/gcc/cp/parser.cc:10393
#13 0x008653bd in cp_parser_assignment_expression
(parser=parser@entry=0x76fb4dc8, pidk=pidk@entry=0x0,
cast_p=cast_p@entry=false, decltype_p=decltype_p@entry=false)
at /usr/src/debug/gcc/gcc/gcc/cp/parser.cc:10737
#14 0x00865994 in cp_parser_expression
(parser=parser@entry=0x76fb4dc8, pidk=pidk@entry=0x0,
cast_p=cast_p@entry=false, decltype_p=decltype_p@entry=false,
warn_comma_p=warn_comma_p@entry=false)
at /usr/src/debug/gcc/gcc/gcc/cp/parser.cc:10903
#15 0x0086622e in cp_parser_expression_statement
(parser=0x76fb4dc8, in_statement_expr=0x0) at
/usr/src/debug/gcc/gcc/gcc/cp/parser.cc:13166
#16 0x00876d31 in cp_parser_statement
(parser=parser@entry=0x76fb4dc8,
in_statement_expr=in_statement_expr@entry=0x0,
in_compound=in_compound@entry=true, if_p=if_p@entry=0x0, chain=chain@entry=0x0, 
loc_after_labels=loc_after_labels@entry=0x0) at
/usr/src/debug/gcc/gcc/gcc/cp/parser.cc:12947
#17 0x00

[Bug c++/115219] [11/12/13/14/15 Regression] [c++17+] ICE on depdendent noexcept class operator delete

2024-05-24 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115219

--- Comment #3 from Barnabás Pőcze  ---
That reduced test case compiles fine for me. On CE, too. Am I missing some
compilation flags?

[Bug c++/115222] New: clang does not think libstdc++'s std::optional is nothrow destructible

2024-05-24 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115222

Bug ID: 115222
   Summary: clang does not think libstdc++'s std::optional is
nothrow destructible
   Product: gcc
   Version: 15.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
  Target Milestone: ---

clang and gcc disagree whether libstdc++'s std::optional is nothrow
destructible when T is not. My reading of https://eel.is/c++draft/optional.dtor
suggests that the destructor should be `noexcept(true)` (by omission).

Consider the following piece of C++ code:

```
#include 
#include 

struct A { ~A() noexcept(false); };

static_assert(std::is_nothrow_destructible_v>);
```

the assertion passes on gcc, while it fails on clang:
https://gcc.godbolt.org/z/1ndxK1avM

Now I have tried to reduce the input, and arrived at something like this (
https://gcc.godbolt.org/z/orx5j1Eaf ):

```
template  _Tp declval() noexcept;

template 
inline constexpr bool is_nothrow_destructible_v = noexcept(declval<_Tp>());

template 
struct _Optional_payload_base {
  union _Storage {
_Tp _M_value;
  } _M_payload;
};

template 
struct _Optional_payload : _Optional_payload_base<_Tp> {
~_Optional_payload();
};

struct A {
  ~A() noexcept(false);
};

static_assert(is_nothrow_destructible_v<_Optional_payload>);
```

The assertion passes on gcc, but fails on clang (and edg).

[Bug c++/115229] New: inconsistent `error: possibly dangling reference to a temporary`

2024-05-25 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115229

Bug ID: 115229
   Summary: inconsistent `error: possibly dangling reference to a
temporary`
   Product: gcc
   Version: 15.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
  Target Milestone: ---

Consider the following piece of C++ code:

```
struct A {
int q;
int *p;
};

struct B {
A value_or() {
return A {};
}
};

B f();

void test() {
const auto& x = f().value_or();
}
```

gcc 15, 14 show the following diagnostic:

```
: In function 'void test()':
:15:21: error: possibly dangling reference to a temporary
[-Werror=dangling-reference]
   15 | const auto& x = f().value_or();
  | ^
:15:37: note: the temporary was destroyed at the end of the full
expression 'f().B::value_or()'
   15 | const auto& x = f().value_or();
  | ^~
```

while gcc 13 does not.

Could someone help me understand why this warning is even shown? I would assume
lifetime extension should extend the lifetime of the returned value as needed.

Note that removing `int *p` from `A` makes the warning go away, so I am not
sure if this warning has anything to do with the lifetime of the returned
value, but then I am confused why the error points to `x`.

[Bug c++/115229] inconsistent `error: possibly dangling reference to a temporary`

2024-05-25 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115229

--- Comment #2 from Barnabás Pőcze  ---
So because `A::p` might point into the temporary of type `B` returned by `f()`,
the warning is shown? If so, why don't I get a warning if `x` is not a
reference? The same potential issue is possible in that case, no?

[Bug c++/108238] auto return type and some attributes don't get along

2023-10-20 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108238

--- Comment #5 from Barnabás Pőcze  ---
Based on a suggestion from Jakub Jelínek, I have tried to modify
`is_late_template_attribute()` instead, but it appears that function does not
run in this case.

[Bug c/80454] -Wmissing-braces wrongly warns about universal zero initializer {0}

2023-10-27 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80454

Barnabás Pőcze  changed:

   What|Removed |Added

 CC||pobrn at protonmail dot com

--- Comment #7 from Barnabás Pőcze  ---
Created attachment 56319
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56319&action=edit
proposed patch

I would like to see this fixed, so I have tried something, see the attached
patch. It's a bit of a hack at the moment, and I am not sure it fixes
everything (it improves the status quo in any case), any thoughts?

[Bug libstdc++/112934] New: excessive code for std::map::erase(key)

2023-12-08 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112934

Bug ID: 112934
   Summary: excessive code for std::map::erase(key)
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
  Target Milestone: ---

It is probably expected that calling erase(key) is equivalent to or better than

  auto it = m.find(k);
  if (it != m.end())
m.erase(it);

However, currently that is not the case: https://gcc.godbolt.org/z/f1Mh3bodf

This is because std::map::erase(key) calls erase(key) on the underlying tree,
which then uses equal_range() and tries to delete a range of iterators. This is
unnecessary since a map enforces unique keys.

libc++ has an __erase_unique() method on the underlying tree type to handle
this, which does essentially what - I assume - most people expect erase(key) to
do:
https://github.com/llvm/llvm-project/blob/b88b480640f173582ffbfd2faae690f2bc895d14/libcxx/include/__tree#L2453

I believe the same applies to std::set.

[Bug sanitizer/113053] New: local variable misaligned with AddressSanitizer

2023-12-17 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113053

Bug ID: 113053
   Summary: local variable misaligned with AddressSanitizer
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

Created attachment 56895
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56895&action=edit
source code and tree/rtl dumps

Consider the following code:

#include 
#include 

struct thing {
int x[5] __attribute__((aligned(64)));
};

__attribute__((noinline))
void f(void *x)
{
assert((uintptr_t) x % 64 == 0);
}

int main()
{
struct thing t;
static_assert(_Alignof(t) == 64);
assert((uintptr_t) &t % 64 == 0);

f(&t);
}


When compiled with `gcc -O2 -fsanitize=address`, the following assembly is
generated:


10d0 :
10d0:   55  push   rbp
10d1:   48 89 e5movrbp,rsp
10d4:   41 55   push   r13
10d6:   41 54   push   r12
10d8:   53  push   rbx
10d9:   48 83 e4 c0 andrsp,0xffc0
10dd:   48 81 ec c0 00 00 00subrsp,0xc0
10e4:   8b 05 56 30 00 00   moveax,DWORD PTR [rip+0x3056]  
 # 4140 <__asan_option_detect_stack_use_after_return@@Base>
10ea:   48 8d 5c 24 20  learbx,[rsp+0x20] # ?
10ef:   49 89 ddmovr13,rbx
10f2:   85 c0   test   eax,eax
10f4:   0f 85 95 00 00 00   jne118f 
10fa:   48 8d 05 df 0f 00 00learax,[rip+0xfdf]# 20e0
<__PRETTY_FUNCTION__.0+0x40>
1101:   49 89 dcmovr12,rbx
1104:   48 c7 03 b3 8a b5 41movQWORD PTR [rbx],0x41b58ab3
110b:   48 8d 7b 20 leardi,[rbx+0x20] # ?
...
114d:   e8 ae 01 00 00  call   1300 
...
118f:   bf 80 00 00 00  movedi,0x80
1194:   e8 a7 fe ff ff  call   1040 <__asan_stack_malloc_1@plt>
1199:   48 85 c0test   rax,rax
119c:   48 0f 45 d8 cmovne rbx,rax
11a0:   e9 55 ff ff ff  jmp10fa 


Assume that stack-user-after-return detection is enabled
(`ASAN_OPTIONS=detect_stack_use_after_return=1`). In that case the jump at
0x10f4 will be taken, if __asan_stack_malloc_1 returns a 64 byte aligned
address, then the lea at 0x110b will add 32 to the address, making it not 64
byte aligned anymore.

Now confusingly, the error cannot be reproduced on the Compiler Explorer or in
the GCC docker container because the assembly is different, for example they
call `__asan_stack_malloc_2`, and there is still a +64 to get the address of
the variable, but it is done as a single step, not split up into two parts.

But this code is generated on both current Arch Linux (GCC 13.2.1 20230801),
and Ubuntu 22.04 (GCC 11.4.0-1ubuntu1~22.04). One can easily trigger this error
for example in an Arch container:

$ docker run --rm -it archlinux
# pacman -Syu gcc nano --noconfirm
# nano x.c # etc...
# gcc -O2 -fsanitize=address x.c
# ASAN_OPTIONS=detect_stack_use_after_return=1 ./a.out
a.out: x.c:11: f: Assertion `(uintptr_t) x % 64 == 0' failed.
Aborted (core dumped)


GCC on Arch Linux is configured as follows:
https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/blob/64b6b1ded75259ba7e9311d0e5b1ab44320b92d5/PKGBUILD#L111

[Bug other/115581] New: missed argument forwarding in lambda

2024-06-21 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115581

Bug ID: 115581
   Summary: missed argument forwarding in lambda
   Product: gcc
   Version: 15.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: other
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
  Target Milestone: ---

Consider the following piece of C++ code:
```
struct thing {
int x[64];
};

void g(const thing &);

void f1(thing x)
{
g(x);
}

auto *f2 = +[](thing x) {
g(x);
};

struct f3 {
void operator()(thing);
};
void f3::operator()(thing x) {
g(x);
}
```

Checking the generated code on an x86-64 linux system at -O2, note that `f1()`
and `f3::operator()()` simply "forward" their by-value arguments to `g()`:

```
f1(thing):
sub rsp, 8
lea rdi, [rsp+16]
callg(thing const&)
add rsp, 8
ret
```

Notice that this is not done in the case of `f2`, the generated function from
the lambda makes a copy of `x`:

```
f2::{lambda(thing)#1}::_FUN(thing):
sub rsp, 264
movdqu  xmm0, XMMWORD PTR [rsp+272]
mov rdi, rsp
movaps  XMMWORD PTR [rsp], xmm0
movdqu  xmm0, XMMWORD PTR [rsp+288]
[...]
movdqu  xmm0, XMMWORD PTR [rsp+512]
movaps  XMMWORD PTR [rsp+240], xmm0
callg(thing const&)
add rsp, 264
ret
```

See https://gcc.godbolt.org/z/n43a6MPjY, clang does the same copy, so maybe
there is a rule in C++ that prevents this optimization and that I failed to
consider?

[Bug middle-end/115581] could remove copy of struct if original otherwise not used

2024-06-21 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115581

--- Comment #3 from Barnabás Pőcze  ---
Isn't your testcase a bit different? I guess my question is, why does gcc feel
the need to make a local copy of a by-value argument when calling a function
with a reference to it, but seemingly only in a function generated from a
lambda?

[Bug c++/118632] New: 0 vs nullptr mixup in template

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

Bug ID: 118632
   Summary: 0 vs nullptr mixup in template
   Product: gcc
   Version: 15.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pobrn at protonmail dot com
  Target Milestone: ---

Consider the following piece of code:

#include 

template > * =
nullptr>
class Matrix {};

template  void operator*(Matrix, int rgb) {
Matrix{} * rgb;
}


-- https://gcc.godbolt.org/z/GTqMf69K4

It fails on gcc 15 with the following error:

: In function 'void operator*(Matrix, int)':
:7:17: error: no match for 'operator*' (operand types are
'Matrix' and 'int') [-Wtemplate-body]
7 |   Matrix{} * rgb;
|   ~~^
:7:17: note: there is 1 candidate
:6:28: note: candidate 1: 'template void
operator*(Matrix, int)'
6 | template  void operator*(Matrix, int rgb) {
|^~~~
:6:28: note: template argument deduction/substitution failed:
:7:19: note:   template argument '0' does not match 'nullptr'
7 |   Matrix{} * rgb;
|   ^~~

This does not happen with clang, msvc, or earlier gcc versions.

[Bug libstdc++/112934] excessive code for std::map::erase(key)

2025-04-28 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112934

--- Comment #5 from Barnabás Pőcze  ---
If I'm not mistaken, GCC 15.1 has been released, so I am wondering if the patch
could now be merged?

[Bug libstdc++/112934] excessive code for std::map::erase(key)

2025-04-03 Thread pobrn at protonmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112934

--- Comment #3 from Barnabás Pőcze  ---
Any idea as to when it might get merged?